Skip to content

Commit a13b01f

Browse files
committed
test: ✅ add some test fixes
1 parent 4773337 commit a13b01f

File tree

48 files changed

+465
-371
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+465
-371
lines changed

.github/workflows/app-version.yml

+157-157
Large diffs are not rendered by default.

food-delivery-microservices.sln

+7
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodDelivery.Services.Ident
542542
EndProject
543543
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodDelivery.Services.Identity.TestShared", "tests\Services\Identity\FoodDelivery.Services.Identity.TestShared\FoodDelivery.Services.Identity.TestShared.csproj", "{D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C}"
544544
EndProject
545+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoodDelivery.Services.Identity.DependencyTests", "tests\Services\Identity\FoodDelivery.Services.Identity.DependencyTests\FoodDelivery.Services.Identity.DependencyTests.csproj", "{12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}"
546+
EndProject
545547
Global
546548
GlobalSection(SolutionConfigurationPlatforms) = preSolution
547549
Debug|Any CPU = Debug|Any CPU
@@ -812,6 +814,10 @@ Global
812814
{D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C}.Debug|Any CPU.Build.0 = Debug|Any CPU
813815
{D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C}.Release|Any CPU.ActiveCfg = Release|Any CPU
814816
{D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C}.Release|Any CPU.Build.0 = Release|Any CPU
817+
{12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
818+
{12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
819+
{12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
820+
{12AB9357-D6EE-404A-AADB-7D31BBFAFCD7}.Release|Any CPU.Build.0 = Release|Any CPU
815821
EndGlobalSection
816822
GlobalSection(SolutionProperties) = preSolution
817823
HideSolutionNode = FALSE
@@ -968,6 +974,7 @@ Global
968974
{D9A193CB-020A-4367-A954-6D4EDAD9E327} = {A9B8E9D0-8E3C-4495-B8FE-CBBAE3D46E62}
969975
{84A67508-47F8-41D8-95D8-3493FF35554A} = {A9B8E9D0-8E3C-4495-B8FE-CBBAE3D46E62}
970976
{D12A7726-3B12-4CCD-A3F4-4ABDD28BD44C} = {A9B8E9D0-8E3C-4495-B8FE-CBBAE3D46E62}
977+
{12AB9357-D6EE-404A-AADB-7D31BBFAFCD7} = {A9B8E9D0-8E3C-4495-B8FE-CBBAE3D46E62}
971978
EndGlobalSection
972979
GlobalSection(ExtensibilityGlobals) = postSolution
973980
SolutionGuid = {AD0585D6-CBA4-4818-86D8-0D914F18E390}

src/BuildingBlocks/BuildingBlocks.Core/Extensions/ServiceCollection/Dependency.cs

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Reflection;
22
using Microsoft.Extensions.DependencyInjection.Extensions;
3+
using Microsoft.Extensions.Hosting;
34

45
namespace BuildingBlocks.Core.Extensions.ServiceCollection;
56

@@ -233,29 +234,44 @@ params Assembly[] assembliesToScan
233234
)
234235
{
235236
var scanAssemblies = assembliesToScan.Length != 0 ? assembliesToScan : [Assembly.GetExecutingAssembly(),];
236-
var exceptions = new List<string>();
237237

238238
// for resolving scoped based dependencies without errors
239239
using var scope = rootServiceProvider.CreateScope();
240240
var sp = scope.ServiceProvider;
241241

242242
foreach (var serviceDescriptor in services)
243243
{
244+
// Skip services that are not typically resolved directly or are special cases
245+
if (
246+
serviceDescriptor.ServiceType == typeof(IHostedService)
247+
|| serviceDescriptor.ServiceType == typeof(IApplicationLifetime)
248+
)
249+
{
250+
continue;
251+
}
252+
244253
try
245254
{
246255
var serviceType = serviceDescriptor.ServiceType;
247256
if (scanAssemblies.Contains(serviceType.Assembly))
248-
sp.GetRequiredService(serviceType);
257+
{
258+
// Attempt to resolve the service
259+
var service = sp.GetService(serviceType);
260+
261+
// Assert: Check that the service was resolved if it's not meant to be optional
262+
if (
263+
serviceDescriptor.ImplementationInstance == null
264+
&& serviceDescriptor.ImplementationFactory == null
265+
)
266+
{
267+
service.NotBeNull();
268+
}
269+
}
249270
}
250-
catch (System.Exception e)
271+
catch (System.Exception ex)
251272
{
252-
exceptions.Add($"Unable to resolve '{serviceDescriptor.ServiceType.FullName}', detail: {e.Message}");
273+
throw new($"Failed to resolve service {serviceDescriptor.ServiceType.FullName}: {ex.Message}", ex);
253274
}
254275
}
255-
256-
if (exceptions.Count != 0)
257-
{
258-
throw new System.Exception(string.Join("\n", exceptions));
259-
}
260276
}
261277
}

src/BuildingBlocks/BuildingBlocks.Core/Extensions/ValidationExtensions.cs

+17-15
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public static T NotBeNull<T>([NotNull] this T? argument, System.Exception except
3535
return argument;
3636
}
3737

38-
public static string NotBeEmpty(
38+
public static string NotBeInvalid(
3939
this string argument,
4040
[CallerArgumentExpression("argument")] string? argumentName = null
4141
)
@@ -74,7 +74,7 @@ public static string NotBeNullOrWhiteSpace(
7474
return argument;
7575
}
7676

77-
public static Guid NotBeEmpty(
77+
public static Guid NotBeInvalid(
7878
this Guid argument,
7979
[CallerArgumentExpression("argument")] string? argumentName = null
8080
)
@@ -87,7 +87,7 @@ public static Guid NotBeEmpty(
8787
return argument;
8888
}
8989

90-
public static Guid NotBeEmpty(
90+
public static Guid NotBeInvalid(
9191
[NotNull] this Guid? argument,
9292
[CallerArgumentExpression("argument")] string? argumentName = null
9393
)
@@ -97,15 +97,15 @@ public static Guid NotBeEmpty(
9797
throw new ValidationException(message: $"{argumentName} cannot be null or empty.");
9898
}
9999

100-
return argument.Value.NotBeEmpty();
100+
return argument.Value.NotBeInvalid();
101101
}
102102

103103
public static int NotBeNegativeOrZero(
104104
this int argument,
105105
[CallerArgumentExpression("argument")] string? argumentName = null
106106
)
107107
{
108-
if (argument == 0)
108+
if (argument <= 0)
109109
{
110110
throw new ValidationException($"{argumentName} cannot be zero.");
111111
}
@@ -131,9 +131,9 @@ public static long NotBeNegativeOrZero(
131131
[CallerArgumentExpression("argument")] string? argumentName = null
132132
)
133133
{
134-
if (argument == 0)
134+
if (argument <= 0)
135135
{
136-
throw new ValidationException($"{argumentName} cannot be zero.");
136+
throw new ValidationException($"{argumentName} cannot be negative or zero.");
137137
}
138138

139139
return argument;
@@ -157,9 +157,9 @@ public static decimal NotBeNegativeOrZero(
157157
[CallerArgumentExpression("argument")] string? argumentName = null
158158
)
159159
{
160-
if (argument == 0)
160+
if (argument <= 0)
161161
{
162-
throw new ValidationException($"{argumentName} cannot be zero.");
162+
throw new ValidationException($"{argumentName} cannot be negative or zero.");
163163
}
164164

165165
return argument;
@@ -183,7 +183,7 @@ public static double NotBeNegativeOrZero(
183183
[CallerArgumentExpression("argument")] string? argumentName = null
184184
)
185185
{
186-
if (argument == 0)
186+
if (argument <= 0)
187187
{
188188
throw new ValidationException($"{argumentName} cannot be zero.");
189189
}
@@ -277,29 +277,31 @@ public static TEnum NotBeEmptyOrNull<TEnum>(
277277
throw new ValidationException(message: $"{argumentName} cannot be null or empty.");
278278
}
279279

280-
enumValue.NotBeEmpty();
280+
enumValue.NotBeInvalid();
281281

282282
return enumValue;
283283
}
284284

285-
public static TEnum NotBeEmpty<TEnum>(
285+
public static TEnum NotBeInvalid<TEnum>(
286286
[NotNull] this TEnum enumValue,
287287
[CallerArgumentExpression("enumValue")] string? argumentName = null
288288
)
289289
where TEnum : Enum
290290
{
291291
enumValue.NotBeNull();
292-
if (enumValue.Equals(default(TEnum)))
292+
293+
// returns `true` if `enumValue` corresponds to one of the defined values in `TEnum`
294+
if (!Enum.IsDefined(typeof(TEnum), enumValue))
293295
{
294296
throw new ValidationException(
295-
$"The value of '{argumentName}' cannot be the default value of '{typeof(TEnum).Name}' enum."
297+
$"The value of '{argumentName}' is not valid for enum of '{typeof(TEnum).Name}'."
296298
);
297299
}
298300

299301
return enumValue;
300302
}
301303

302-
public static void NotBeEmpty(
304+
public static void NotBeInvalid(
303305
this DateTime dateTime,
304306
[CallerArgumentExpression("dateTime")] string? argumentName = null
305307
)

src/BuildingBlocks/BuildingBlocks.Core/Types/MachineInstanceInfo.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public record MachineInstanceInfo : IMachineInstanceInfo
88
public MachineInstanceInfo(Guid clientId, string? clientGroup)
99
{
1010
clientGroup.NotBeNullOrWhiteSpace();
11-
clientId.NotBeEmpty();
11+
clientId.NotBeInvalid();
1212

1313
ClientId = clientId;
1414
ClientGroup = clientGroup;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace BuildingBlocks.Core.Web;
2+
3+
public static class Environments
4+
{
5+
public const string Development = "Development";
6+
public const string Staging = "Staging";
7+
public const string Production = "Production";
8+
public const string Test = "Test";
9+
public const string Docker = "Docker";
10+
public const string DependencyTest = "DependencyTest";
11+
}

src/BuildingBlocks/BuildingBlocks.Core/Web/Extensions/HostEnvironmentExtensions.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ namespace BuildingBlocks.Core.Web.Extensions;
44

55
public static class HostEnvironmentExtensions
66
{
7-
public static bool IsTest(this IHostEnvironment env) => env.IsEnvironment("test");
7+
public static bool IsTest(this IHostEnvironment env) => env.IsEnvironment("Test");
88

9-
public static bool IsDocker(this IHostEnvironment env) => env.IsEnvironment("docker");
9+
public static bool IsDependencyTest(this IHostEnvironment env) => env.IsEnvironment("DependencyTest");
10+
11+
public static bool IsDocker(this IHostEnvironment env) => env.IsEnvironment("Docker");
1012
}

src/Services/Catalogs/FoodDelivery.Services.Catalogs.Api/Program.cs

+2-6
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,9 @@
5353

5454
var app = builder.Build();
5555

56-
if (app.Environment.IsDevelopment() || app.Environment.IsTest())
56+
if (app.Environment.IsDependencyTest())
5757
{
58-
app.Services.ValidateDependencies(
59-
builder.Services,
60-
typeof(CatalogsMetadata).Assembly,
61-
Assembly.GetExecutingAssembly()
62-
);
58+
return;
6359
}
6460

6561
/*----------------- Module Middleware Setup ------------------*/

src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/CreateProduct.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ public static CreateProduct Of(
8787
Name.Of(name),
8888
Price.Of(price),
8989
Stock.Of(stock, restockThreshold, maxStockThreshold),
90-
status.NotBeEmpty(),
90+
status.NotBeInvalid(),
9191
productType,
9292
Dimensions.Of(width, height, depth),
9393
Size.Of(size),
94-
color.NotBeEmpty(),
94+
color.NotBeInvalid(),
9595
CategoryId.Of(categoryId),
9696
SupplierId.Of(supplierId),
9797
BrandId.Of(brandId),

src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Features/CreatingProduct/v1/Events/Domain/ProductCreated.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ public static ProductCreated Of(
6666
stock.Available,
6767
stock.RestockThreshold,
6868
stock.MaxStockThreshold,
69-
status.NotBeEmpty(),
69+
status.NotBeInvalid(),
7070
dimensions.Width,
7171
dimensions.Height,
7272
dimensions.Depth,
7373
size,
74-
color.NotBeEmpty(),
74+
color.NotBeInvalid(),
7575
categoryId,
7676
supplierId,
7777
brandId,

src/Services/Catalogs/FoodDelivery.Services.Catalogs/Products/Models/Product.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ public void ChangeProductDetail(
137137
name.NotBeNull();
138138
Name = name;
139139

140-
status.NotBeEmpty();
140+
status.NotBeInvalid();
141141
ProductStatus = status;
142142

143-
productType.NotBeEmpty();
143+
productType.NotBeInvalid();
144144
ProductType = productType;
145145

146146
dimensions.NotBeNull();
@@ -149,7 +149,7 @@ public void ChangeProductDetail(
149149
size.NotBeNull();
150150
Size = size;
151151

152-
color.NotBeEmpty();
152+
color.NotBeInvalid();
153153
Color = color;
154154

155155
// input validation will do in the command and our value objects, here we just do business validation
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
namespace FoodDelivery.Services.Customers.Api;
22

3-
public class CustomersApiMetadata { }
3+
public class CustomersApiMetadata;

src/Services/Customers/FoodDelivery.Services.Customers.Api/Program.cs

+2-6
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,9 @@
5555

5656
var app = builder.Build();
5757

58-
if (app.Environment.IsDevelopment() || app.Environment.IsTest())
58+
if (app.Environment.IsDependencyTest())
5959
{
60-
// app.Services.ValidateDependencies(
61-
// builder.Services,
62-
// typeof(CustomersMetadata).Assembly,
63-
// Assembly.GetExecutingAssembly()
64-
// );
60+
return;
6561
}
6662

6763
/*----------------- Module Middleware Setup ------------------*/

src/Services/Customers/FoodDelivery.Services.Customers/Customers/CustomersModuleMapping.cs

+22-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using FoodDelivery.Services.Customers.Customers.Features.UpdatingCustomer.v1;
55
using FoodDelivery.Services.Customers.Customers.Features.UpdatingCustomer.v1.Events.Domain;
66
using FoodDelivery.Services.Customers.Customers.Features.UpdatingCustomer.v1.Read.Mongo;
7+
using FoodDelivery.Services.Customers.Customers.Models.Reads;
78
using Riok.Mapperly.Abstractions;
89

910
namespace FoodDelivery.Services.Customers.Customers;
@@ -112,16 +113,28 @@ internal static partial class CustomersModuleMapping
112113
)]
113114
internal static partial UpdateCustomerRead ToUpdateCustomerRead(this Models.Customer customer);
114115

115-
[MapProperty(nameof(UpdateCustomerRead.CustomerId), nameof(Models.Reads.Customer.CustomerId))]
116-
[MapProperty(nameof(UpdateCustomerRead.Id), nameof(Models.Reads.Customer.Id))]
117-
[MapProperty(nameof(UpdateCustomerRead.OccurredOn), nameof(Models.Reads.Customer.Created))]
118-
internal static partial Models.Reads.Customer ToCustomer(this UpdateCustomerRead updateCustomerRead);
119-
120116
// https://mapperly.riok.app/docs/configuration/existing-target/
121-
[MapProperty(nameof(UpdateCustomerRead.CustomerId), nameof(Models.Reads.Customer.CustomerId))]
122-
[MapProperty(nameof(UpdateCustomerRead.Id), nameof(Models.Reads.Customer.Id))]
123-
[MapProperty(nameof(UpdateCustomerRead.OccurredOn), nameof(Models.Reads.Customer.Created))]
124-
internal static partial void ToCustomer(this UpdateCustomerRead updateCustomerRead, Models.Reads.Customer customer);
117+
// Todo: doesn't map correctly
118+
internal static Models.Reads.Customer ToCustomer(this UpdateCustomerRead updateCustomerRead)
119+
{
120+
return new Customer
121+
{
122+
Created = updateCustomerRead.OccurredOn,
123+
Email = updateCustomerRead.Email,
124+
CustomerId = updateCustomerRead.CustomerId,
125+
IdentityId = updateCustomerRead.IdentityId,
126+
FirstName = updateCustomerRead.FirstName,
127+
LastName = updateCustomerRead.LastName,
128+
FullName = updateCustomerRead.FullName,
129+
PhoneNumber = updateCustomerRead.PhoneNumber,
130+
Country = updateCustomerRead.Country,
131+
City = updateCustomerRead.City,
132+
DetailAddress = updateCustomerRead.DetailAddress,
133+
Nationality = updateCustomerRead.Nationality,
134+
BirthDate = updateCustomerRead.BirthDate,
135+
Id = updateCustomerRead.Id
136+
};
137+
}
125138

126139
[MapperIgnoreTarget(nameof(UpdateCustomerRead.Id))]
127140
[MapProperty(nameof(CustomerUpdated.Id), nameof(UpdateCustomerRead.CustomerId))]

src/Services/Customers/FoodDelivery.Services.Customers/Customers/Features/CreatingCustomer/v1/CreateCustomer.cs

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using BuildingBlocks.Abstractions.Commands;
22
using BuildingBlocks.Core.Domain.ValueObjects;
3+
using BuildingBlocks.Core.Exception.Types;
34
using BuildingBlocks.Core.Extensions;
45
using BuildingBlocks.Core.IdsGenerator;
56
using BuildingBlocks.Validation.Extensions;
@@ -58,6 +59,8 @@ public async Task<CreateCustomerResult> Handle(CreateCustomer command, Cancellat
5859
throw new CustomerAlreadyExistsException($"Customer with email '{command.Email}' already exists.");
5960

6061
var identityUser = await identityApiClient.GetUserByEmailAsync(command.Email, cancellationToken);
62+
if (identityUser is null)
63+
throw new NotFoundAppException($"user with email {command.Email} not found.");
6164

6265
var customer = Customer.Create(
6366
CustomerId.Of(command.Id),

0 commit comments

Comments
 (0)