Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue / Add Service Blueprint Tests #81

Merged
merged 25 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ run:
fi
test:
dotnet test

# dotnet test -c Release --collect:"XPlat Code Coverage" --logger trx --results-directory .coverage --settings test/runsettings.xml
# reportgenerator -reports:.coverage\0d84daea-0041-4f8d-a93c-51d3d348fa69\coverage.cobertura.xml;.coverage\d606db4f-8ea5-4e9f-a304-f37b22a1f34b\coverage.cobertura.xml -targetdir:.coverage/report
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,19 @@ public async Task<TEntity> CommitAsync<TEntity>(Func<Task<TEntity>> action)
return result;
}

public async Task CommitAsync<TEntity>(TEntity entity, Action<TEntity> action)
public async Task CommitAsync<TEntity>(TEntity? entity, Action<TEntity> action)
{
if (entity is null) { return; }

action(entity);

await CommitAndBeginNewTransaction();
}

public async Task CommitAsync<TEntity>(TEntity entity, Func<TEntity, Task> action)
public async Task CommitAsync<TEntity>(TEntity? entity, Func<TEntity, Task> action)
{
if (entity is null) { return; }

await action(entity);

await CommitAndBeginNewTransaction();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,19 @@ public async Task<TEntity> CommitAsync<TEntity>(Func<Task<TEntity>> action)
return await action();
}

public Task CommitAsync<TEntity>(TEntity entity, Action<TEntity> action)
public Task CommitAsync<TEntity>(TEntity? entity, Action<TEntity> action)
{
if (entity is null) { return Task.CompletedTask; }

action(entity);

return Task.CompletedTask;
}

