mycroforge/MycroForge.CLI.Tests/InitCommandTests.cs

223 lines
8.0 KiB
C#

using System.Text;
using System.Text.Json;
using DotNet.Testcontainers.Builders;
using DotNet.Testcontainers.Containers;
using DotNet.Testcontainers.Images;
using MycroForge.CLI.Tests.Extensions;
using MycroForge.Core;
namespace MycroForge.CLI.Tests;
public class InitCommandTests
{
private IFutureDockerImage Image = null!;
private IContainer Container = null!;
private async Task CreateImage()
{
Image = new ImageFromDockerfileBuilder()
.WithDockerfileDirectory(CommonDirectoryPath.GetSolutionDirectory(), string.Empty)
.WithDockerfile("Dockerfile")
.WithCleanUp(true)
.Build();
await Image.CreateAsync();
}
private async Task CreateContainer()
{
Container = new ContainerBuilder()
.WithImage(Image)
.WithCleanUp(true)
.Build();
await Container.StartAsync();
}
[OneTimeSetUp]
public async Task SetupOnce()
{
await CreateImage();
await CreateContainer();
await Container.ExecAsync(["m4g", "init", "todo"]);
}
[Test]
public async Task Creates_m4g_json()
{
var bytes = await Container.ReadFileFromRootAsync("m4g.json");
using var stream = new MemoryStream(bytes);
var config = await JsonSerializer.DeserializeAsync<ProjectConfig>(stream, DefaultJsonSerializerOptions.Default);
Assert.That(config, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(config!.Api, Is.Not.Null);
Assert.That(config.Api.Port, Is.EqualTo(8000));
Assert.That(config.Db, Is.Not.Null);
Assert.That(config.Db.DbhPort, Is.EqualTo(5050));
Assert.That(config.Db.DbuPort, Is.EqualTo(5051));
});
}
[Test]
public async Task Creates_main_py()
{
var bytes = await Container.ReadFileFromRootAsync("main.py");
var text = Encoding.UTF8.GetString(bytes);
var lines = text.Split('\n');
TestContext.WriteLine(text);
Assert.Multiple(() =>
{
Assert.That(text, Is.Not.Empty);
Assert.That(lines, Does.Contain("from fastapi import FastAPI"));
Assert.That(lines, Does.Contain("from api.routers import hello"));
Assert.That(lines, Does.Contain("app = FastAPI()"));
Assert.That(lines, Does.Contain("app.include_router(prefix=\"/hello\", router=hello.router)"));
});
}
[Test]
public async Task Creates_gitignore()
{
var bytes = await Container.ReadFileFromRootAsync(".gitignore");
var text = Encoding.UTF8.GetString(bytes);
var lines = text.Split('\n');
TestContext.WriteLine(text);
Assert.Multiple(() =>
{
Assert.That(text, Is.Not.Empty);
Assert.That(lines, Does.Contain(".venv"));
Assert.That(lines, Does.Contain("__pycache__/"));
});
}
[Test]
public async Task Creates_alembic_ini()
{
var bytes = await Container.ReadFileFromRootAsync("alembic.ini");
var text = Encoding.UTF8.GetString(bytes);
var lines = text.Split('\n');
TestContext.WriteLine(text);
Assert.Multiple(() =>
{
Assert.That(text, Is.Not.Empty);
Assert.That(lines, Does.Contain("[alembic]"));
Assert.That(lines, Does.Contain("sqlalchemy.url = driver://user:pass@localhost/dbname"));
});
}
[Test]
public async Task Creates_db_docker_compose_yml()
{
var bytes = await Container.ReadFileFromRootAsync("db.docker-compose.yml");
var text = Encoding.UTF8.GetString(bytes);
var lines = text.Split('\n');
TestContext.WriteLine(text);
Assert.Multiple(() =>
{
Assert.That(text, Is.Not.Empty);
Assert.That(lines, Does.Contain(" todo_mariadb:"));
Assert.That(lines, Does.Contain(" container_name: 'todo_mariadb'"));
Assert.That(lines, Does.Contain(" - '${DBH_PORT}:3306'"));
Assert.That(lines, Does.Contain(" MYSQL_DATABASE: 'todo'"));
Assert.That(lines, Does.Contain(" - 'todo_mariadb:/var/lib/mysql'"));
Assert.That(lines, Does.Contain(" todo_phpmyadmin:"));
Assert.That(lines, Does.Contain(" container_name: todo_phpmyadmin"));
Assert.That(lines, Does.Contain(" PMA_HOST: todo_mariadb"));
Assert.That(lines, Does.Contain(" - todo_mariadb"));
Assert.That(lines, Does.Contain(" todo_mariadb:"));
});
}
[Test]
public async Task Creates_api__router_hello_py()
{
var bytes = await Container.ReadFileFromRootAsync("api/routers/hello.py");
var text = Encoding.UTF8.GetString(bytes);
var lines = text.Split('\n');
TestContext.WriteLine(text);
Assert.Multiple(() =>
{
Assert.That(text, Is.Not.Empty);
Assert.That(lines, Does.Contain("from fastapi import APIRouter"));
Assert.That(lines, Does.Contain("from fastapi.responses import JSONResponse"));
Assert.That(lines, Does.Contain("from fastapi.encoders import jsonable_encoder"));
Assert.That(lines, Does.Contain("router = APIRouter()"));
Assert.That(lines, Does.Contain("@router.get(\"/{name}\")"));
Assert.That(lines, Does.Contain("async def hello(name: str):"));
Assert.That(lines, Does.Contain("\treturn JSONResponse(status_code=200, content=jsonable_encoder({'greeting': f\"Hello, {name}!\"}))"));
});
}
[Test]
public async Task Creates_db__engine__async_session_py()
{
var bytes = await Container.ReadFileFromRootAsync("db/engine/async_session.py");
var text = Encoding.UTF8.GetString(bytes);
var lines = text.Split('\n');
TestContext.WriteLine(text);
Assert.Multiple(() =>
{
Assert.That(text, Is.Not.Empty);
Assert.That(lines, Does.Contain("from sqlalchemy.ext.asyncio import create_async_engine, AsyncEngine, AsyncSession"));
Assert.That(lines, Does.Contain("from db.settings import DbSettings"));
Assert.That(lines, Does.Contain("async_engine: AsyncEngine = create_async_engine(DbSettings.get_connectionstring())"));
Assert.That(lines, Does.Contain("def async_session() -> AsyncSession:"));
Assert.That(lines, Does.Contain("\treturn AsyncSession(async_engine, expire_on_commit=False)"));
});
}
[Test]
public async Task Creates_db__entities__entity_base_py()
{
var bytes = await Container.ReadFileFromRootAsync("db/entities/entity_base.py");
var text = Encoding.UTF8.GetString(bytes);
var lines = text.Split('\n');
TestContext.WriteLine(text);
Assert.Multiple(() =>
{
Assert.That(text, Is.Not.Empty);
Assert.That(lines, Does.Contain("from sqlalchemy.orm import DeclarativeBase"));
Assert.That(lines, Does.Contain("class EntityBase(DeclarativeBase):"));
Assert.That(lines, Does.Contain("\tpass"));
});
}
[Test]
public async Task Creates_db__settings_py()
{
var bytes = await Container.ReadFileFromRootAsync("db/settings.py");
var text = Encoding.UTF8.GetString(bytes);
var lines = text.Split('\n');
TestContext.WriteLine(text);
Assert.Multiple(() =>
{
Assert.That(text, Is.Not.Empty);
Assert.That(lines, Does.Contain("class DbSettings:"));
Assert.That(lines, Does.Contain("\tdef get_connectionstring() -> str:"));
Assert.That(lines, Does.Contain("\t\tconnectionstring = \"mysql+asyncmy://root:password@localhost:5050/todo\""));
Assert.That(lines, Does.Contain("\t\treturn connectionstring"));
});
}
}