Skip to content

Commit 7e09c88

Browse files
authored
Merge pull request #51 from samanazadi1996/refactor-test-integration
Refactor test integration
2 parents 4559e0e + 6535d09 commit 7e09c88

File tree

11 files changed

+245
-42
lines changed

11 files changed

+245
-42
lines changed

src/OA.Infrastructure/Extension/ConfigureServiceContainer.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,20 @@ namespace OA.Infrastructure.Extension;
1515

1616
public static class ConfigureServiceContainer
1717
{
18-
public static void AddDbContext(this IServiceCollection serviceCollection,
19-
IConfiguration configuration, IConfigurationRoot configRoot)
18+
public static void AddDbContext(this IServiceCollection serviceCollection, IConfiguration configuration)
2019
{
21-
serviceCollection.AddDbContext<ApplicationDbContext>(options =>
22-
options.UseSqlServer(configuration.GetConnectionString("OnionArchConn") ?? configRoot["ConnectionStrings:OnionArchConn"]
23-
, b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)));
2420

21+
if (configuration.GetValue<bool>("UseInMemoryDatabase"))
22+
{
23+
serviceCollection.AddDbContext<ApplicationDbContext>(options =>
24+
options.UseInMemoryDatabase(nameof(ApplicationDbContext)));
25+
}
26+
else
27+
{
28+
serviceCollection.AddDbContext<ApplicationDbContext>(options =>
29+
options.UseSqlServer(configuration.GetConnectionString("OnionArchConn")
30+
, b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)));
31+
}
2532

2633
}
2734

src/OA.Service/DependencyInjection.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static void AddIdentityService(this IServiceCollection services, IConfigu
3232
if (configuration.GetValue<bool>("UseInMemoryDatabase"))
3333
{
3434
services.AddDbContext<IdentityContext>(options =>
35-
options.UseInMemoryDatabase("IdentityDb"));
35+
options.UseInMemoryDatabase(nameof(IdentityContext)));
3636
}
3737
else
3838
{
@@ -41,6 +41,7 @@ public static void AddIdentityService(this IServiceCollection services, IConfigu
4141
configuration.GetConnectionString("IdentityConnection"),
4242
b => b.MigrationsAssembly(typeof(IdentityContext).Assembly.FullName)));
4343
}
44+
4445
services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<IdentityContext>()
4546
.AddDefaultTokenProviders();
4647
#region Services