public async Task CommitAsync<TEntity>(TEntity entity, Func<TEntity, Task> action)
public async Task CommitAsync<TEntity>(TEntity? entity, Func<TEntity, Task> action)
{
if (entity is null) { return; }

await action(entity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ public static void ShouldHaveOneParameter<T>(this MethodInfo source)

#region Settings

public static void ASetting<T>(this Mocker mockMe,
string? key = default,
T? value = default
) => mockMe.ASetting(key: key, value: $"{value}");

public static void ASetting(this Mocker mockMe,
string? key = default,
string? value = default
Expand Down
4 changes: 2 additions & 2 deletions src/blueprints/Do.Blueprints.Service/Database/ITransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ public interface ITransaction
Task<TEntity> CommitAsync<TEntity>(Func<TEntity> action);
Task<TEntity> CommitAsync<TEntity>(Func<Task<TEntity>> action);

Task CommitAsync<TEntity>(TEntity entity, Action<TEntity> action);
Task CommitAsync<TEntity>(TEntity entity, Func<TEntity, Task> action);
Task CommitAsync<TEntity>(TEntity? entity, Action<TEntity> action);
Task CommitAsync<TEntity>(TEntity? entity, Func<TEntity, Task> action);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,33 @@ public class EntityController
public EntityController(IServiceProvider serviceProvider) =>
_serviceProvider = serviceProvider;

public record ByRequest(
Guid guid = default,
string @string = default,
string stringData = default,
int int32 = default,
Uri uri = default,
Status status = default,
DateTime dateTime = default
);

[HttpGet]
[Route("entities")]
public List<Entity> By([FromQuery] string @string = default, [FromQuery] int? take = null, [FromQuery] int? skip = null)
public List<Entity> By([FromQuery] ByRequest request, [FromQuery] int? take = null, [FromQuery] int? skip = null)
{
var target = _serviceProvider.GetRequiredService<Entities>();

var result = target.By(@string: @string, take: take, skip: skip);
var result = target.By(
guid: request.guid,
@string: request.@string,
stringData: request.stringData,
int32: request.int32,
uri: request.uri,
status: request.status,
dateTime: request.dateTime,
take: take,
skip: skip
);

return result;
}
Expand All @@ -33,15 +53,24 @@ public Entity Get(Guid id)
return target.SingleById(id);
}

public record NewRequest(Guid Guid, string String, string StringData, int Int32, Uri Uri, object Dynamic, Status Status);
public record NewRequest(
Guid Guid = default,
string String = default,
string StringData = default,
int Int32 = default,
Uri Uri = default,
object Dynamic = default,
Status Status = default,
DateTime DateTime = default
);

[HttpPost]
[Route("entities")]
public Entity New([FromBody] NewRequest request)
{
var target = _serviceProvider.GetRequiredService<Entity>();

return target.With(request.Guid, request.String, request.StringData, request.Int32, request.Uri, request.Dynamic, request.Status);
return target.With(request.Guid, request.String, request.StringData, request.Int32, request.Uri, request.Dynamic, request.Status, request.DateTime);
}

[HttpDelete]
Expand All @@ -53,7 +82,15 @@ public void Delete([FromRoute] Guid id)
target.Delete();
}

public record UpdateRequest(Guid Guid, string String, string StringData, int Int32, Uri Uri, object Dynamic, Status Status,
public record UpdateRequest(
Guid Guid = default,
string String = default,
string StringData = default,
int Int32 = default,
Uri Uri = default,
object Dynamic = default,
Status Status = default,
DateTime DateTime = default,
bool useTransaction = false,
bool throwError = false
);
Expand All @@ -64,7 +101,7 @@ public async Task Update([FromRoute] Guid id, [FromBody] UpdateRequest request)
{
var target = _serviceProvider.GetRequiredService<IQueryContext<Entity>>().SingleById(id);

await target.Update(request.Guid, request.String, request.StringData, request.Int32, request.Uri, request.Dynamic, request.Status,
await target.Update(request.Guid, request.String, request.StringData, request.Int32, request.Uri, request.Dynamic, request.Status, request.DateTime,
useTransaction: request.useTransaction,
throwError: request.throwError
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// This file will be auto-generated

using Do.Orm;
using Microsoft.AspNetCore.Mvc;

namespace Do.Test;
Expand Down Expand Up @@ -54,6 +55,22 @@ public void TestException(bool handled)
target.TestException(handled);
}

public record TestTransactionNullableRequest(Guid? EntityId = default);

[HttpPost]
[Produces("application/json")]
[Route("singleton/test-transaction-nullable")]
public async Task TestTransactionNullable([FromBody] TestTransactionNullableRequest request)
{
var target = _serviceProvider.GetRequiredService<Singleton>();

await target.TestTransactionNullable(
entity: request.EntityId.HasValue
? _serviceProvider.GetRequiredService<IQueryContext<Entity>>().SingleById(request.EntityId.Value)
: null
);
}

[HttpPut]
[Produces("application/json")]
[Route("singleton/test-async-object")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,30 @@ public void Mock_configuration_returns_mocked_settings_value()
actual.ShouldBe(10);
}

[Test]
public void Mock_configuration_returns_default_value_when_not_set()
{
MockMe.ASetting<int>("Config");
var configuration = GiveMe.The<IConfiguration>();

var actual = configuration.GetRequiredValue<int>("Config");

actual.ShouldBe(0);
}

[TestCase(42)]
[TestCase("value")]
[TestCase(false)]
public void Mock_ASetting_value_parameter_is_generic<T>(T value)
{
MockMe.ASetting("Config", value);
var configuration = GiveMe.The<IConfiguration>();

var actual = configuration.GetRequiredValue<T>("Config");

actual.ShouldBeEquivalentTo(value);
}

[TestCase("Int", 42)] // defined in TestServiceSpec
[TestCase("String", "test value")] // defined in TestServiceSpec
public void Mock_configuration_uses_settings_value_provider_for_not_mocked_config_sections(string key, object value)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
namespace Do.Test.DataAccess;

public class MappingProperties : TestServiceSpec
{
[Test]
public async Task Guid()
{
var entity = GiveMe.An<Entity>().With(guid: GiveMe.AGuid("EB8DD0A1-07B7-42EC-AAD3-14B2A623C01E"));
entity.Guid.ShouldBe(GiveMe.AGuid("EB8DD0A1-07B7-42EC-AAD3-14B2A623C01E"));

await entity.Update(guid: GiveMe.AGuid("AB8DD0A1-07B7-42EC-AAD3-14B2A623C01E"));
entity.Guid.ShouldBe(GiveMe.AGuid("AB8DD0A1-07B7-42EC-AAD3-14B2A623C01E"));

var actual = GiveMe.The<Entities>().By(guid: GiveMe.AGuid("AB8DD0A1-07B7-42EC-AAD3-14B2A623C01E")).FirstOrDefault();
actual.ShouldBe(entity);
}

[Test]
public async Task String()
{
var entity = GiveMe.An<Entity>().With(@string: "string");
entity.String.ShouldBe("string");

await entity.Update(@string: "test");
entity.String.ShouldBe("test");

var actual = GiveMe.The<Entities>().By(@string: "test").FirstOrDefault();
actual.ShouldBe(entity);
}

[Test]
public async Task String_data()
{
var entity = GiveMe.An<Entity>().With(stringData: "string");
entity.StringData.ShouldBe("string");

await entity.Update(stringData: "test");
entity.StringData.ShouldBe("test");

var actual = GiveMe.The<Entities>().By(stringData: "test").FirstOrDefault();
actual.ShouldBe(entity);
}

[Test]
public async Task Object()
{
var entity = GiveMe.An<Entity>().With(dynamic: new { dynamic = "dynamic" });
entity.Dynamic.ShouldBe(new { dynamic = "dynamic" });

await entity.Update(dynamic: new { update = "update" });
entity.Dynamic.ShouldBe(new { update = "update" });
}

[Test]
public async Task Int()
{
var entity = GiveMe.An<Entity>().With(int32: 5);
entity.Int32.ShouldBe(5);

await entity.Update(int32: 1);
entity.Int32.ShouldBe(1);

var actual = GiveMe.The<Entities>().By(int32: 1).FirstOrDefault();
actual.ShouldBe(entity);
}

[Test]
public async Task Enum()
{
var entity = GiveMe.An<Entity>().With(@enum: Status.Enabled);
entity.Enum.ShouldBe(Status.Enabled);

await entity.Update(@enum: Status.Disabled);
entity.Enum.ShouldBe(Status.Disabled);

var actual = GiveMe.The<Entities>().By(status: Status.Disabled).FirstOrDefault();
actual.ShouldBe(entity);
}

[Test]
public async Task DateTime()
{
var entity = GiveMe.An<Entity>().With(dateTime: GiveMe.ADateTime(year: 2023, month: 11, day: 29));
entity.DateTime.ShouldBe(GiveMe.ADateTime(year: 2023, month: 11, day: 29));

await entity.Update(dateTime: GiveMe.ADateTime(year: 2023, month: 11, day: 30));
entity.DateTime.ShouldBe(GiveMe.ADateTime(year: 2023, month: 11, day: 30));

var actual = GiveMe.The<Entities>().By(dateTime: GiveMe.ADateTime(year: 2023, month: 11, day: 30)).FirstOrDefault();
actual.ShouldBe(entity);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace Do.Test.DataAccess;

public class PersistingEntity : TestServiceSpec
cihandeniz marked this conversation as resolved.
Show resolved Hide resolved
{
[Test]
public void Created_entity_persists()
{
var newEntity = GiveMe.A<Func<Entity>>();

var actual = newEntity().With(
guid: Guid.NewGuid(),
@string: string.Empty,
stringData: string.Empty,
int32: 0,
uri: GiveMe.AUrl(),
@dynamic: new { },
@enum: Status.Disabled
);

actual.ShouldBeInserted();
}

[Test]
public void Entity_is_deleted_successfully()
{
var entity = GiveMe.AnEntity();

entity.Delete();

entity.ShouldBeDeleted();
}

[Test]
public void Object_user_type_supports_special_characters_to_be_used_within_strings()
{
var entity = GiveMe.AnEntity(dynamic: new { test = "ğ€@test" });
var entities = GiveMe.The<Entities>();

Func<List<Entity>> task = () => entities.By(@string: entity.String);

task.ShouldNotThrow();
}
}
Loading