aboutsummaryrefslogtreecommitdiff
path: root/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests
diff options
context:
space:
mode:
Diffstat (limited to 'dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests')
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/ColumnTypeInfoTest.cs39
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudIntegratedTest.cs200
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudServiceTest.cs77
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/SqlCompareHelper.cs85
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs35
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TestEntity.cs23
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/CrupestApi.Commons.Tests.csproj29
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Usings.cs1
8 files changed, 489 insertions, 0 deletions
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/ColumnTypeInfoTest.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/ColumnTypeInfoTest.cs
new file mode 100644
index 0000000..b9ec03e
--- /dev/null
+++ b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/ColumnTypeInfoTest.cs
@@ -0,0 +1,39 @@
+using System.Data;
+
+namespace CrupestApi.Commons.Crud.Tests;
+
+public class ColumnTypeInfoTest
+{
+ private ColumnTypeProvider _provider = new ColumnTypeProvider();
+
+ [Theory]
+ [InlineData(typeof(int), DbType.Int32, 123)]
+ [InlineData(typeof(long), DbType.Int64, 456)]
+ [InlineData(typeof(sbyte), DbType.SByte, 789)]
+ [InlineData(typeof(short), DbType.Int16, 101)]
+ [InlineData(typeof(float), DbType.Single, 1.0f)]
+ [InlineData(typeof(double), DbType.Double, 1.0)]
+ [InlineData(typeof(string), DbType.String, "Hello world!")]
+ [InlineData(typeof(byte[]), DbType.Binary, new byte[] { 1, 2, 3 })]
+ public void BasicColumnTypeTest(Type type, DbType dbType, object? value)
+ {
+ var typeInfo = _provider.Get(type);
+ Assert.True(typeInfo.IsSimple);
+ Assert.Equal(dbType, typeInfo.DbType);
+ Assert.Equal(value, typeInfo.ConvertFromDatabase(value));
+ Assert.Equal(value, typeInfo.ConvertToDatabase(value));
+ }
+
+ [Fact]
+ public void DateTimeColumnTypeTest()
+ {
+ var dateTimeColumnTypeInfo = _provider.Get(typeof(DateTime));
+ Assert.Equal(typeof(DateTime), dateTimeColumnTypeInfo.ClrType);
+ Assert.Equal(typeof(string), dateTimeColumnTypeInfo.DatabaseClrType);
+
+ var dateTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ var dateTimeString = "2000-01-01T00:00:00Z";
+ Assert.Equal(dateTimeString, dateTimeColumnTypeInfo.ConvertToDatabase(dateTime));
+ Assert.Equal(dateTime, dateTimeColumnTypeInfo.ConvertFromDatabase(dateTimeString));
+ }
+}
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudIntegratedTest.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudIntegratedTest.cs
new file mode 100644
index 0000000..bd07c70
--- /dev/null
+++ b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudIntegratedTest.cs
@@ -0,0 +1,200 @@
+using System.Net;
+using System.Net.Http.Headers;
+using CrupestApi.Commons.Secrets;
+using Microsoft.AspNetCore.TestHost;
+
+namespace CrupestApi.Commons.Crud.Tests;
+
+public class CrudIntegratedTest : IAsyncLifetime
+{
+ private readonly WebApplication _app;
+ private HttpClient _httpClient = default!;
+ private HttpClient _authorizedHttpClient = default!;
+ private string _token = default!;
+
+ public CrudIntegratedTest()
+ {
+ var builder = WebApplication.CreateBuilder();
+ builder.Logging.ClearProviders();
+ builder.Services.AddSingleton<IDbConnectionFactory, SqliteMemoryConnectionFactory>();
+ builder.Services.AddCrud<TestEntity>();
+ builder.WebHost.UseTestServer();
+ _app = builder.Build();
+ _app.UseCrudCore();
+ _app.MapCrud<TestEntity>("/test", "test-perm");
+ }
+
+ public async Task InitializeAsync()
+ {
+ await _app.StartAsync();
+ _httpClient = _app.GetTestClient();
+
+ using (var scope = _app.Services.CreateScope())
+ {
+ var secretService = (SecretService)scope.ServiceProvider.GetRequiredService<ISecretService>();
+ var key = secretService.Create(new SecretInfo
+ {
+ Key = "test-perm"
+ });
+ _token = secretService.GetByKey(key).Secret;
+ }
+
+ _authorizedHttpClient = _app.GetTestClient();
+ _authorizedHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token);
+ }
+
+ public async Task DisposeAsync()
+ {
+ await _app.StopAsync();
+ }
+
+
+ [Fact]
+ public async Task EmptyTest()
+ {
+ using var response = await _authorizedHttpClient.GetAsync("/test");
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ var body = await response.Content.ReadFromJsonAsync<List<TestEntity>>();
+ Assert.NotNull(body);
+ Assert.Empty(body);
+ }
+
+ [Fact]
+ public async Task CrudTest()
+ {
+ {
+ using var response = await _authorizedHttpClient.PostAsJsonAsync("/test", new TestEntity
+ {
+ Name = "test",
+ Age = 22
+ });
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ var body = await response.Content.ReadFromJsonAsync<TestEntity>();
+ Assert.NotNull(body);
+ Assert.Equal("test", body.Name);
+ Assert.Equal(22, body.Age);
+ Assert.Null(body.Height);
+ Assert.NotEmpty(body.Secret);
+ }
+
+ {
+ using var response = await _authorizedHttpClient.GetAsync("/test");
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ var body = await response.Content.ReadFromJsonAsync<List<TestEntity>>();
+ Assert.NotNull(body);
+ var entity = Assert.Single(body);
+ Assert.Equal("test", entity.Name);
+ Assert.Equal(22, entity.Age);
+ Assert.Null(entity.Height);
+ Assert.NotEmpty(entity.Secret);
+ }
+
+ {
+ using var response = await _authorizedHttpClient.GetAsync("/test/test");
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ var body = await response.Content.ReadFromJsonAsync<TestEntity>();
+ Assert.NotNull(body);
+ Assert.Equal("test", body.Name);
+ Assert.Equal(22, body.Age);
+ Assert.Null(body.Height);
+ Assert.NotEmpty(body.Secret);
+ }
+
+ {
+ using var response = await _authorizedHttpClient.PatchAsJsonAsync("/test/test", new TestEntity
+ {
+ Name = "test-2",
+ Age = 23,
+ Height = 188.0f
+ });
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ var body = await response.Content.ReadFromJsonAsync<TestEntity>();
+ Assert.NotNull(body);
+ Assert.Equal("test-2", body.Name);
+ Assert.Equal(23, body.Age);
+ Assert.Equal(188.0f, body.Height);
+ Assert.NotEmpty(body.Secret);
+ }
+
+ {
+ using var response = await _authorizedHttpClient.GetAsync("/test/test-2");
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ var body = await response.Content.ReadFromJsonAsync<TestEntity>();
+ Assert.NotNull(body);
+ Assert.Equal("test-2", body.Name);
+ Assert.Equal(23, body.Age);
+ Assert.Equal(188.0f, body.Height);
+ Assert.NotEmpty(body.Secret);
+ }
+
+ {
+ using var response = await _authorizedHttpClient.DeleteAsync("/test/test-2");
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ }
+
+ {
+ using var response = await _authorizedHttpClient.GetAsync("/test");
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ var body = await response.Content.ReadFromJsonAsync<List<TestEntity>>();
+ Assert.NotNull(body);
+ Assert.Empty(body);
+ }
+ }
+
+ [Fact]
+ public async Task UnauthorizedTest()
+ {
+ {
+ using var response = await _httpClient.GetAsync("/test");
+ Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
+ }
+
+ {
+ using var response = await _httpClient.GetAsync("/test/test");
+ Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
+ }
+
+ {
+ using var response = await _httpClient.PostAsJsonAsync("/test", new TestEntity
+ {
+ Name = "test",
+ Age = 22
+ });
+ Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
+ }
+
+ {
+ using var response = await _httpClient.PatchAsJsonAsync("/test/test", new TestEntity
+ {
+ Name = "test-2",
+ Age = 23,
+ Height = 188.0f
+ });
+ Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
+ }
+
+ {
+ using var response = await _httpClient.DeleteAsync("/test/test");
+ Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
+ }
+ }
+
+ [Fact]
+ public async Task NotFoundTest()
+ {
+ {
+ using var response = await _authorizedHttpClient.GetAsync("/test/test");
+ Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
+ }
+
+ {
+ using var response = await _authorizedHttpClient.PatchAsJsonAsync("/test/test", new TestEntity
+ {
+ Name = "test-2",
+ Age = 23,
+ Height = 188.0f
+ });
+ Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
+ }
+ }
+}
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudServiceTest.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudServiceTest.cs
new file mode 100644
index 0000000..ad0d34c
--- /dev/null
+++ b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/CrudServiceTest.cs
@@ -0,0 +1,77 @@
+using CrupestApi.Commons.Crud.Migrations;
+using Microsoft.Extensions.Logging.Abstractions;
+
+namespace CrupestApi.Commons.Crud.Tests;
+
+public class CrudServiceTest
+{
+ private readonly SqliteMemoryConnectionFactory _memoryConnectionFactory = new SqliteMemoryConnectionFactory();
+
+ private readonly CrudService<TestEntity> _crudService;
+
+ public CrudServiceTest()
+ {
+ var columnTypeProvider = new ColumnTypeProvider();
+ var tableInfoFactory = new TableInfoFactory(columnTypeProvider, NullLoggerFactory.Instance);
+ var dbConnectionFactory = new SqliteMemoryConnectionFactory();
+
+ _crudService = new CrudService<TestEntity>(
+ tableInfoFactory, dbConnectionFactory, new SqliteDatabaseMigrator(), NullLoggerFactory.Instance);
+ }
+
+ [Fact]
+ public void CrudTest()
+ {
+ var key = _crudService.Create(new TestEntity()
+ {
+ Name = "crupest",
+ Age = 18,
+ });
+
+ Assert.Equal("crupest", key);
+
+ var entity = _crudService.GetByKey(key);
+ Assert.Equal("crupest", entity.Name);
+ Assert.Equal(18, entity.Age);
+ Assert.Null(entity.Height);
+ Assert.NotEmpty(entity.Secret);
+
+ var list = _crudService.GetAll();
+ entity = Assert.Single(list);
+ Assert.Equal("crupest", entity.Name);
+ Assert.Equal(18, entity.Age);
+ Assert.Null(entity.Height);
+ Assert.NotEmpty(entity.Secret);
+
+ var count = _crudService.GetCount();
+ Assert.Equal(1, count);
+
+ _crudService.UpdateByKey(key, new TestEntity()
+ {
+ Name = "crupest2.0",
+ Age = 22,
+ Height = 180,
+ });
+
+ entity = _crudService.GetByKey("crupest2.0");
+ Assert.Equal("crupest2.0", entity.Name);
+ Assert.Equal(22, entity.Age);
+ Assert.Equal(180, entity.Height);
+ Assert.NotEmpty(entity.Secret);
+
+ _crudService.DeleteByKey("crupest2.0");
+
+ count = _crudService.GetCount();
+ Assert.Equal(0, count);
+ }
+
+ [Fact]
+ public void EntityNotExistTest()
+ {
+ Assert.Throws<EntityNotExistException>(() => _crudService.GetByKey("KeyNotExist"));
+ Assert.Throws<EntityNotExistException>(() => _crudService.UpdateByKey("KeyNotExist", new TestEntity
+ {
+ Name = "crupest"
+ }));
+ }
+}
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/SqlCompareHelper.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/SqlCompareHelper.cs
new file mode 100644
index 0000000..72b6218
--- /dev/null
+++ b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/SqlCompareHelper.cs
@@ -0,0 +1,85 @@
+using System.Text;
+
+namespace CrupestApi.Commons.Crud.Tests;
+
+public class SqlCompareHelper
+{
+ private static List<char> SymbolTokens = new List<char>() { '(', ')', ';' };
+
+ public static List<string> SqlExtractWords(string? sql, bool toLower = true)
+ {
+ var result = new List<string>();
+
+ if (string.IsNullOrEmpty(sql))
+ {
+ return result;
+ }
+
+ var current = 0;
+
+ StringBuilder? wordBuilder = null;
+
+ while (current < sql.Length)
+ {
+ if (char.IsWhiteSpace(sql[current]))
+ {
+ if (wordBuilder is not null)
+ {
+ result.Add(wordBuilder.ToString());
+ wordBuilder = null;
+ }
+ }
+ else if (SymbolTokens.Contains(sql[current]))
+ {
+ if (wordBuilder is not null)
+ {
+ result.Add(wordBuilder.ToString());
+ wordBuilder = null;
+ }
+ result.Add(sql[current].ToString());
+ }
+ else
+ {
+ if (wordBuilder is not null)
+ {
+ wordBuilder.Append(sql[current]);
+ }
+ else
+ {
+ wordBuilder = new StringBuilder();
+ wordBuilder.Append(sql[current]);
+ }
+ }
+ current++;
+ }
+
+ if (wordBuilder is not null)
+ {
+ result.Add(wordBuilder.ToString());
+ }
+
+ if (toLower)
+ {
+ for (int i = 0; i < result.Count; i++)
+ {
+ result[i] = result[i].ToLower();
+ }
+ }
+
+ return result;
+ }
+
+ public static bool SqlEqual(string left, string right)
+ {
+ return SqlExtractWords(left) == SqlExtractWords(right);
+ }
+
+ [Fact]
+ public void TestSqlExtractWords()
+ {
+ var sql = "SELECT * FROM TableName WHERE (id = @abcd);";
+ var words = SqlExtractWords(sql);
+
+ Assert.Equal(new List<string> { "select", "*", "from", "tablename", "where", "(", "id", "=", "@abcd", ")", ";" }, words);
+ }
+}
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs
new file mode 100644
index 0000000..b0aa702
--- /dev/null
+++ b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TableInfoTest.cs
@@ -0,0 +1,35 @@
+using Microsoft.Extensions.Logging.Abstractions;
+
+namespace CrupestApi.Commons.Crud.Tests;
+
+public class TableInfoTest
+{
+ private static TableInfoFactory TableInfoFactory = new TableInfoFactory(new ColumnTypeProvider(), NullLoggerFactory.Instance);
+
+ private TableInfo _tableInfo;
+
+ public TableInfoTest()
+ {
+ _tableInfo = TableInfoFactory.Get(typeof(TestEntity));
+ }
+
+ [Fact]
+ public void TestColumnCount()
+ {
+ Assert.Equal(5, _tableInfo.Columns.Count);
+ Assert.Equal(4, _tableInfo.PropertyColumns.Count);
+ Assert.Equal(4, _tableInfo.ColumnProperties.Count);
+ Assert.Equal(1, _tableInfo.NonColumnProperties.Count);
+ }
+
+ [Fact]
+ public void GenerateSelectSqlTest()
+ {
+ var (sql, parameters) = _tableInfo.GenerateSelectSql(null, WhereClause.Create().Eq("Name", "Hello"));
+ var parameterName = parameters.First().Name;
+
+ // TODO: Is there a way to auto detect parameters?
+ SqlCompareHelper.SqlEqual($"SELECT * FROM TestEntity WHERE (Name = @{parameterName})", sql);
+ Assert.Equal("Hello", parameters.Get<string>(parameterName));
+ }
+}
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TestEntity.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TestEntity.cs
new file mode 100644
index 0000000..c15334c
--- /dev/null
+++ b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Crud/TestEntity.cs
@@ -0,0 +1,23 @@
+namespace CrupestApi.Commons.Crud.Tests;
+
+public class TestEntity
+{
+ [Column(ActAsKey = true, NotNull = true)]
+ public string Name { get; set; } = default!;
+
+ [Column(NotNull = true)]
+ public int Age { get; set; }
+
+ [Column]
+ public float? Height { get; set; }
+
+ [Column(OnlyGenerated = true, NotNull = true, NoUpdate = true)]
+ public string Secret { get; set; } = default!;
+
+ public static string SecretDefaultValueGenerator()
+ {
+ return "secret";
+ }
+
+ public string NonColumn { get; set; } = "Not A Column";
+}
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/CrupestApi.Commons.Tests.csproj b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/CrupestApi.Commons.Tests.csproj
new file mode 100644
index 0000000..0360ee1
--- /dev/null
+++ b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/CrupestApi.Commons.Tests.csproj
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+ <PropertyGroup>
+ <TargetFramework>net7.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+
+ <IsPackable>false</IsPackable>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="7.0.1" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
+ <PackageReference Include="xunit" Version="2.4.2" />
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+ <PrivateAssets>all</PrivateAssets>
+ </PackageReference>
+ <PackageReference Include="coverlet.collector" Version="3.2.0">
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+ <PrivateAssets>all</PrivateAssets>
+ </PackageReference>
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\CrupestApi.Commons\CrupestApi.Commons.csproj" />
+ </ItemGroup>
+
+</Project> \ No newline at end of file
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Usings.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Usings.cs
new file mode 100644
index 0000000..8c927eb
--- /dev/null
+++ b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons.Tests/Usings.cs
@@ -0,0 +1 @@
+global using Xunit; \ No newline at end of file