diff --git a/GroundsForSupport.sln b/GroundsForSupport.sln
index 37e03a0..539cc38 100644
--- a/GroundsForSupport.sln
+++ b/GroundsForSupport.sln
@@ -11,7 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0AB3BF05
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GroundsForSupport.Server.Tests", "GroundsForSupport.Server.Tests", "{56565355-472A-D7A5-BBD6-5A9243A600D2}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroundsForSupport.API.Tests", "tests\GroundsForSupport.Server.Tests\GroundsForSupport.API.Tests.csproj", "{73D83B11-C5BC-4C4B-82BF-2DCEE689EDDC}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GroundsForSupport.Server.Tests", "tests\GroundsForSupport.Server.Tests\GroundsForSupport.Server.Tests.csproj", "{73D83B11-C5BC-4C4B-82BF-2DCEE689EDDC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/src/GroundsForSupport.Server/Data/ContextOptions.cs b/src/GroundsForSupport.Server/Data/ContextOptions.cs
index e4eaacc..1413737 100644
--- a/src/GroundsForSupport.Server/Data/ContextOptions.cs
+++ b/src/GroundsForSupport.Server/Data/ContextOptions.cs
@@ -4,7 +4,7 @@ namespace GroundsForSupport.Server.Data;
internal sealed record ContextOptions
{
- public string DatabaseFilePath { get; init; } = "GroundsForSupport.db";
+ public string DatabaseFilePath { get; init; } = string.Empty;
public string GetFullyQualifiedDatabasePath()
{
return Path.GetFullPath(DatabaseFilePath, AppContext.BaseDirectory);
diff --git a/src/GroundsForSupport.Server/GroundsForSupport.Server.csproj b/src/GroundsForSupport.Server/GroundsForSupport.Server.csproj
index 74aa631..da4765d 100644
--- a/src/GroundsForSupport.Server/GroundsForSupport.Server.csproj
+++ b/src/GroundsForSupport.Server/GroundsForSupport.Server.csproj
@@ -16,6 +16,11 @@
+
+
+
+
+
diff --git a/src/GroundsForSupport.Server/Payments/Endpoints/CreatePaymentIntentEndpoint.cs b/src/GroundsForSupport.Server/Payments/Endpoints/CreatePaymentIntentEndpoint.cs
index 0ac607b..ebd0505 100644
--- a/src/GroundsForSupport.Server/Payments/Endpoints/CreatePaymentIntentEndpoint.cs
+++ b/src/GroundsForSupport.Server/Payments/Endpoints/CreatePaymentIntentEndpoint.cs
@@ -16,7 +16,8 @@ internal static class CreatePaymentIntentEndpoint
public static async Task CreatePaymentIntentHandler(
Request request,
- IStripeService stripeService
+ IStripeService stripeService,
+ CancellationToken cancellationToken
)
{
var validationErrors = request.Validate(new ValidationContext(request));
@@ -32,7 +33,8 @@ internal static class CreatePaymentIntentEndpoint
request.Name,
request.Amount,
request.Message,
- request.Email
+ request.Email,
+ cancellationToken
);
if (isSuccess is false)
diff --git a/src/GroundsForSupport.Server/Payments/Stripe/IStripeService.cs b/src/GroundsForSupport.Server/Payments/Stripe/IStripeService.cs
index 3481c94..6575709 100644
--- a/src/GroundsForSupport.Server/Payments/Stripe/IStripeService.cs
+++ b/src/GroundsForSupport.Server/Payments/Stripe/IStripeService.cs
@@ -6,6 +6,7 @@ internal interface IStripeService
string name,
decimal amount,
string? message,
- string? email
+ string? email,
+ CancellationToken cancellationToken = default
);
}
\ No newline at end of file
diff --git a/src/GroundsForSupport.Server/Payments/Stripe/StripeService.cs b/src/GroundsForSupport.Server/Payments/Stripe/StripeService.cs
index 5fb57d4..59498a9 100644
--- a/src/GroundsForSupport.Server/Payments/Stripe/StripeService.cs
+++ b/src/GroundsForSupport.Server/Payments/Stripe/StripeService.cs
@@ -1,5 +1,3 @@
-using GroundsForSupport.Server.Data;
-
using Microsoft.Extensions.Options;
using Stripe;
@@ -15,7 +13,13 @@ internal sealed class StripeService(
private readonly StripeClient _client = new(options.Value.ApiKey, httpClient: new SystemNetHttpClient(httpClient));
private readonly ILogger _logger = logger;
- public async Task<(bool IsSuccess, Intent Intent)> CreatePaymentIntentAsync(string name, decimal amount, string? message, string? email)
+ public async Task<(bool IsSuccess, Intent Intent)> CreatePaymentIntentAsync(
+ string name,
+ decimal amount,
+ string? message,
+ string? email,
+ CancellationToken cancellationToken = default
+ )
{
try
{
@@ -40,7 +44,7 @@ internal sealed class StripeService(
createOptions.ReceiptEmail = email;
}
- var intent = await _client.V1.PaymentIntents.CreateAsync(createOptions);
+ var intent = await _client.V1.PaymentIntents.CreateAsync(createOptions, cancellationToken: cancellationToken);
return (true, new Intent(intent.ClientSecret));
}
diff --git a/tests/GroundsForSupport.Server.Tests/GroundsForSupport.API.Tests.csproj b/tests/GroundsForSupport.Server.Tests/GroundsForSupport.Server.Tests.csproj
similarity index 95%
rename from tests/GroundsForSupport.Server.Tests/GroundsForSupport.API.Tests.csproj
rename to tests/GroundsForSupport.Server.Tests/GroundsForSupport.Server.Tests.csproj
index 31a8799..846c685 100644
--- a/tests/GroundsForSupport.Server.Tests/GroundsForSupport.API.Tests.csproj
+++ b/tests/GroundsForSupport.Server.Tests/GroundsForSupport.Server.Tests.csproj
@@ -4,7 +4,7 @@
enable
enable
Exe
- GroundsForSupport.API.Tests
+ GroundsForSupport.Server.Tests
net10.0
@@ -29,6 +29,7 @@
+
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/tests/GroundsForSupport.Server.Tests/Integration/Infra/TestApi.cs b/tests/GroundsForSupport.Server.Tests/Integration/Infra/TestApi.cs
index 5040b23..34890c8 100644
--- a/tests/GroundsForSupport.Server.Tests/Integration/Infra/TestApi.cs
+++ b/tests/GroundsForSupport.Server.Tests/Integration/Infra/TestApi.cs
@@ -1,7 +1,40 @@
+using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
+using GroundsForSupport.Server.Data;
+using GroundsForSupport.Server.Payments.Stripe;
-namespace GroundsForSupport.API.Tests.Integration.Infra;
+using System.Text.Json;
+using Microsoft.Extensions.Configuration;
+using System.Text;
+
+namespace GroundsForSupport.Server.Tests.Integration.Infra;
public sealed class TestApi : WebApplicationFactory
{
+ protected override void ConfigureWebHost(IWebHostBuilder builder)
+ {
+ var contextOptions = new ContextOptions()
+ {
+ DatabaseFilePath = "GroundsForSupport.Test.db",
+ };
+
+ var stripeOptions = new StripeOptions()
+ {
+ ApiKey = "sk_test_12345",
+ };
+
+ var contextOptionsJson = JsonSerializer.Serialize(contextOptions);
+ var stripeOptionsJson = JsonSerializer.Serialize(stripeOptions);
+
+ var configJson = $@"{{
+ ""{nameof(ContextOptions)}"": {contextOptionsJson},
+ ""{nameof(StripeOptions)}"": {stripeOptionsJson}
+ }}";
+
+ var config = new ConfigurationBuilder()
+ .AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(configJson)))
+ .Build();
+
+ builder.UseConfiguration(config);
+ }
}
\ No newline at end of file
diff --git a/tests/GroundsForSupport.Server.Tests/Integration/PaymentTests.cs b/tests/GroundsForSupport.Server.Tests/Integration/PaymentTests.cs
index 9889f4c..dbfbe2a 100644
--- a/tests/GroundsForSupport.Server.Tests/Integration/PaymentTests.cs
+++ b/tests/GroundsForSupport.Server.Tests/Integration/PaymentTests.cs
@@ -1,7 +1,14 @@
using System.Net;
using System.Net.Http.Json;
-using GroundsForSupport.API.Tests.Integration.Infra;
+using GroundsForSupport.Server.Payments;
+using GroundsForSupport.Server.Payments.Stripe;
+using GroundsForSupport.Server.Tests.Integration.Infra;
+
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.DependencyInjection;
+
+using Moq;
[assembly: CaptureConsole]
@@ -50,7 +57,26 @@ public sealed class PaymentTests(TestApi api) : IClassFixture
[Fact]
public async Task CreatePaymentIntent_WhenGivenValidRequest_ItShouldReturnCreated()
{
- var client = _api.CreateClient();
+ var mockStripeService = new Mock();
+
+ mockStripeService
+ .Setup(s => s.CreatePaymentIntentAsync(
+ It.IsAny(),
+ It.IsAny(),
+ It.IsAny(),
+ It.IsAny(),
+ It.IsAny()
+ )
+ )
+ .ReturnsAsync((true, new Intent("pi_12345_secret_67890")));
+
+ var api = _api.WithWebHostBuilder(
+ b => b.ConfigureTestServices(
+ s => s.AddSingleton(mockStripeService.Object)
+ )
+ );
+
+ var client = api.CreateClient();
var request = new
{