src/OA.Test.Integration/ApiCustomerTest.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
using NUnit.Framework;
2+
using OA.Service.Features.CustomerFeatures.Commands;
3+
using System.Net;
4+
5+
namespace OA.Test.Integration.ApiEndpoints;
6+
7+
public class ApiCustomerTest : TestClientProvider
8+
{
9+
[TestCase("api/v1/Customer", HttpStatusCode.OK)]
10+
[TestCase("api/v1/Customer/100", HttpStatusCode.NoContent)]
11+
public async Task GetAllCustomerTestAsync(string url, HttpStatusCode result)
12+
{
13+
var request = new HttpRequestMessage(HttpMethod.Get, url);
14+
15+
var response = await Client
16+
.AddBearerTokenAuthorization()
17+
.SendAsync(request);
18+
19+
Assert.That(response.StatusCode, Is.EqualTo(result));
20+
}
21+
22+
[Test]
23+
public async Task CreateCustomerTestAsync()
24+
{
25+
// Create a customer model
26+
var model = new CreateCustomerCommand
27+
{
28+
CustomerName = "John Wick",
29+
ContactName = "John Wick",
30+
ContactTitle = "Manager",
31+
Address = "123 Main St",
32+
City = "New York",
33+
Region = "NY",
34+
PostalCode = "10001",
35+
Country = "USA",
36+
Phone = "123-456-7890",
37+
Fax = "987-654-3210"
38+
};
39+
40+
// Create POST request
41+
var request = new HttpRequestMessage(HttpMethod.Post, "api/v1/Customer")
42+
{
43+
Content = HttpClientExtensions.SerializeAndCreateContent(model)
44+
};
45+
46+
// Send request and check response
47+
var response = await Client
48+
.AddBearerTokenAuthorization()
49+
.SendAsync(request);
50+
51+
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
52+
}
53+
54+
[Test]
55+
public async Task UpdateCustomerTestAsync()
56+
{
57+
// First, create a new customer
58+
var createModel = new CreateCustomerCommand
59+
{
60+
CustomerName = "John Wick",
61+
ContactName = "John Wick",
62+
ContactTitle = "Manager",
63+
Address = "123 Main St",
64+
City = "New York",
65+
Region = "NY",
66+
PostalCode = "10001",
67+
Country = "USA",
68+
Phone = "123-456-7890",
69+
Fax = "987-654-3210"
70+
};
71+
72+
var createRequest = new HttpRequestMessage(HttpMethod.Post, "api/v1/Customer")
73+
{
74+
Content = HttpClientExtensions.SerializeAndCreateContent(createModel)
75+
};
76+
77+
var createResponse = await Client
78+
.AddBearerTokenAuthorization()
79+
.SendAsync(createRequest);
80+
81+
Assert.That(createResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));
82+
83+
// Now update the new customer
84+
var updateModel = new UpdateCustomerCommand
85+
{
86+
Id = int.Parse(await createResponse.Content.ReadAsStringAsync()),
87+
CustomerName = "Updated John Wick",
88+
ContactName = "Jane Wick",
89+
ContactTitle = "Director",
90+
Address = "456 Another St",
91+
City = "Los Angeles",
92+
Region = "CA",
93+
PostalCode = "90001",
94+
Country = "USA",
95+
Phone = "987-654-3210",
96+
Fax = "123-456-7890"
97+
};
98+
99+
var updateRequest = new HttpRequestMessage(HttpMethod.Put, $"api/v1/Customer/{updateModel.Id}")
100+
{
101+
Content = HttpClientExtensions.SerializeAndCreateContent(updateModel)
102+
};
103+
104+
// Send update request and check response status
105+
var updateResponse = await Client
106+
.AddBearerTokenAuthorization()
107+
.SendAsync(updateRequest);
108+
109+
Assert.That(updateResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));
110+
}
111+
112+
[Test]
113+
public async Task DeleteCustomerTestAsync()
114+
{
115+
// First, create a new customer
116+
var createModel = new CreateCustomerCommand
117+
{
118+
CustomerName = "John Wick",
119+
ContactName = "John Wick",
120+
ContactTitle = "Manager",
121+
Address = "123 Main St",
122+
City = "New York",
123+
Region = "NY",
124+
PostalCode = "10001",
125+
Country = "USA",
126+
Phone = "123-456-7890",
127+
Fax = "987-654-3210"
128+
};
129+
130+
var createRequest = new HttpRequestMessage(HttpMethod.Post, "api/v1/Customer")
131+
{
132+
Content = HttpClientExtensions.SerializeAndCreateContent(createModel)
133+
};
134+
135+
var createResponse = await Client
136+
.AddBearerTokenAuthorization()
137+
.SendAsync(createRequest);
138+
139+
Assert.That(createResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));
140+
141+
// Get the created customer's ID
142+
int customerId = int.Parse(await createResponse.Content.ReadAsStringAsync());
143+
144+
// Now delete the customer
145+
var deleteRequest = new HttpRequestMessage(HttpMethod.Delete, $"api/v1/Customer/{customerId}");
146+
147+
// Send delete request and check response status
148+
var deleteResponse = await Client
149+
.AddBearerTokenAuthorization()
150+
.SendAsync(deleteRequest);
151+
152+
Assert.That(deleteResponse.StatusCode, Is.EqualTo(HttpStatusCode.OK));
153+
154+
// Optionally, you can check if the customer has been actually deleted by trying to retrieve it
155+
var getRequest = new HttpRequestMessage(HttpMethod.Get, $"api/v1/Customer/{customerId}");
156+
var getResponse = await Client.AddBearerTokenAuthorization().SendAsync(getRequest);
157+
Assert.That(getResponse.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
158+
}
159+
160+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace OA.Test.Integration;
2+
3+
internal static class HttpClientAuthExtensions
4+
{
5+
const string AuthorizationKey = "Authorization";
6+
7+
// JWT generated for 'superadmin@gmail.com' with max expiry date
8+
const string Jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdXBlcmFkbWluIiwianRpIjoiNDIzNzhlNjktMmI0YS00ZTVhLWEyZjUtM2RjMTI4YTFhNGFiIiwiZW1haWwiOiJzdXBlcmFkbWluQGdtYWlsLmNvbSIsInVpZCI6Ijk3Y2Y0ZDkwLWYyY2EtNGEwZi04MjdhLWU2ZmVkZTE2ODQyYSIsImlwIjoiMTkyLjE2OC40NS4xMzUiLCJyb2xlcyI6WyJTdXBlckFkbWluIiwiQWRtaW4iLCJCYXNpYyIsIk1vZGVyYXRvciJdLCJleHAiOjI1MzQwMjI4ODIwMCwiaXNzIjoiSWRlbnRpdHkiLCJhdWQiOiJJZGVudGl0eVVzZXIifQ.sYDCw6R-HtNfC8xJYENmq39iYJtXiVrAh5dboTrGlX8";
9+
10+
public static HttpClient AddBearerTokenAuthorization(this HttpClient client)
11+
{
12+
// Check if the Authorization header is already present
13+
if (client.DefaultRequestHeaders.Any(p => p.Key == AuthorizationKey))
14+
return client;
15+
16+
client.DefaultRequestHeaders.Add(AuthorizationKey, $"Bearer {Jwt}");
17+
18+
return client;
19+
20+
}
21+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Text.Json;
2+
using System.Text;
3+
4+
namespace OA.Test.Integration;
5+
6+
public static class HttpClientExtensions
7+
{
8+
static readonly JsonSerializerOptions DefaultJsonOptions = new JsonSerializerOptions
9+
{
10+
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
11+
};
12+
13+
public static StringContent SerializeAndCreateContent<T>(T model)
14+
{
15+
string jsonContent = JsonSerializer.Serialize(model, DefaultJsonOptions);
16+
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
17+
return content;
18+
}
19+
}

src/OA.Test.Integration/OA.Test.Integration.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.8" />
13+
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
1414
<PackageReference Include="nunit" Version="4.2.2" />
1515
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
1616
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
11
using Microsoft.AspNetCore.Hosting;
2-
using Microsoft.AspNetCore.TestHost;
2+
using Microsoft.AspNetCore.Mvc.Testing;
33

44
namespace OA.Test.Integration;
55

6-
public class TestClientProvider
6+
public class TestClientProvider : IDisposable
77
{
8-
public HttpClient Client { get; private set; }
8+
private readonly WebApplicationFactory<Program> _factory;
9+
public HttpClient Client { get; }
910

1011
public TestClientProvider()
1112
{
12-
var server = new TestServer(new WebHostBuilder()
13-
.UseContentRoot(Directory.GetCurrentDirectory())
14-
.UseStartup<Program>());
13+
// Initialize WebApplicationFactory with the Program class
14+
_factory = new WebApplicationFactory<Program>()
15+
.WithWebHostBuilder(builder =>
16+
{
17+
// Set the environment to Test
18+
builder.UseEnvironment("Test");
19+
});
1520

16-
Client = server.CreateClient();
21+
Client = _factory.CreateClient();
22+
}
23+
24+
public void Dispose()
25+
{
26+
Client.Dispose();
27+
_factory.Dispose();
1728
}
1829
}

src/OA/Program.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,13 @@
1010
var builder = WebApplication.CreateBuilder(args);
1111

1212

13-
// Build the configuration
14-
var configRoot = new ConfigurationBuilder()
15-
.SetBasePath(Directory.GetCurrentDirectory())
16-
.AddJsonFile("appsettings.json")
17-
.Build();
18-
1913
// Bind AppSettings
2014
var appSettings = new AppSettings();
2115
builder.Configuration.Bind(appSettings);
2216

2317
// Add services to the container.
2418
builder.Services.AddControllers();
25-
builder.Services.AddDbContext(builder.Configuration, configRoot);
19+
builder.Services.AddDbContext(builder.Configuration);
2620
builder.Services.AddIdentityService(builder.Configuration);
2721
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
2822
builder.Services.AddScopedServices();
@@ -96,6 +90,7 @@
9690
// Run the application
9791
app.Run();
9892

93+
9994
public partial class Program
10095
{
10196
}

src/OA/appsettings.Test.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"UseInMemoryDatabase": true,
3+
"Serilog": {
4+
"MinimumLevel": "Information",
5+
"Properties": {
6+
"Application": "Onion Architecture application"
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)