Files
dance-lessons-coach/pkg/bdd/steps/steps.go.backup
Gabriel Radureau 5eec64e5e8
All checks were successful
CI/CD Pipeline / Build Docker Cache (push) Successful in 9s
CI/CD Pipeline / CI Pipeline (push) Successful in 4m15s
CI/CD Pipeline / Trigger Docker Push (push) Has been skipped
🧪 test: add JWT secret rotation BDD scenarios and step implementations (#12)
 merge: implement JWT secret rotation with BDD scenario isolation

- Implement JWT secret rotation mechanism (closes #8)
- Add per-scenario state isolation for BDD tests (closes #14)
- Validate password reset workflow via BDD tests (closes #7)
- Fix port conflicts in test validation
- Add state tracer for debugging test execution
- Document BDD isolation strategies in ADR 0025
- Fix PostgreSQL configuration environment variables

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Co-authored-by: Gabriel Radureau <arcodange@gmail.com>
Co-committed-by: Gabriel Radureau <arcodange@gmail.com>
2026-04-11 17:56:45 +02:00

102 lines
7.0 KiB
Plaintext

package steps
import (
"dance-lessons-coach/pkg/bdd/testserver"
"github.com/cucumber/godog"
)
// StepContext holds the test client and implements all step definitions
type StepContext struct {
client *testserver.Client
greetSteps *GreetSteps
healthSteps *HealthSteps
authSteps *AuthSteps
commonSteps *CommonSteps
jwtRetentionSteps *JWTRetentionSteps
}
// NewStepContext creates a new step context
func NewStepContext(client *testserver.Client) *StepContext {
return &StepContext{
client: client,
greetSteps: NewGreetSteps(client),
healthSteps: NewHealthSteps(client),
authSteps: NewAuthSteps(client),
commonSteps: NewCommonSteps(client),
jwtRetentionSteps: NewJWTRetentionSteps(client),
}
}
// InitializeAllSteps registers all step definitions for the BDD tests
func InitializeAllSteps(ctx *godog.ScenarioContext, client *testserver.Client) {
sc := NewStepContext(client)
// Greet steps
ctx.Step(`^I request a greeting for "([^"]*)"$`, sc.greetSteps.iRequestAGreetingFor)
ctx.Step(`^I request the default greeting$`, sc.greetSteps.iRequestTheDefaultGreeting)
ctx.Step(`^I send a POST request to v2 greet with name "([^"]*)"$`, sc.greetSteps.iSendPOSTRequestToV2GreetWithName)
ctx.Step(`^I send a POST request to v2 greet with invalid JSON "([^"]*)"$`, sc.greetSteps.iSendPOSTRequestToV2GreetWithInvalidJSON)
ctx.Step(`^the server is running with v2 enabled$`, sc.greetSteps.theServerIsRunningWithV2Enabled)
// Health steps
ctx.Step(`^I request the health endpoint$`, sc.healthSteps.iRequestTheHealthEndpoint)
ctx.Step(`^the server is running$`, sc.healthSteps.theServerIsRunning)
// Auth steps
ctx.Step(`^a user "([^"]*)" exists with password "([^"]*)"$`, sc.authSteps.aUserExistsWithPassword)
ctx.Step(`^I authenticate with username "([^"]*)" and password "([^"]*)"$`, sc.authSteps.iAuthenticateWithUsernameAndPassword)
ctx.Step(`^the authentication should be successful$`, sc.authSteps.theAuthenticationShouldBeSuccessful)
ctx.Step(`^I should receive a valid JWT token$`, sc.authSteps.iShouldReceiveAValidJWTToken)
ctx.Step(`^the authentication should fail$`, sc.authSteps.theAuthenticationShouldFail)
ctx.Step(`^I authenticate as admin with master password "([^"]*)"$`, sc.authSteps.iAuthenticateAsAdminWithMasterPassword)
ctx.Step(`^the token should contain admin claims$`, sc.authSteps.theTokenShouldContainAdminClaims)
ctx.Step(`^I register a new user "([^"]*)" with password "([^"]*)"$`, sc.authSteps.iRegisterANewUserWithPassword)
ctx.Step(`^the registration should be successful$`, sc.authSteps.theRegistrationShouldBeSuccessful)
ctx.Step(`^I should be able to authenticate with the new credentials$`, sc.authSteps.iShouldBeAbleToAuthenticateWithTheNewCredentials)
ctx.Step(`^I am authenticated as admin$`, sc.authSteps.iAmAuthenticatedAsAdmin)
ctx.Step(`^I request password reset for user "([^"]*)"$`, sc.authSteps.iRequestPasswordResetForUser)
ctx.Step(`^the password reset should be allowed$`, sc.authSteps.thePasswordResetShouldBeAllowed)
ctx.Step(`^the user should be flagged for password reset$`, sc.authSteps.theUserShouldBeFlaggedForPasswordReset)
ctx.Step(`^I complete password reset for "([^"]*)" with new password "([^"]*)"$`, sc.authSteps.iCompletePasswordResetForWithNewPassword)
ctx.Step(`^I should be able to authenticate with the new password$`, sc.authSteps.iShouldBeAbleToAuthenticateWithTheNewPassword)
ctx.Step(`^a user "([^"]*)" exists and is flagged for password reset$`, sc.authSteps.aUserExistsAndIsFlaggedForPasswordReset)
ctx.Step(`^the password reset should be successful$`, sc.authSteps.thePasswordResetShouldBeSuccessful)
ctx.Step(`^the password reset should fail$`, sc.authSteps.thePasswordResetShouldFail)
ctx.Step(`^the registration should fail$`, sc.authSteps.theRegistrationShouldFail)
ctx.Step(`^the authentication should fail with validation error$`, sc.authSteps.theAuthenticationShouldFailWithValidationError)
// JWT edge case steps
ctx.Step(`^I use an expired JWT token for authentication$`, sc.authSteps.iUseAnExpiredJWTTokenForAuthentication)
ctx.Step(`^I use a JWT token signed with wrong secret for authentication$`, sc.authSteps.iUseAJWTTokenSignedWithWrongSecretForAuthentication)
ctx.Step(`^I use a malformed JWT token for authentication$`, sc.authSteps.iUseAMalformedJWTTokenForAuthentication)
// JWT validation steps
ctx.Step(`^I validate the received JWT token$`, sc.authSteps.iValidateTheReceivedJWTToken)
ctx.Step(`^the token should be valid$`, sc.authSteps.theTokenShouldBeValid)
ctx.Step(`^it should contain the correct user ID$`, sc.authSteps.itShouldContainTheCorrectUserID)
ctx.Step(`^I should receive a different JWT token$`, sc.authSteps.iShouldReceiveADifferentJWTToken)
ctx.Step(`^I authenticate with username "([^"]*)" and password "([^"]*)" again$`, sc.authSteps.iAuthenticateWithUsernameAndPasswordAgain)
// JWT Secret Rotation steps
ctx.Step(`^the server is running with multiple JWT secrets$`, sc.authSteps.theServerIsRunningWithMultipleJWTSecrets)
ctx.Step(`^I should receive a valid JWT token signed with the primary secret$`, sc.authSteps.iShouldReceiveAValidJWTTokenSignedWithThePrimarySecret)
ctx.Step(`^I validate a JWT token signed with the secondary secret$`, sc.authSteps.iValidateAJWTTokenSignedWithTheSecondarySecret)
ctx.Step(`^I add a new secondary JWT secret to the server$`, sc.authSteps.iAddANewSecondaryJWTSecretToTheServer)
ctx.Step(`^I add a new secondary JWT secret and rotate to it$`, sc.authSteps.iAddANewSecondaryJWTSecretAndRotateToIt)
ctx.Step(`^I authenticate with username "([^"]*)" and password "([^"]*)" after rotation$`, sc.authSteps.iAuthenticateWithUsernameAndPasswordAfterRotation)
ctx.Step(`^I should receive a valid JWT token signed with the new secondary secret$`, sc.authSteps.iShouldReceiveAValidJWTTokenSignedWithTheNewSecondarySecret)
ctx.Step(`^the token should still be valid during retention period$`, sc.authSteps.theTokenShouldStillBeValidDuringRetentionPeriod)
ctx.Step(`^I use a JWT token signed with the expired secondary secret for authentication$`, sc.authSteps.iUseAJWTTokenSignedWithTheExpiredSecondarySecretForAuthentication)
ctx.Step(`^I use the old JWT token signed with primary secret$`, sc.authSteps.iUseTheOldJWTTokenSignedWithPrimarySecret)
ctx.Step(`^I validate the old JWT token signed with primary secret$`, sc.authSteps.iValidateTheOldJWTTokenSignedWithPrimarySecret)
ctx.Step(`^the server is running with primary JWT secret$`, sc.authSteps.theServerIsRunningWithPrimaryJWTSecret)
ctx.Step(`^the server is running with primary and expired secondary JWT secrets$`, sc.authSteps.theServerIsRunningWithPrimaryAndExpiredSecondaryJWTSecrets)
ctx.Step(`^the token should still be valid$`, sc.authSteps.theTokenShouldStillBeValid)
// Common steps
ctx.Step(`^the response should be "{\\"([^"]*)":\\"([^"]*)"}"$`, sc.commonSteps.theResponseShouldBe)
ctx.Step(`^the response should contain error "([^"]*)"$`, sc.commonSteps.theResponseShouldContainError)
ctx.Step(`^the status code should be (\d+)$`, sc.commonSteps.theStatusCodeShouldBe)
}