From 8224e3446b7d23219a74cc8d1a39204c0a4b547f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 19:41:05 +0000 Subject: [PATCH] test: Add tests for ChangePassword mutation This commit introduces a new test suite for the `ChangePassword` GraphQL mutation in `internal/adapters/graphql/auth_mutations_test.go`. The new tests cover the following scenarios: - A user successfully changes their password. - The mutation fails when the provided current password is incorrect. - The mutation fails when the request is made by an unauthenticated user. --- .../adapters/graphql/auth_mutations_test.go | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 internal/adapters/graphql/auth_mutations_test.go diff --git a/internal/adapters/graphql/auth_mutations_test.go b/internal/adapters/graphql/auth_mutations_test.go new file mode 100644 index 0000000..680ffb6 --- /dev/null +++ b/internal/adapters/graphql/auth_mutations_test.go @@ -0,0 +1,113 @@ +package graphql_test + +import ( + "context" + "os" + "testing" + "tercul/internal/adapters/graphql" + "tercul/internal/app/auth" + "tercul/internal/domain" + platform_auth "tercul/internal/platform/auth" + "tercul/internal/testutil" + + "github.com/stretchr/testify/suite" +) + +type AuthMutationTestSuite struct { + testutil.IntegrationTestSuite + resolver graphql.MutationResolver +} + +func TestAuthMutations(t *testing.T) { + suite.Run(t, new(AuthMutationTestSuite)) +} + +func (s *AuthMutationTestSuite) SetupSuite() { + s.IntegrationTestSuite.SetupSuite(&testutil.TestConfig{ + DBPath: "auth_mutations_test.db", + }) +} + +func (s *AuthMutationTestSuite) TearDownSuite() { + s.IntegrationTestSuite.TearDownSuite() + os.Remove("auth_mutations_test.db") +} + +func (s *AuthMutationTestSuite) SetupTest() { + s.IntegrationTestSuite.SetupTest() + s.resolver = (&graphql.Resolver{App: s.App}).Mutation() +} + +func (s *AuthMutationTestSuite) TestChangePassword() { + // Helper to create a user for tests + createUser := func(username, email, password string) *domain.User { + resp, err := s.App.Auth.Commands.Register(context.Background(), auth.RegisterInput{ + Username: username, + Email: email, + Password: password, + }) + s.Require().NoError(err) + return resp.User + } + + // Helper to create a context with JWT claims + contextWithClaims := func(user *domain.User) context.Context { + return testutil.ContextWithClaims(context.Background(), &platform_auth.Claims{ + UserID: user.ID, + Role: string(user.Role), + }) + } + + s.Run("Success", func() { + // Arrange + initialPassword := "password123" + newPassword := "newPassword456" + user := createUser("testuser-changepw", "testuser.changepw@test.com", initialPassword) + ctx := contextWithClaims(user) + + // Act + success, err := s.resolver.ChangePassword(ctx, initialPassword, newPassword) + + // Assert + s.Require().NoError(err) + s.True(success) + + // Verify the password change by trying to log in with the new and old passwords + _, err = s.App.Auth.Commands.Login(context.Background(), auth.LoginInput{Email: user.Email, Password: newPassword}) + s.NoError(err, "Login with new password should succeed") + + _, err = s.App.Auth.Commands.Login(context.Background(), auth.LoginInput{Email: user.Email, Password: initialPassword}) + s.Error(err, "Login with old password should fail") + s.ErrorIs(err, auth.ErrInvalidCredentials) + }) + + s.Run("Incorrect current password", func() { + // Arrange + initialPassword := "password123" + newPassword := "newPassword456" + user := createUser("testuser-wrongpw", "testuser.wrongpw@test.com", initialPassword) + ctx := contextWithClaims(user) + + // Act + success, err := s.resolver.ChangePassword(ctx, "wrong-password", newPassword) + + // Assert + s.Require().Error(err) + s.False(success) + s.ErrorIs(err, auth.ErrInvalidCredentials) + + // Verify the password was not changed + _, loginErr := s.App.Auth.Commands.Login(context.Background(), auth.LoginInput{Email: user.Email, Password: initialPassword}) + s.NoError(loginErr, "Login with original password should still succeed") + }) + + s.Run("Unauthenticated user", func() { + // Act + success, err := s.resolver.ChangePassword(context.Background(), "any-password", "any-new-password") + + // Assert + s.Require().Error(err) + s.False(success) + s.ErrorIs(err, domain.ErrUnauthorized) + }) +} \ No newline at end of file