- Add missing JWT secret rotation step definitions - Implement JWT retention policy step implementations - Fix step pattern matching for Godog compatibility - Add proper godog.ErrPending for unimplemented steps - Resolve argument mismatch in step definitions Reduces undefined steps by 98% (52 → 1) All JWT secret rotation scenarios now have step definitions Remaining undefined step is response validation pattern issue
102 lines
7.0 KiB
Plaintext
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)
|
|
}
|