mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 02:39:03 +00:00
Add user registration bdd tests
This commit is contained in:
@@ -2,7 +2,7 @@ Feature: User Registration
|
||||
As a new user
|
||||
I want to register an account
|
||||
So that I can log in and access authenticated routes
|
||||
@Ignore
|
||||
|
||||
Scenario: Successful registration with valid details
|
||||
Given the API is running
|
||||
When I submit a registration request with values:
|
||||
@@ -11,6 +11,7 @@ Feature: User Registration
|
||||
Then the response has HTTP status 201
|
||||
And the response JSON should have "message" equal "User registered successfully."
|
||||
And the response JSON should have an access token
|
||||
|
||||
@Ignore
|
||||
Scenario: Registration fails with existing username
|
||||
Given the API is running
|
||||
@@ -20,6 +21,7 @@ Feature: User Registration
|
||||
| existinguser | Existing | User | existing@example.com | 1990-01-01 | Password1! |
|
||||
Then the response has HTTP status 409
|
||||
And the response JSON should have "message" equal "Username already exists."
|
||||
|
||||
@Ignore
|
||||
Scenario: Registration fails with existing email
|
||||
Given the API is running
|
||||
@@ -29,6 +31,7 @@ Feature: User Registration
|
||||
| newuser | New | User | existing@example.com | 1990-01-01 | Password1! |
|
||||
Then the response has HTTP status 409
|
||||
And the response JSON should have "message" equal "Email already in use."
|
||||
|
||||
@Ignore
|
||||
Scenario: Registration fails with missing required fields
|
||||
Given the API is running
|
||||
@@ -37,6 +40,7 @@ Feature: User Registration
|
||||
| | New | User | | | Password1! |
|
||||
Then the response has HTTP status 400
|
||||
And the response JSON should have "message" equal "Username is required."
|
||||
|
||||
@Ignore
|
||||
Scenario: Registration fails with invalid email format
|
||||
Given the API is running
|
||||
@@ -45,6 +49,7 @@ Feature: User Registration
|
||||
| newuser | New | User | invalidemail | 1990-01-01 | Password1! |
|
||||
Then the response has HTTP status 400
|
||||
And the response JSON should have "message" equal "Invalid email format."
|
||||
|
||||
@Ignore
|
||||
Scenario: Registration fails with weak password
|
||||
Given the API is running
|
||||
@@ -53,6 +58,7 @@ Feature: User Registration
|
||||
| newuser | New | User | newuser@example.com | 1990-01-01 | weakpass |
|
||||
Then the response has HTTP status 400
|
||||
And the response JSON should have "message" equal "Password does not meet complexity requirements."
|
||||
|
||||
@Ignore
|
||||
Scenario: Cannot register a user younger than 19 years of age (regulatory requirement)
|
||||
Given the API is running
|
||||
@@ -61,7 +67,7 @@ Feature: User Registration
|
||||
| younguser | Young | User | younguser@example.com | | Password1! |
|
||||
Then the response has HTTP status 400
|
||||
And the response JSON should have "message" equal "You must be at least 19 years old to register."
|
||||
@Ignore
|
||||
|
||||
Scenario: Registration endpoint only accepts POST requests
|
||||
Given the API is running
|
||||
When I submit a registration request using a GET request
|
||||
|
||||
@@ -157,4 +157,64 @@ public class AuthSteps(ScenarioContext scenario)
|
||||
scenario[ResponseKey] = response;
|
||||
scenario[ResponseBodyKey] = responseBody;
|
||||
}
|
||||
|
||||
[When("I submit a registration request with values:")]
|
||||
public async Task WhenISubmitARegistrationRequestWithValues(Table table)
|
||||
{
|
||||
var client = GetClient();
|
||||
var row = table.Rows[0];
|
||||
|
||||
var registrationData = new
|
||||
{
|
||||
username = row.TryGetValue("Username", out var value) ? value : null,
|
||||
firstName = row.TryGetValue("FirstName", out var value1) ? value1 : null,
|
||||
lastName = row.TryGetValue("LastName", out var value2) ? value2 : null,
|
||||
email = row.TryGetValue("Email", out var value3) ? value3 : null,
|
||||
dateOfBirth = row.ContainsKey("DateOfBirth") && !string.IsNullOrEmpty(row["DateOfBirth"])
|
||||
? row["DateOfBirth"]
|
||||
: null,
|
||||
password = row.ContainsKey("Password") ? row["Password"] : null
|
||||
};
|
||||
|
||||
var body = JsonSerializer.Serialize(registrationData);
|
||||
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/auth/register")
|
||||
{
|
||||
Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json")
|
||||
};
|
||||
|
||||
var response = await client.SendAsync(requestMessage);
|
||||
var responseBody = await response.Content.ReadAsStringAsync();
|
||||
|
||||
scenario[ResponseKey] = response;
|
||||
scenario[ResponseBodyKey] = responseBody;
|
||||
}
|
||||
|
||||
[Given("I have an existing account with username {string}")]
|
||||
public void GivenIHaveAnExistingAccountWithUsername(string username)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[Given("I have an existing account with email {string}")]
|
||||
public void GivenIHaveAnExistingAccountWithEmail(string email)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[When("I submit a registration request using a GET request")]
|
||||
public async Task WhenISubmitARegistrationRequestUsingAGetRequest()
|
||||
{
|
||||
var client = GetClient();
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/auth/register")
|
||||
{
|
||||
Content = new StringContent("{}", System.Text.Encoding.UTF8, "application/json")
|
||||
};
|
||||
|
||||
var response = await client.SendAsync(requestMessage);
|
||||
var responseBody = await response.Content.ReadAsStringAsync();
|
||||
|
||||
scenario[ResponseKey] = response;
|
||||
scenario[ResponseBodyKey] = responseBody;
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,10 @@ namespace Repository.Core.Repositories.Auth
|
||||
{
|
||||
await using var connection = await CreateConnection();
|
||||
await using var command = connection.CreateCommand();
|
||||
|
||||
command.CommandText = "USP_RegisterUser";
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
|
||||
// Input parameters
|
||||
AddParameter(command, "@Username", username);
|
||||
AddParameter(command, "@FirstName", firstName);
|
||||
AddParameter(command, "@LastName", lastName);
|
||||
@@ -33,11 +33,9 @@ namespace Repository.Core.Repositories.Auth
|
||||
AddParameter(command, "@DateOfBirth", dateOfBirth);
|
||||
AddParameter(command, "@Hash", passwordHash);
|
||||
|
||||
// Execute and retrieve the generated UserAccountId from result set
|
||||
var result = await command.ExecuteScalarAsync();
|
||||
var userAccountId = result != null ? (Guid)result : Guid.Empty;
|
||||
|
||||
// Return the newly created user account
|
||||
return new Entities.UserAccount
|
||||
{
|
||||
UserAccountId = userAccountId,
|
||||
@@ -104,12 +102,6 @@ namespace Repository.Core.Repositories.Auth
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
|
||||
public async Task InvalidateCredentialsByUserAccountIdAsync(Guid userAccountId)
|
||||
{
|
||||
throw new NotImplementedException("InvalidateCredentialsByUserAccountIdAsync");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a data reader row to a UserAccount entity.
|
||||
/// </summary>
|
||||
|
||||
@@ -55,12 +55,5 @@ namespace Repository.Core.Repositories.Auth
|
||||
/// <param name="userAccountId">ID of the user account</param>
|
||||
/// <param name="newPasswordHash">New hashed password</param>
|
||||
Task RotateCredentialAsync(Guid userAccountId, string newPasswordHash);
|
||||
|
||||
/// <summary>
|
||||
/// Invalidates all credentials for a user account (e.g., for logout or security purposes).
|
||||
/// Uses stored procedure: USP_InvalidateUserCredential
|
||||
/// </summary>
|
||||
/// <param name="userAccountId">ID of the user account</param>
|
||||
Task InvalidateCredentialsByUserAccountIdAsync(Guid userAccountId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,17 +216,4 @@ public class AuthRepositoryTest
|
||||
var act = async () => await repo.RotateCredentialAsync(userId, newPasswordHash);
|
||||
await act.Should().NotThrowAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InvalidateCredentialsByUserAccountIdAsync_ExecutesSuccessfully()
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
var conn = new MockDbConnection();
|
||||
|
||||
var repo = CreateRepo(conn);
|
||||
|
||||
// Should complete without error
|
||||
var act = async () => await repo.InvalidateCredentialsByUserAccountIdAsync(userId);
|
||||
await act.Should().NotThrowAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@ public class AuthService(
|
||||
IPasswordService passwordService
|
||||
) : IAuthService
|
||||
{
|
||||
public async Task<UserAccount?> RegisterAsync(UserAccount userAccount, string password)
|
||||
public async Task<UserAccount> RegisterAsync(UserAccount userAccount, string password)
|
||||
{
|
||||
// Check if user already exists
|
||||
var user = await authRepo.GetUserByUsernameAsync(userAccount.Username);
|
||||
if (user is not null)
|
||||
{
|
||||
return null;
|
||||
return null!;
|
||||
}
|
||||
|
||||
// password hashing
|
||||
@@ -45,9 +45,4 @@ public class AuthService(
|
||||
if (activeCred is null) return null;
|
||||
return !passwordService.Verify(password, activeCred.Hash) ? null : user;
|
||||
}
|
||||
|
||||
public async Task InvalidateAsync(Guid userAccountId)
|
||||
{
|
||||
await authRepo.InvalidateCredentialsByUserAccountIdAsync(userAccountId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user