Skip to content

Commit 7a4141e

Browse files
tests: this commit introduces integration tests for the payments endpoint
1 parent 154e954 commit 7a4141e

1 file changed

Lines changed: 163 additions & 0 deletions

File tree

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
namespace Comanda.Payments.TestSuite.Integration;
2+
3+
public sealed class PaymentEndpointTests(IntegrationEnvironmentFixture factory) :
4+
IClassFixture<IntegrationEnvironmentFixture>,
5+
IAsyncLifetime
6+
{
7+
private readonly Fixture _fixture = new();
8+
private readonly JsonSerializerOptions _serializerOptions = new()
9+
{
10+
PropertyNameCaseInsensitive = true,
11+
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
12+
};
13+
14+
[Fact(DisplayName = "[e2e] - when GET /api/v1/payments is called and there are payments, 200 OK is returned with the payments")]
15+
public async Task GetOwners_ReturnsOwners_WhenOwnersExist()
16+
{
17+
/* arrange: resolve http client and collection instances from integration environment */
18+
var httpClient = factory.HttpClient;
19+
var collection = factory.Services.GetRequiredService<IPaymentCollection>();
20+
21+
var payments = _fixture.Build<Payment>()
22+
.With(payment => payment.IsDeleted, false)
23+
.CreateMany(3)
24+
.ToList();
25+
26+
await collection.InsertManyAsync(payments, cancellation: TestContext.Current.CancellationToken);
27+
28+
/* act: send GET request to the owners endpoint */
29+
var response = await httpClient.GetAsync("/api/v1/payments", TestContext.Current.CancellationToken);
30+
var content = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
31+
32+
/* assert: verify http response status and content */
33+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
34+
Assert.False(string.IsNullOrWhiteSpace(content));
35+
36+
/* assert: deserialize response and validate data structure */
37+
var result = JsonSerializer.Deserialize<PaginationScheme<PaymentScheme>>(content, _serializerOptions);
38+
39+
/* assert: ensure response contains owners */
40+
Assert.NotNull(result);
41+
Assert.NotEmpty(result.Items);
42+
43+
/* assert: check if the number of returned payments matches the inserted ones */
44+
Assert.Equal(payments.Count, result.Items.Count);
45+
}
46+
47+
[Fact(DisplayName = "[e2e] - when POST /api/v1/payments/offline is called with valid data, 201 Created is returned and payment is persisted")]
48+
public async Task CreateOfflinePaymentCharge_ReturnsCreated_AndPersistsPayment()
49+
{
50+
/* arrange: resolve http client and collection instances from integration environment */
51+
var httpClient = factory.HttpClient;
52+
var collection = factory.Services.GetRequiredService<IPaymentCollection>();
53+
54+
/* arrange: create valid offline payment charge request */
55+
var request = _fixture.Build<OfflinePaymentChargeScheme>()
56+
.With(request => request.Reference, Identifier.Generate<Payment>())
57+
.With(request => request.Method, Method.Cash)
58+
.With(request => request.Amount, 100m)
59+
.Create();
60+
61+
/* act: send POST request to create offline payment charge */
62+
var response = await httpClient.PostAsJsonAsync("/api/v1/payments/offline", request, TestContext.Current.CancellationToken);
63+
var content = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
64+
65+
/* assert: verify http response status and content */
66+
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
67+
Assert.False(string.IsNullOrWhiteSpace(content));
68+
69+
/* assert: deserialize response and validate data structure */
70+
var result = JsonSerializer.Deserialize<PaymentScheme>(content, _serializerOptions);
71+
72+
/* assert: ensure response contains payment data */
73+
Assert.NotNull(result);
74+
Assert.False(string.IsNullOrWhiteSpace(result.Identifier));
75+
76+
Assert.Equal(request.Reference, result.Reference);
77+
Assert.Equal(request.Amount, result.Amount);
78+
79+
Assert.Equal(request.Method, result.Method);
80+
Assert.Equal(Status.Paid, result.Status);
81+
82+
/* assert: verify payment was persisted in the database */
83+
var filters = PaymentFilters.WithSpecifications()
84+
.WithIdentifier(result.Identifier)
85+
.Build();
86+
87+
var persistedPayments = await collection.FilterPaymentsAsync(filters, TestContext.Current.CancellationToken);
88+
var persistedPayment = persistedPayments.FirstOrDefault();
89+
90+
Assert.NotNull(persistedPayment);
91+
92+
Assert.Equal(result.Identifier, persistedPayment.Id);
93+
Assert.Equal(request.Reference, persistedPayment.Metadata.Reference);
94+
95+
Assert.Equal(Status.Paid, persistedPayment.Status);
96+
Assert.Equal(request.Amount, persistedPayment.Amount);
97+
Assert.Equal(request.Method, persistedPayment.Method);
98+
}
99+
100+
[Fact(DisplayName = "[e2e] - when POST /api/v1/payments/online is called with valid data, 200 OK is returned and payment is persisted")]
101+
public async Task CreateCheckoutSession_ReturnsSuccess_AndPersistsPayment()
102+
{
103+
/* arrange: resolve http client and collection instances from integration environment */
104+
var httpClient = factory.HttpClient;
105+
var collection = factory.Services.GetRequiredService<IPaymentCollection>();
106+
107+
/* arrange: create valid checkout session request */
108+
var request = _fixture.Build<CheckoutSessionCreationScheme>()
109+
.With(request => request.Reference, Identifier.Generate<Payment>())
110+
.With(request => request.Amount, 100m)
111+
.With(request => request.Payer, new User(Identifier.Generate<User>(), $"john.doe@email.com"))
112+
.Create();
113+
114+
var payload = JsonSerializer.Serialize(request, _serializerOptions);
115+
116+
var content = new StringContent(payload, System.Text.Encoding.UTF8, MediaTypeNames.Application.Json);
117+
var httpRequest = new HttpRequestMessage(HttpMethod.Post, "/api/v1/payments/online")
118+
{
119+
Content = content
120+
};
121+
122+
httpRequest.Headers.Add(WebApi.Constants.Headers.Credential, "mocked.credential");
123+
124+
/* act: send POST request to create checkout session */
125+
var response = await httpClient.SendAsync(httpRequest, TestContext.Current.CancellationToken);
126+
var responseContent = await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken);
127+
128+
/* assert: verify http response status and content */
129+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
130+
Assert.False(string.IsNullOrWhiteSpace(responseContent));
131+
132+
/* assert: deserialize response and validate session structure */
133+
var result = JsonSerializer.Deserialize<CheckoutSession>(responseContent, _serializerOptions);
134+
135+
/* assert: ensure response contains checkout session data */
136+
Assert.NotNull(result);
137+
138+
Assert.False(string.IsNullOrWhiteSpace(result.Code));
139+
Assert.False(string.IsNullOrWhiteSpace(result.QrCode));
140+
141+
/* assert: verify payment was persisted in the database */
142+
var filters = PaymentFilters.WithSpecifications()
143+
.WithReferenceId(request.Reference)
144+
.Build();
145+
146+
var persistedPayments = await collection.FilterPaymentsAsync(filters, TestContext.Current.CancellationToken);
147+
var persistedPayment = persistedPayments.FirstOrDefault();
148+
149+
Assert.NotNull(persistedPayment);
150+
151+
Assert.Equal(request.Reference, persistedPayment.Metadata.Reference);
152+
Assert.Equal(request.Amount, persistedPayment.Amount);
153+
154+
Assert.Equal(Method.Pix, persistedPayment.Method);
155+
Assert.Equal(Status.Pending, persistedPayment.Status);
156+
157+
Assert.Equal(request.Payer.Identifier, persistedPayment.Payer.Identifier);
158+
Assert.Equal(request.Payer.Username, persistedPayment.Payer.Username);
159+
}
160+
161+
public ValueTask InitializeAsync() => factory.InitializeAsync();
162+
public ValueTask DisposeAsync() => factory.DisposeAsync();
163+
}

0 commit comments

Comments
 (0)