mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-07-16 09:37:23 +00:00
Format ./web/backend/API/API.Specs
This commit is contained in:
@@ -8,40 +8,37 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||||
<PackageReference Include="xunit" Version="2.9.2"/>
|
<PackageReference Include="xunit" Version="2.9.2" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2"/>
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
|
||||||
<PackageReference Include="FluentAssertions" Version="6.9.0"/>
|
<PackageReference Include="FluentAssertions" Version="6.9.0" />
|
||||||
<PackageReference Include="dbup" Version="5.0.41"/>
|
<PackageReference Include="dbup" Version="5.0.41" />
|
||||||
|
|
||||||
<!-- Reqnroll core, xUnit adapter and code-behind generator -->
|
<!-- Reqnroll core, xUnit adapter and code-behind generator -->
|
||||||
<PackageReference Include="Reqnroll" Version="3.3.3"/>
|
<PackageReference Include="Reqnroll" Version="3.3.3" />
|
||||||
<PackageReference Include="Reqnroll.xUnit" Version="3.3.3"/>
|
<PackageReference Include="Reqnroll.xUnit" Version="3.3.3" />
|
||||||
<PackageReference
|
<PackageReference
|
||||||
Include="Reqnroll.Tools.MsBuild.Generation"
|
Include="Reqnroll.Tools.MsBuild.Generation"
|
||||||
Version="3.3.3"
|
Version="3.3.3"
|
||||||
PrivateAssets="all"
|
PrivateAssets="all"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- ASP.NET Core integration testing -->
|
<!-- ASP.NET Core integration testing -->
|
||||||
<PackageReference
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.1" />
|
||||||
Include="Microsoft.AspNetCore.Mvc.Testing"
|
|
||||||
Version="9.0.1"
|
|
||||||
/>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- Ensure feature files are included in the project -->
|
<!-- Ensure feature files are included in the project -->
|
||||||
<None Include="Features\**\*.feature"/>
|
<None Include="Features\**\*.feature" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Using Include="Xunit"/>
|
<Using Include="Xunit" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\API.Core\API.Core.csproj"/>
|
<ProjectReference Include="..\API.Core\API.Core.csproj" />
|
||||||
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Email\Infrastructure.Email.csproj"/>
|
<ProjectReference Include="..\..\Infrastructure\Infrastructure.Email\Infrastructure.Email.csproj" />
|
||||||
<ProjectReference Include="..\..\Features\Features.Emails\Features.Emails.csproj"/>
|
<ProjectReference Include="..\..\Features\Features.Emails\Features.Emails.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -8,11 +8,7 @@ public class MockEmailDispatcher : IEmailDispatcher
|
|||||||
|
|
||||||
public List<ResendConfirmationEmail> SentResendConfirmationEmails { get; } = new();
|
public List<ResendConfirmationEmail> SentResendConfirmationEmails { get; } = new();
|
||||||
|
|
||||||
public Task SendRegistrationEmailAsync(
|
public Task SendRegistrationEmailAsync(string firstName, string email, string confirmationToken)
|
||||||
string firstName,
|
|
||||||
string email,
|
|
||||||
string confirmationToken
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SentRegistrationEmails.Add(
|
SentRegistrationEmails.Add(
|
||||||
new RegistrationEmail
|
new RegistrationEmail
|
||||||
@@ -20,7 +16,7 @@ public class MockEmailDispatcher : IEmailDispatcher
|
|||||||
FirstName = firstName,
|
FirstName = firstName,
|
||||||
Email = email,
|
Email = email,
|
||||||
ConfirmationToken = confirmationToken,
|
ConfirmationToken = confirmationToken,
|
||||||
SentAt = DateTime.UtcNow
|
SentAt = DateTime.UtcNow,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -39,7 +35,7 @@ public class MockEmailDispatcher : IEmailDispatcher
|
|||||||
FirstName = firstName,
|
FirstName = firstName,
|
||||||
Email = email,
|
Email = email,
|
||||||
ConfirmationToken = confirmationToken,
|
ConfirmationToken = confirmationToken,
|
||||||
SentAt = DateTime.UtcNow
|
SentAt = DateTime.UtcNow,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -67,4 +63,4 @@ public class MockEmailDispatcher : IEmailDispatcher
|
|||||||
public string ConfirmationToken { get; init; } = string.Empty;
|
public string ConfirmationToken { get; init; } = string.Empty;
|
||||||
public DateTime SentAt { get; init; }
|
public DateTime SentAt { get; init; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,7 @@ public class MockEmailProvider : IEmailProvider
|
|||||||
{
|
{
|
||||||
public List<SentEmail> SentEmails { get; } = new();
|
public List<SentEmail> SentEmails { get; } = new();
|
||||||
|
|
||||||
public Task SendAsync(
|
public Task SendAsync(string to, string subject, string body, bool isHtml = true)
|
||||||
string to,
|
|
||||||
string subject,
|
|
||||||
string body,
|
|
||||||
bool isHtml = true
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SentEmails.Add(
|
SentEmails.Add(
|
||||||
new SentEmail
|
new SentEmail
|
||||||
@@ -24,19 +19,14 @@ public class MockEmailProvider : IEmailProvider
|
|||||||
Subject = subject,
|
Subject = subject,
|
||||||
Body = body,
|
Body = body,
|
||||||
IsHtml = isHtml,
|
IsHtml = isHtml,
|
||||||
SentAt = DateTime.UtcNow
|
SentAt = DateTime.UtcNow,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SendAsync(
|
public Task SendAsync(IEnumerable<string> to, string subject, string body, bool isHtml = true)
|
||||||
IEnumerable<string> to,
|
|
||||||
string subject,
|
|
||||||
string body,
|
|
||||||
bool isHtml = true
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SentEmails.Add(
|
SentEmails.Add(
|
||||||
new SentEmail
|
new SentEmail
|
||||||
@@ -45,7 +35,7 @@ public class MockEmailProvider : IEmailProvider
|
|||||||
Subject = subject,
|
Subject = subject,
|
||||||
Body = body,
|
Body = body,
|
||||||
IsHtml = isHtml,
|
IsHtml = isHtml,
|
||||||
SentAt = DateTime.UtcNow
|
SentAt = DateTime.UtcNow,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -65,4 +55,4 @@ public class MockEmailProvider : IEmailProvider
|
|||||||
public bool IsHtml { get; init; }
|
public bool IsHtml { get; init; }
|
||||||
public DateTime SentAt { get; init; }
|
public DateTime SentAt { get; init; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ public class ApiGeneralSteps(ScenarioContext scenario)
|
|||||||
|
|
||||||
private HttpClient GetClient()
|
private HttpClient GetClient()
|
||||||
{
|
{
|
||||||
if (scenario.TryGetValue<HttpClient>(ClientKey, out HttpClient? client)) return client;
|
if (scenario.TryGetValue<HttpClient>(ClientKey, out HttpClient? client))
|
||||||
|
return client;
|
||||||
|
|
||||||
TestApiFactory? factory = scenario.TryGetValue<TestApiFactory>(
|
TestApiFactory? factory = scenario.TryGetValue<TestApiFactory>(
|
||||||
FactoryKey,
|
FactoryKey,
|
||||||
@@ -47,11 +48,7 @@ public class ApiGeneralSteps(ScenarioContext scenario)
|
|||||||
|
|
||||||
HttpRequestMessage requestMessage = new(new HttpMethod(method), url)
|
HttpRequestMessage requestMessage = new(new HttpMethod(method), url)
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(jsonBody, Encoding.UTF8, "application/json"),
|
||||||
jsonBody,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -62,16 +59,10 @@ public class ApiGeneralSteps(ScenarioContext scenario)
|
|||||||
}
|
}
|
||||||
|
|
||||||
[When("I send an HTTP request {string} to {string}")]
|
[When("I send an HTTP request {string} to {string}")]
|
||||||
public async Task WhenISendAnHttpRequestStringToString(
|
public async Task WhenISendAnHttpRequestStringToString(string method, string url)
|
||||||
string method,
|
|
||||||
string url
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(new HttpMethod(method), url);
|
||||||
new HttpMethod(method),
|
|
||||||
url
|
|
||||||
);
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
string responseBody = await response.Content.ReadAsStringAsync();
|
string responseBody = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
@@ -100,19 +91,13 @@ public class ApiGeneralSteps(ScenarioContext scenario)
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Then("the response JSON should have {string} equal {string}")]
|
[Then("the response JSON should have {string} equal {string}")]
|
||||||
public void ThenTheResponseJsonShouldHaveStringEqualString(
|
public void ThenTheResponseJsonShouldHaveStringEqualString(string field, string expected)
|
||||||
string field,
|
|
||||||
string expected
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
scenario
|
scenario
|
||||||
.TryGetValue<HttpResponseMessage>(ResponseKey, out HttpResponseMessage? response)
|
.TryGetValue<HttpResponseMessage>(ResponseKey, out HttpResponseMessage? response)
|
||||||
.Should()
|
.Should()
|
||||||
.BeTrue();
|
.BeTrue();
|
||||||
scenario
|
scenario.TryGetValue<string>(ResponseBodyKey, out string? responseBody).Should().BeTrue();
|
||||||
.TryGetValue<string>(ResponseBodyKey, out string? responseBody)
|
|
||||||
.Should()
|
|
||||||
.BeTrue();
|
|
||||||
|
|
||||||
using JsonDocument doc = JsonDocument.Parse(responseBody!);
|
using JsonDocument doc = JsonDocument.Parse(responseBody!);
|
||||||
JsonElement root = doc.RootElement;
|
JsonElement root = doc.RootElement;
|
||||||
@@ -125,25 +110,16 @@ public class ApiGeneralSteps(ScenarioContext scenario)
|
|||||||
"Expected field '{0}' to be present either at the root or inside 'payload'",
|
"Expected field '{0}' to be present either at the root or inside 'payload'",
|
||||||
field
|
field
|
||||||
);
|
);
|
||||||
payloadElem
|
payloadElem.ValueKind.Should().Be(JsonValueKind.Object, "payload must be an object");
|
||||||
.ValueKind.Should()
|
|
||||||
.Be(JsonValueKind.Object, "payload must be an object");
|
|
||||||
payloadElem
|
payloadElem
|
||||||
.TryGetProperty(field, out value)
|
.TryGetProperty(field, out value)
|
||||||
.Should()
|
.Should()
|
||||||
.BeTrue(
|
.BeTrue("Expected field '{0}' to be present inside 'payload'", field);
|
||||||
"Expected field '{0}' to be present inside 'payload'",
|
|
||||||
field
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value
|
value
|
||||||
.ValueKind.Should()
|
.ValueKind.Should()
|
||||||
.Be(
|
.Be(JsonValueKind.String, "Expected field '{0}' to be a string", field);
|
||||||
JsonValueKind.String,
|
|
||||||
"Expected field '{0}' to be a string",
|
|
||||||
field
|
|
||||||
);
|
|
||||||
value.GetString().Should().Be(expected);
|
value.GetString().Should().Be(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,10 +133,7 @@ public class ApiGeneralSteps(ScenarioContext scenario)
|
|||||||
.TryGetValue<HttpResponseMessage>(ResponseKey, out HttpResponseMessage? response)
|
.TryGetValue<HttpResponseMessage>(ResponseKey, out HttpResponseMessage? response)
|
||||||
.Should()
|
.Should()
|
||||||
.BeTrue();
|
.BeTrue();
|
||||||
scenario
|
scenario.TryGetValue<string>(ResponseBodyKey, out string? responseBody).Should().BeTrue();
|
||||||
.TryGetValue<string>(ResponseBodyKey, out string? responseBody)
|
|
||||||
.Should()
|
|
||||||
.BeTrue();
|
|
||||||
|
|
||||||
using JsonDocument doc = JsonDocument.Parse(responseBody!);
|
using JsonDocument doc = JsonDocument.Parse(responseBody!);
|
||||||
JsonElement root = doc.RootElement;
|
JsonElement root = doc.RootElement;
|
||||||
@@ -173,25 +146,16 @@ public class ApiGeneralSteps(ScenarioContext scenario)
|
|||||||
"Expected field '{0}' to be present either at the root or inside 'payload'",
|
"Expected field '{0}' to be present either at the root or inside 'payload'",
|
||||||
field
|
field
|
||||||
);
|
);
|
||||||
payloadElem
|
payloadElem.ValueKind.Should().Be(JsonValueKind.Object, "payload must be an object");
|
||||||
.ValueKind.Should()
|
|
||||||
.Be(JsonValueKind.Object, "payload must be an object");
|
|
||||||
payloadElem
|
payloadElem
|
||||||
.TryGetProperty(field, out value)
|
.TryGetProperty(field, out value)
|
||||||
.Should()
|
.Should()
|
||||||
.BeTrue(
|
.BeTrue("Expected field '{0}' to be present inside 'payload'", field);
|
||||||
"Expected field '{0}' to be present inside 'payload'",
|
|
||||||
field
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value
|
value
|
||||||
.ValueKind.Should()
|
.ValueKind.Should()
|
||||||
.Be(
|
.Be(JsonValueKind.String, "Expected field '{0}' to be a string", field);
|
||||||
JsonValueKind.String,
|
|
||||||
"Expected field '{0}' to be a string",
|
|
||||||
field
|
|
||||||
);
|
|
||||||
string? actualValue = value.GetString();
|
string? actualValue = value.GetString();
|
||||||
actualValue
|
actualValue
|
||||||
.Should()
|
.Should()
|
||||||
@@ -203,4 +167,4 @@ public class ApiGeneralSteps(ScenarioContext scenario)
|
|||||||
actualValue
|
actualValue
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
|
|
||||||
private HttpClient GetClient()
|
private HttpClient GetClient()
|
||||||
{
|
{
|
||||||
if (scenario.TryGetValue<HttpClient>(ClientKey, out HttpClient? client)) return client;
|
if (scenario.TryGetValue<HttpClient>(ClientKey, out HttpClient? client))
|
||||||
|
return client;
|
||||||
|
|
||||||
TestApiFactory? factory = scenario.TryGetValue<TestApiFactory>(
|
TestApiFactory? factory = scenario.TryGetValue<TestApiFactory>(
|
||||||
FactoryKey,
|
FactoryKey,
|
||||||
@@ -39,9 +40,7 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
private static string GetRequiredEnvVar(string name)
|
private static string GetRequiredEnvVar(string name)
|
||||||
{
|
{
|
||||||
return Environment.GetEnvironmentVariable(name)
|
return Environment.GetEnvironmentVariable(name)
|
||||||
?? throw new InvalidOperationException(
|
?? throw new InvalidOperationException($"{name} environment variable is not set");
|
||||||
$"{name} environment variable is not set"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GenerateJwtToken(
|
private static string GenerateJwtToken(
|
||||||
@@ -57,21 +56,13 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
|
|
||||||
private static Guid ParseRegisteredUserId(JsonElement root)
|
private static Guid ParseRegisteredUserId(JsonElement root)
|
||||||
{
|
{
|
||||||
return root
|
return root.GetProperty("payload").GetProperty("userAccountId").GetGuid();
|
||||||
.GetProperty("payload")
|
|
||||||
.GetProperty("userAccountId")
|
|
||||||
.GetGuid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ParseRegisteredUsername(JsonElement root)
|
private static string ParseRegisteredUsername(JsonElement root)
|
||||||
{
|
{
|
||||||
return root
|
return root.GetProperty("payload").GetProperty("username").GetString()
|
||||||
.GetProperty("payload")
|
?? throw new InvalidOperationException("username missing from registration payload");
|
||||||
.GetProperty("username")
|
|
||||||
.GetString()
|
|
||||||
?? throw new InvalidOperationException(
|
|
||||||
"username missing from registration payload"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ParseTokenFromPayload(
|
private static string ParseTokenFromPayload(
|
||||||
@@ -85,9 +76,7 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
|| payload.TryGetProperty(pascalCaseName, out tokenElem)
|
|| payload.TryGetProperty(pascalCaseName, out tokenElem)
|
||||||
)
|
)
|
||||||
return tokenElem.GetString()
|
return tokenElem.GetString()
|
||||||
?? throw new InvalidOperationException(
|
?? throw new InvalidOperationException($"{camelCaseName} is null");
|
||||||
$"{camelCaseName} is null"
|
|
||||||
);
|
|
||||||
|
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
$"Could not find token field '{camelCaseName}' in payload"
|
$"Could not find token field '{camelCaseName}' in payload"
|
||||||
@@ -113,22 +102,15 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
(string username, string password) = scenario.TryGetValue<(
|
(string username, string password) = scenario.TryGetValue<(
|
||||||
string username,
|
string username,
|
||||||
string password
|
string password
|
||||||
)>(TestUserKey, out (string username, string password) user)
|
)>(TestUserKey, out (string username, string password) user)
|
||||||
? user
|
? user
|
||||||
: ("test.user", "password");
|
: ("test.user", "password");
|
||||||
|
|
||||||
string body = JsonSerializer.Serialize(new { username, password });
|
string body = JsonSerializer.Serialize(new { username, password });
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/login")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/login"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -144,16 +126,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
string body = JsonSerializer.Serialize(new { password = "test" });
|
string body = JsonSerializer.Serialize(new { password = "test" });
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/login")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/login"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -169,16 +144,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
string body = JsonSerializer.Serialize(new { username = "test" });
|
string body = JsonSerializer.Serialize(new { username = "test" });
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/login")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/login"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -192,16 +160,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitALoginRequestWithBothUsernameAndPasswordMissing()
|
public async Task WhenISubmitALoginRequestWithBothUsernameAndPasswordMissing()
|
||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/login")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/login"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent("{}", Encoding.UTF8, "application/json"),
|
||||||
"{}",
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -218,10 +179,7 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
.TryGetValue<HttpResponseMessage>(ResponseKey, out HttpResponseMessage? response)
|
.TryGetValue<HttpResponseMessage>(ResponseKey, out HttpResponseMessage? response)
|
||||||
.Should()
|
.Should()
|
||||||
.BeTrue();
|
.BeTrue();
|
||||||
scenario
|
scenario.TryGetValue<string>(ResponseBodyKey, out string? responseBody).Should().BeTrue();
|
||||||
.TryGetValue<string>(ResponseBodyKey, out string? responseBody)
|
|
||||||
.Should()
|
|
||||||
.BeTrue();
|
|
||||||
|
|
||||||
JsonDocument doc = JsonDocument.Parse(responseBody!);
|
JsonDocument doc = JsonDocument.Parse(responseBody!);
|
||||||
JsonElement root = doc.RootElement;
|
JsonElement root = doc.RootElement;
|
||||||
@@ -236,11 +194,7 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
payloadElem.TryGetProperty("accessToken", out tokenElem)
|
payloadElem.TryGetProperty("accessToken", out tokenElem)
|
||||||
|| payloadElem.TryGetProperty("AccessToken", out tokenElem);
|
|| payloadElem.TryGetProperty("AccessToken", out tokenElem);
|
||||||
|
|
||||||
hasToken
|
hasToken.Should().BeTrue("Expected an access token either at the root or inside 'payload'");
|
||||||
.Should()
|
|
||||||
.BeTrue(
|
|
||||||
"Expected an access token either at the root or inside 'payload'"
|
|
||||||
);
|
|
||||||
|
|
||||||
string? token = tokenElem.GetString();
|
string? token = tokenElem.GetString();
|
||||||
token.Should().NotBeNullOrEmpty();
|
token.Should().NotBeNullOrEmpty();
|
||||||
@@ -251,16 +205,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
// testing GET
|
// testing GET
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/auth/login")
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/auth/login"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent("{}", Encoding.UTF8, "application/json"),
|
||||||
"{}",
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -282,7 +229,8 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
string email = row["Email"] ?? "";
|
string email = row["Email"] ?? "";
|
||||||
string dateOfBirth = row["DateOfBirth"] ?? "";
|
string dateOfBirth = row["DateOfBirth"] ?? "";
|
||||||
|
|
||||||
if (dateOfBirth == "{underage_date}") dateOfBirth = DateTime.UtcNow.AddYears(-18).ToString("yyyy-MM-dd");
|
if (dateOfBirth == "{underage_date}")
|
||||||
|
dateOfBirth = DateTime.UtcNow.AddYears(-18).ToString("yyyy-MM-dd");
|
||||||
|
|
||||||
// Keep default registration fixture values unique across repeated runs.
|
// Keep default registration fixture values unique across repeated runs.
|
||||||
if (email == "newuser@example.com")
|
if (email == "newuser@example.com")
|
||||||
@@ -290,7 +238,8 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
string suffix = Guid.NewGuid().ToString("N")[..8];
|
string suffix = Guid.NewGuid().ToString("N")[..8];
|
||||||
email = $"newuser-{suffix}@example.com";
|
email = $"newuser-{suffix}@example.com";
|
||||||
|
|
||||||
if (username == "newuser") username = $"newuser-{suffix}";
|
if (username == "newuser")
|
||||||
|
username = $"newuser-{suffix}";
|
||||||
}
|
}
|
||||||
|
|
||||||
string? password = row["Password"];
|
string? password = row["Password"];
|
||||||
@@ -302,21 +251,14 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
lastName,
|
lastName,
|
||||||
email,
|
email,
|
||||||
dateOfBirth,
|
dateOfBirth,
|
||||||
password
|
password,
|
||||||
};
|
};
|
||||||
|
|
||||||
string body = JsonSerializer.Serialize(registrationData);
|
string body = JsonSerializer.Serialize(registrationData);
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/register")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/register"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -330,16 +272,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitARegistrationRequestUsingAGetRequest()
|
public async Task WhenISubmitARegistrationRequestUsingAGetRequest()
|
||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/auth/register")
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/auth/register"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent("{}", Encoding.UTF8, "application/json"),
|
||||||
"{}",
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -361,20 +296,13 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
lastName = "User",
|
lastName = "User",
|
||||||
email = $"newuser-{suffix}@example.com",
|
email = $"newuser-{suffix}@example.com",
|
||||||
dateOfBirth = "1990-01-01",
|
dateOfBirth = "1990-01-01",
|
||||||
password = "Password1!"
|
password = "Password1!",
|
||||||
};
|
};
|
||||||
|
|
||||||
string body = JsonSerializer.Serialize(registrationData);
|
string body = JsonSerializer.Serialize(registrationData);
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/register")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/register"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -395,16 +323,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
var loginData = new { username = "test.user", password = "password" };
|
var loginData = new { username = "test.user", password = "password" };
|
||||||
string body = JsonSerializer.Serialize(loginData);
|
string body = JsonSerializer.Serialize(loginData);
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/login")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/login"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -445,17 +366,10 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
{
|
{
|
||||||
Guid userId = scenario.TryGetValue<Guid>(RegisteredUserIdKey, out Guid id)
|
Guid userId = scenario.TryGetValue<Guid>(RegisteredUserIdKey, out Guid id)
|
||||||
? id
|
? id
|
||||||
: throw new InvalidOperationException(
|
: throw new InvalidOperationException("registered user ID not found in scenario");
|
||||||
"registered user ID not found in scenario"
|
string? username = scenario.TryGetValue<string>(RegisteredUsernameKey, out string? user)
|
||||||
);
|
|
||||||
string? username = scenario.TryGetValue<string>(
|
|
||||||
RegisteredUsernameKey,
|
|
||||||
out string? user
|
|
||||||
)
|
|
||||||
? user
|
? user
|
||||||
: throw new InvalidOperationException(
|
: throw new InvalidOperationException("registered username not found in scenario");
|
||||||
"registered username not found in scenario"
|
|
||||||
);
|
|
||||||
|
|
||||||
string secret = GetRequiredEnvVar("ACCESS_TOKEN_SECRET");
|
string secret = GetRequiredEnvVar("ACCESS_TOKEN_SECRET");
|
||||||
scenario["accessToken"] = GenerateJwtToken(
|
scenario["accessToken"] = GenerateJwtToken(
|
||||||
@@ -471,17 +385,10 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
{
|
{
|
||||||
Guid userId = scenario.TryGetValue<Guid>(RegisteredUserIdKey, out Guid id)
|
Guid userId = scenario.TryGetValue<Guid>(RegisteredUserIdKey, out Guid id)
|
||||||
? id
|
? id
|
||||||
: throw new InvalidOperationException(
|
: throw new InvalidOperationException("registered user ID not found in scenario");
|
||||||
"registered user ID not found in scenario"
|
string? username = scenario.TryGetValue<string>(RegisteredUsernameKey, out string? user)
|
||||||
);
|
|
||||||
string? username = scenario.TryGetValue<string>(
|
|
||||||
RegisteredUsernameKey,
|
|
||||||
out string? user
|
|
||||||
)
|
|
||||||
? user
|
? user
|
||||||
: throw new InvalidOperationException(
|
: throw new InvalidOperationException("registered username not found in scenario");
|
||||||
"registered username not found in scenario"
|
|
||||||
);
|
|
||||||
|
|
||||||
string secret = GetRequiredEnvVar("CONFIRMATION_TOKEN_SECRET");
|
string secret = GetRequiredEnvVar("CONFIRMATION_TOKEN_SECRET");
|
||||||
scenario["confirmationToken"] = GenerateJwtToken(
|
scenario["confirmationToken"] = GenerateJwtToken(
|
||||||
@@ -497,17 +404,10 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
{
|
{
|
||||||
Guid userId = scenario.TryGetValue<Guid>(RegisteredUserIdKey, out Guid id)
|
Guid userId = scenario.TryGetValue<Guid>(RegisteredUserIdKey, out Guid id)
|
||||||
? id
|
? id
|
||||||
: throw new InvalidOperationException(
|
: throw new InvalidOperationException("registered user ID not found in scenario");
|
||||||
"registered user ID not found in scenario"
|
string? username = scenario.TryGetValue<string>(RegisteredUsernameKey, out string? user)
|
||||||
);
|
|
||||||
string? username = scenario.TryGetValue<string>(
|
|
||||||
RegisteredUsernameKey,
|
|
||||||
out string? user
|
|
||||||
)
|
|
||||||
? user
|
? user
|
||||||
: throw new InvalidOperationException(
|
: throw new InvalidOperationException("registered username not found in scenario");
|
||||||
"registered username not found in scenario"
|
|
||||||
);
|
|
||||||
|
|
||||||
string secret = GetRequiredEnvVar("CONFIRMATION_TOKEN_SECRET");
|
string secret = GetRequiredEnvVar("CONFIRMATION_TOKEN_SECRET");
|
||||||
scenario["confirmationToken"] = GenerateJwtToken(
|
scenario["confirmationToken"] = GenerateJwtToken(
|
||||||
@@ -523,20 +423,12 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
{
|
{
|
||||||
Guid userId = scenario.TryGetValue<Guid>(RegisteredUserIdKey, out Guid id)
|
Guid userId = scenario.TryGetValue<Guid>(RegisteredUserIdKey, out Guid id)
|
||||||
? id
|
? id
|
||||||
: throw new InvalidOperationException(
|
: throw new InvalidOperationException("registered user ID not found in scenario");
|
||||||
"registered user ID not found in scenario"
|
string? username = scenario.TryGetValue<string>(RegisteredUsernameKey, out string? user)
|
||||||
);
|
|
||||||
string? username = scenario.TryGetValue<string>(
|
|
||||||
RegisteredUsernameKey,
|
|
||||||
out string? user
|
|
||||||
)
|
|
||||||
? user
|
? user
|
||||||
: throw new InvalidOperationException(
|
: throw new InvalidOperationException("registered username not found in scenario");
|
||||||
"registered username not found in scenario"
|
|
||||||
);
|
|
||||||
|
|
||||||
const string wrongSecret =
|
const string wrongSecret = "wrong-confirmation-secret-that-is-very-long-1234567890";
|
||||||
"wrong-confirmation-secret-that-is-very-long-1234567890";
|
|
||||||
scenario["confirmationToken"] = GenerateJwtToken(
|
scenario["confirmationToken"] = GenerateJwtToken(
|
||||||
userId,
|
userId,
|
||||||
username,
|
username,
|
||||||
@@ -545,9 +437,7 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
[When(
|
[When("I submit a request to a protected endpoint with a valid access token")]
|
||||||
"I submit a request to a protected endpoint with a valid access token"
|
|
||||||
)]
|
|
||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithAValidAccessToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithAValidAccessToken()
|
||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
@@ -555,12 +445,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
? t
|
? t
|
||||||
: "invalid-token";
|
: "invalid-token";
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/protected")
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/protected"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } }
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -569,18 +456,13 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
scenario[ResponseBodyKey] = responseBody;
|
scenario[ResponseBodyKey] = responseBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
[When(
|
[When("I submit a request to a protected endpoint with an invalid access token")]
|
||||||
"I submit a request to a protected endpoint with an invalid access token"
|
|
||||||
)]
|
|
||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithAnInvalidAccessToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithAnInvalidAccessToken()
|
||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/protected")
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/protected"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", "Bearer invalid-token-format" } }
|
Headers = { { "Authorization", "Bearer invalid-token-format" } },
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -673,16 +555,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
: "valid-refresh-token";
|
: "valid-refresh-token";
|
||||||
string body = JsonSerializer.Serialize(new { refreshToken = token });
|
string body = JsonSerializer.Serialize(new { refreshToken = token });
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/refresh")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/refresh"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -695,20 +570,11 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitARefreshTokenRequestWithAnInvalidRefreshToken()
|
public async Task WhenISubmitARefreshTokenRequestWithAnInvalidRefreshToken()
|
||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
string body = JsonSerializer.Serialize(
|
string body = JsonSerializer.Serialize(new { refreshToken = "invalid-refresh-token" });
|
||||||
new { refreshToken = "invalid-refresh-token" }
|
|
||||||
);
|
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/refresh")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/refresh"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -722,20 +588,11 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
// Use an expired token
|
// Use an expired token
|
||||||
string body = JsonSerializer.Serialize(
|
string body = JsonSerializer.Serialize(new { refreshToken = "expired-refresh-token" });
|
||||||
new { refreshToken = "expired-refresh-token" }
|
|
||||||
);
|
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/refresh")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/refresh"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -750,16 +607,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
string body = JsonSerializer.Serialize(new { });
|
string body = JsonSerializer.Serialize(new { });
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Post, "/api/auth/refresh")
|
||||||
HttpMethod.Post,
|
|
||||||
"/api/auth/refresh"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent(body, Encoding.UTF8, "application/json"),
|
||||||
body,
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -772,16 +622,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitARefreshTokenRequestUsingAGETRequest()
|
public async Task WhenISubmitARefreshTokenRequestUsingAGETRequest()
|
||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/auth/refresh")
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/auth/refresh"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Content = new StringContent(
|
Content = new StringContent("{}", Encoding.UTF8, "application/json"),
|
||||||
"{}",
|
|
||||||
Encoding.UTF8,
|
|
||||||
"application/json"
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -795,10 +638,7 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
public async Task WhenISubmitARequestToAProtectedEndpointWithoutAnAccessToken()
|
public async Task WhenISubmitARequestToAProtectedEndpointWithoutAnAccessToken()
|
||||||
{
|
{
|
||||||
HttpClient client = GetClient();
|
HttpClient client = GetClient();
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/protected");
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/protected"
|
|
||||||
);
|
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
string responseBody = await response.Content.ReadAsStringAsync();
|
string responseBody = await response.Content.ReadAsStringAsync();
|
||||||
@@ -830,12 +670,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
? t
|
? t
|
||||||
: "expired-token";
|
: "expired-token";
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/protected")
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/protected"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } }
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -852,12 +689,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
? t
|
? t
|
||||||
: "tampered-token";
|
: "tampered-token";
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/protected")
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/protected"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } }
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -876,12 +710,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
? t
|
? t
|
||||||
: "refresh-token";
|
: "refresh-token";
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/protected")
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/protected"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } }
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -991,12 +822,9 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
? t
|
? t
|
||||||
: "confirmation-token";
|
: "confirmation-token";
|
||||||
|
|
||||||
HttpRequestMessage requestMessage = new(
|
HttpRequestMessage requestMessage = new(HttpMethod.Get, "/api/protected")
|
||||||
HttpMethod.Get,
|
|
||||||
"/api/protected"
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Headers = { { "Authorization", $"Bearer {token}" } }
|
Headers = { { "Authorization", $"Bearer {token}" } },
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
HttpResponseMessage response = await client.SendAsync(requestMessage);
|
||||||
@@ -1049,54 +877,30 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
[Then("the response JSON should have a new access token")]
|
[Then("the response JSON should have a new access token")]
|
||||||
public void ThenTheResponseJsonShouldHaveANewAccessToken()
|
public void ThenTheResponseJsonShouldHaveANewAccessToken()
|
||||||
{
|
{
|
||||||
scenario
|
scenario.TryGetValue<string>(ResponseBodyKey, out string? responseBody).Should().BeTrue();
|
||||||
.TryGetValue<string>(ResponseBodyKey, out string? responseBody)
|
|
||||||
.Should()
|
|
||||||
.BeTrue();
|
|
||||||
|
|
||||||
using JsonDocument doc = JsonDocument.Parse(responseBody!);
|
using JsonDocument doc = JsonDocument.Parse(responseBody!);
|
||||||
JsonElement payload = doc.RootElement.GetProperty("payload");
|
JsonElement payload = doc.RootElement.GetProperty("payload");
|
||||||
string accessToken = ParseTokenFromPayload(
|
string accessToken = ParseTokenFromPayload(payload, "accessToken", "AccessToken");
|
||||||
payload,
|
|
||||||
"accessToken",
|
|
||||||
"AccessToken"
|
|
||||||
);
|
|
||||||
|
|
||||||
accessToken.Should().NotBeNullOrWhiteSpace();
|
accessToken.Should().NotBeNullOrWhiteSpace();
|
||||||
|
|
||||||
if (
|
if (scenario.TryGetValue<string>(PreviousAccessTokenKey, out string? previousAccessToken))
|
||||||
scenario.TryGetValue<string>(
|
|
||||||
PreviousAccessTokenKey,
|
|
||||||
out string? previousAccessToken
|
|
||||||
)
|
|
||||||
)
|
|
||||||
accessToken.Should().NotBe(previousAccessToken);
|
accessToken.Should().NotBe(previousAccessToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Then("the response JSON should have a new refresh token")]
|
[Then("the response JSON should have a new refresh token")]
|
||||||
public void ThenTheResponseJsonShouldHaveANewRefreshToken()
|
public void ThenTheResponseJsonShouldHaveANewRefreshToken()
|
||||||
{
|
{
|
||||||
scenario
|
scenario.TryGetValue<string>(ResponseBodyKey, out string? responseBody).Should().BeTrue();
|
||||||
.TryGetValue<string>(ResponseBodyKey, out string? responseBody)
|
|
||||||
.Should()
|
|
||||||
.BeTrue();
|
|
||||||
|
|
||||||
using JsonDocument doc = JsonDocument.Parse(responseBody!);
|
using JsonDocument doc = JsonDocument.Parse(responseBody!);
|
||||||
JsonElement payload = doc.RootElement.GetProperty("payload");
|
JsonElement payload = doc.RootElement.GetProperty("payload");
|
||||||
string refreshToken = ParseTokenFromPayload(
|
string refreshToken = ParseTokenFromPayload(payload, "refreshToken", "RefreshToken");
|
||||||
payload,
|
|
||||||
"refreshToken",
|
|
||||||
"RefreshToken"
|
|
||||||
);
|
|
||||||
|
|
||||||
refreshToken.Should().NotBeNullOrWhiteSpace();
|
refreshToken.Should().NotBeNullOrWhiteSpace();
|
||||||
|
|
||||||
if (
|
if (scenario.TryGetValue<string>(PreviousRefreshTokenKey, out string? previousRefreshToken))
|
||||||
scenario.TryGetValue<string>(
|
|
||||||
PreviousRefreshTokenKey,
|
|
||||||
out string? previousRefreshToken
|
|
||||||
)
|
|
||||||
)
|
|
||||||
refreshToken.Should().NotBe(previousRefreshToken);
|
refreshToken.Should().NotBe(previousRefreshToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1186,4 +990,4 @@ public class AuthSteps(ScenarioContext scenario)
|
|||||||
scenario[ResponseKey] = response;
|
scenario[ResponseKey] = response;
|
||||||
scenario[ResponseBodyKey] = responseBody;
|
scenario[ResponseBodyKey] = responseBody;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ public class TestApiFactory : WebApplicationFactory<Program>
|
|||||||
d.ServiceType == typeof(IEmailProvider)
|
d.ServiceType == typeof(IEmailProvider)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (emailProviderDescriptor != null) services.Remove(emailProviderDescriptor);
|
if (emailProviderDescriptor != null)
|
||||||
|
services.Remove(emailProviderDescriptor);
|
||||||
|
|
||||||
services.AddScoped<IEmailProvider, MockEmailProvider>();
|
services.AddScoped<IEmailProvider, MockEmailProvider>();
|
||||||
|
|
||||||
@@ -29,9 +30,10 @@ public class TestApiFactory : WebApplicationFactory<Program>
|
|||||||
d.ServiceType == typeof(IEmailDispatcher)
|
d.ServiceType == typeof(IEmailDispatcher)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (emailDispatcherDescriptor != null) services.Remove(emailDispatcherDescriptor);
|
if (emailDispatcherDescriptor != null)
|
||||||
|
services.Remove(emailDispatcherDescriptor);
|
||||||
|
|
||||||
services.AddScoped<IEmailDispatcher, MockEmailDispatcher>();
|
services.AddScoped<IEmailDispatcher, MockEmailDispatcher>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user