diff --git a/src/main/java/com/jobtracker/dto/auth/RegisterRequest.java b/src/main/java/com/jobtracker/dto/auth/RegisterRequest.java index 19d3ee90..df9f9e58 100644 --- a/src/main/java/com/jobtracker/dto/auth/RegisterRequest.java +++ b/src/main/java/com/jobtracker/dto/auth/RegisterRequest.java @@ -1,6 +1,7 @@ package com.jobtracker.dto.auth; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; @@ -25,5 +26,9 @@ public record RegisterRequest( @Schema(description = "Confirm password (must match password)", example = "secureP@ss1") @NotBlank(message = "Confirm password is required") - String confirmPassword + String confirmPassword, + + @Schema(description = "User must accept the Privacy Policy to register", example = "true") + @AssertTrue(message = "You must accept the Privacy Policy to create an account") + boolean acceptedPrivacyPolicy ) {} diff --git a/src/main/java/com/jobtracker/dto/auth/UserResponse.java b/src/main/java/com/jobtracker/dto/auth/UserResponse.java index 937b02bc..959719c4 100644 --- a/src/main/java/com/jobtracker/dto/auth/UserResponse.java +++ b/src/main/java/com/jobtracker/dto/auth/UserResponse.java @@ -19,5 +19,7 @@ public record UserResponse( @Schema(description = "Granted application roles", example = "[\"USER\", \"BETA\"]") Set roles, @Schema(description = "Whether the user can access Google integration features", example = "true") - boolean canUseGoogleIntegration + boolean canUseGoogleIntegration, + @Schema(description = "Whether the user has accepted the Privacy Policy", example = "true") + boolean privacyPolicyAccepted ) {} diff --git a/src/main/java/com/jobtracker/entity/ToolExecutionMetric.java b/src/main/java/com/jobtracker/entity/ToolExecutionMetric.java index eb5c1ded..c6115ef5 100644 --- a/src/main/java/com/jobtracker/entity/ToolExecutionMetric.java +++ b/src/main/java/com/jobtracker/entity/ToolExecutionMetric.java @@ -1,7 +1,6 @@ package com.jobtracker.entity; import jakarta.persistence.*; -import lombok.*; import org.hibernate.annotations.UuidGenerator; import java.time.LocalDateTime; @@ -13,11 +12,6 @@ @Index(name = "idx_tool_metrics_created_at", columnList = "created_at"), @Index(name = "idx_tool_metrics_expensive", columnList = "expensive") }) -@Getter -@Setter -@Builder -@NoArgsConstructor -@AllArgsConstructor public class ToolExecutionMetric { @Id @@ -58,4 +52,72 @@ protected void onCreate() { createdAt = LocalDateTime.now(); } } + + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } + + public String getToolName() { return toolName; } + public void setToolName(String toolName) { this.toolName = toolName; } + + public long getExecutionTimeMs() { return executionTimeMs; } + public void setExecutionTimeMs(long executionTimeMs) { this.executionTimeMs = executionTimeMs; } + + public int getRequestBytes() { return requestBytes; } + public void setRequestBytes(int requestBytes) { this.requestBytes = requestBytes; } + + public int getResponseBytes() { return responseBytes; } + public void setResponseBytes(int responseBytes) { this.responseBytes = responseBytes; } + + public int getRequestTokens() { return requestTokens; } + public void setRequestTokens(int requestTokens) { this.requestTokens = requestTokens; } + + public int getResponseTokens() { return responseTokens; } + public void setResponseTokens(int responseTokens) { this.responseTokens = responseTokens; } + + public int getTotalTokens() { return totalTokens; } + public void setTotalTokens(int totalTokens) { this.totalTokens = totalTokens; } + + public boolean isExpensive() { return expensive; } + public void setExpensive(boolean expensive) { this.expensive = expensive; } + + public LocalDateTime getCreatedAt() { return createdAt; } + public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; } + + public static Builder builder() { return new Builder(); } + + public static class Builder { + private String toolName; + private long executionTimeMs; + private int requestBytes; + private int responseBytes; + private int requestTokens; + private int responseTokens; + private int totalTokens; + private boolean expensive; + private LocalDateTime createdAt; + + public Builder toolName(String toolName) { this.toolName = toolName; return this; } + public Builder executionTimeMs(long executionTimeMs) { this.executionTimeMs = executionTimeMs; return this; } + public Builder requestBytes(int requestBytes) { this.requestBytes = requestBytes; return this; } + public Builder responseBytes(int responseBytes) { this.responseBytes = responseBytes; return this; } + public Builder requestTokens(int requestTokens) { this.requestTokens = requestTokens; return this; } + public Builder responseTokens(int responseTokens) { this.responseTokens = responseTokens; return this; } + public Builder totalTokens(int totalTokens) { this.totalTokens = totalTokens; return this; } + public Builder expensive(boolean expensive) { this.expensive = expensive; return this; } + public Builder createdAt(LocalDateTime createdAt) { this.createdAt = createdAt; return this; } + + public ToolExecutionMetric build() { + ToolExecutionMetric m = new ToolExecutionMetric(); + m.toolName = toolName; + m.executionTimeMs = executionTimeMs; + m.requestBytes = requestBytes; + m.responseBytes = responseBytes; + m.requestTokens = requestTokens; + m.responseTokens = responseTokens; + m.totalTokens = totalTokens; + m.expensive = expensive; + m.createdAt = createdAt; + return m; + } + } } diff --git a/src/main/java/com/jobtracker/entity/User.java b/src/main/java/com/jobtracker/entity/User.java index 94f59570..768d1c34 100644 --- a/src/main/java/com/jobtracker/entity/User.java +++ b/src/main/java/com/jobtracker/entity/User.java @@ -32,6 +32,12 @@ public class User { @Column(name = "reminder_time", nullable = false) private LocalTime reminderTime; + @Column(name = "privacy_policy_accepted", nullable = false, columnDefinition = "TINYINT(1) DEFAULT 0") + private boolean privacyPolicyAccepted; + + @Column(name = "privacy_policy_accepted_at") + private LocalDateTime privacyPolicyAcceptedAt; + @Column(name = "created_at", nullable = false, updatable = false) private LocalDateTime createdAt; @@ -79,4 +85,10 @@ protected void onUpdate() { public Set getRoles() { return roles; } public void setRoles(Set roles) { this.roles = roles; } + + public boolean isPrivacyPolicyAccepted() { return privacyPolicyAccepted; } + public void setPrivacyPolicyAccepted(boolean privacyPolicyAccepted) { this.privacyPolicyAccepted = privacyPolicyAccepted; } + + public LocalDateTime getPrivacyPolicyAcceptedAt() { return privacyPolicyAcceptedAt; } + public void setPrivacyPolicyAcceptedAt(LocalDateTime privacyPolicyAcceptedAt) { this.privacyPolicyAcceptedAt = privacyPolicyAcceptedAt; } } diff --git a/src/main/java/com/jobtracker/mapper/AuthMapper.java b/src/main/java/com/jobtracker/mapper/AuthMapper.java index 72874153..dde07338 100644 --- a/src/main/java/com/jobtracker/mapper/AuthMapper.java +++ b/src/main/java/com/jobtracker/mapper/AuthMapper.java @@ -22,6 +22,7 @@ public UserResponse toUserResponse(User user) { user.getEmail(), user.getReminderTime(), roles, - roles.contains(RoleName.BETA.name())); + roles.contains(RoleName.BETA.name()), + user.isPrivacyPolicyAccepted()); } } diff --git a/src/main/java/com/jobtracker/service/AuthService.java b/src/main/java/com/jobtracker/service/AuthService.java index 231c4e51..448ce417 100644 --- a/src/main/java/com/jobtracker/service/AuthService.java +++ b/src/main/java/com/jobtracker/service/AuthService.java @@ -92,6 +92,8 @@ public AuthResponse register(RegisterRequest request) { user.setEmail(request.email()); user.setPasswordHash(passwordEncoder.encode(request.password())); user.setRoles(Set.of(resolveDefaultUserRole())); + user.setPrivacyPolicyAccepted(true); + user.setPrivacyPolicyAcceptedAt(java.time.LocalDateTime.now()); user = userRepository.save(user); log.info("event=REGISTRATION_SUCCESS email={} userId={}", user.getEmail(), user.getId()); return buildAuthResponse(user); diff --git a/src/main/resources/db/migration/V28__add_privacy_policy_accepted_to_users.sql b/src/main/resources/db/migration/V28__add_privacy_policy_accepted_to_users.sql new file mode 100644 index 00000000..7e2b739b --- /dev/null +++ b/src/main/resources/db/migration/V28__add_privacy_policy_accepted_to_users.sql @@ -0,0 +1,3 @@ +ALTER TABLE users + ADD COLUMN privacy_policy_accepted TINYINT(1) NOT NULL DEFAULT 0, + ADD COLUMN privacy_policy_accepted_at DATETIME NULL; diff --git a/src/test/java/com/jobtracker/e2e/ApplicationE2ETest.java b/src/test/java/com/jobtracker/e2e/ApplicationE2ETest.java index 81c7a17e..81fa3b62 100644 --- a/src/test/java/com/jobtracker/e2e/ApplicationE2ETest.java +++ b/src/test/java/com/jobtracker/e2e/ApplicationE2ETest.java @@ -47,7 +47,8 @@ void setUp() { "name": "App E2E User", "email": "appe2e@example.com", "password": "pass1234", - "confirmPassword": "pass1234" + "confirmPassword": "pass1234", + "acceptedPrivacyPolicy": true } """) .post("/api/v1/auth/register") @@ -282,7 +283,8 @@ void getById_shouldReturn404_whenBelongsToAnotherUser() { .contentType("application/json") .body(""" {"name": "Other User", "email": "other@example.com", - "password": "pass1234", "confirmPassword": "pass1234"} + "password": "pass1234", "confirmPassword": "pass1234", + "acceptedPrivacyPolicy": true} """) .post("/api/v1/auth/register"); diff --git a/src/test/java/com/jobtracker/e2e/AuthE2ETest.java b/src/test/java/com/jobtracker/e2e/AuthE2ETest.java index 96efad5f..1a5fba7f 100644 --- a/src/test/java/com/jobtracker/e2e/AuthE2ETest.java +++ b/src/test/java/com/jobtracker/e2e/AuthE2ETest.java @@ -57,7 +57,8 @@ void fullAuthFlow_register_login_refresh_logout() { "name": "E2E User", "email": "e2e@example.com", "password": "pass1234", - "confirmPassword": "pass1234" + "confirmPassword": "pass1234", + "acceptedPrivacyPolicy": true } """) .when() @@ -168,7 +169,8 @@ void register_shouldSetHttpOnlySecureSameSiteCookie() { "name": "Cookie User", "email": "cookies@example.com", "password": "pass1234", - "confirmPassword": "pass1234" + "confirmPassword": "pass1234", + "acceptedPrivacyPolicy": true } """) .when() @@ -192,7 +194,8 @@ void register_shouldReturn409_whenEmailDuplicated() { "name": "Dup User", "email": "dup@example.com", "password": "pass1234", - "confirmPassword": "pass1234" + "confirmPassword": "pass1234", + "acceptedPrivacyPolicy": true } """; @@ -212,7 +215,8 @@ void register_shouldReturn400_whenPasswordsMismatch() { "name": "Mismatch User", "email": "mismatch@example.com", "password": "pass1234", - "confirmPassword": "different" + "confirmPassword": "different", + "acceptedPrivacyPolicy": true } """) .when() @@ -231,7 +235,8 @@ void login_shouldReturn401_whenWrongPassword() { "name": "Wrong Pass", "email": "wrongpass@example.com", "password": "pass1234", - "confirmPassword": "pass1234" + "confirmPassword": "pass1234", + "acceptedPrivacyPolicy": true } """) .post("/api/v1/auth/register") @@ -265,7 +270,8 @@ void logout_shouldReturnSuccess_andClearCookie() { "name": "Logout User", "email": "logout@example.com", "password": "pass1234", - "confirmPassword": "pass1234" + "confirmPassword": "pass1234", + "acceptedPrivacyPolicy": true } """) .when() diff --git a/src/test/java/com/jobtracker/integration/ApplicationControllerIT.java b/src/test/java/com/jobtracker/integration/ApplicationControllerIT.java index c1703b5d..d24a787c 100644 --- a/src/test/java/com/jobtracker/integration/ApplicationControllerIT.java +++ b/src/test/java/com/jobtracker/integration/ApplicationControllerIT.java @@ -51,7 +51,7 @@ void setUp() throws Exception { refreshTokenRepository.deleteAll(); userRepository.deleteAll(); - RegisterRequest reg = new RegisterRequest("App User", "appuser@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("App User", "appuser@example.com", "pass1234", "pass1234", true); MvcResult result = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) diff --git a/src/test/java/com/jobtracker/integration/AuthControllerIT.java b/src/test/java/com/jobtracker/integration/AuthControllerIT.java index 8a66f4b8..8c1130f3 100644 --- a/src/test/java/com/jobtracker/integration/AuthControllerIT.java +++ b/src/test/java/com/jobtracker/integration/AuthControllerIT.java @@ -68,7 +68,7 @@ void cleanDb() { @Test void register_shouldReturn201_setRefreshTokenCookie_andReturnAccessToken() throws Exception { - RegisterRequest request = new RegisterRequest("Test User", "register@example.com", "pass1234", "pass1234"); + RegisterRequest request = new RegisterRequest("Test User", "register@example.com", "pass1234", "pass1234", true); MvcResult result = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) @@ -99,7 +99,7 @@ void register_shouldReturn201_setRefreshTokenCookie_andReturnAccessToken() throw @Test void register_shouldReturn409_whenEmailAlreadyExists() throws Exception { - RegisterRequest request = new RegisterRequest("Test User", "duplicate@example.com", "pass1234", "pass1234"); + RegisterRequest request = new RegisterRequest("Test User", "duplicate@example.com", "pass1234", "pass1234", true); mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) @@ -114,7 +114,7 @@ void register_shouldReturn409_whenEmailAlreadyExists() throws Exception { @Test void register_shouldReturn400_whenPasswordsDoNotMatch() throws Exception { - RegisterRequest request = new RegisterRequest("Test User", "mismatch@example.com", "pass1234", "different"); + RegisterRequest request = new RegisterRequest("Test User", "mismatch@example.com", "pass1234", "different", true); mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) @@ -125,7 +125,7 @@ void register_shouldReturn400_whenPasswordsDoNotMatch() throws Exception { @Test void login_shouldReturn200_setRefreshTokenCookie_andReturnAccessToken() throws Exception { // First register - RegisterRequest reg = new RegisterRequest("Login User", "login@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Login User", "login@example.com", "pass1234", "pass1234", true); mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))); @@ -164,7 +164,7 @@ void login_shouldReturn401_whenBadCredentials() throws Exception { @Test void refresh_shouldReadFromCookie_returnNewAccessToken_andRotateRefreshTokenCookie() throws Exception { // Register to get initial tokens - RegisterRequest reg = new RegisterRequest("Refresh User", "refresh@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Refresh User", "refresh@example.com", "pass1234", "pass1234", true); MvcResult regResult = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) @@ -213,7 +213,7 @@ void refresh_shouldReturn401_whenRefreshTokenIsInvalid() throws Exception { @Test void logout_shouldClearRefreshTokenCookie() throws Exception { // Register - RegisterRequest reg = new RegisterRequest("Logout User", "logout@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Logout User", "logout@example.com", "pass1234", "pass1234", true); MvcResult regResult = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) @@ -247,7 +247,7 @@ void logout_shouldClearRefreshTokenCookie() throws Exception { @Test void me_shouldReturn200_whenAuthenticated() throws Exception { - RegisterRequest reg = new RegisterRequest("Me User", "me@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Me User", "me@example.com", "pass1234", "pass1234", true); MvcResult regResult = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) @@ -271,7 +271,7 @@ void me_shouldReturn403_whenNotAuthenticated() throws Exception { @Test void me_shouldReturn403_whenTokenDoesNotContainRoleUser() throws Exception { - RegisterRequest reg = new RegisterRequest("Admin Token User", "admin-token@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Admin Token User", "admin-token@example.com", "pass1234", "pass1234", true); mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) @@ -290,7 +290,7 @@ void me_shouldReturn403_whenTokenDoesNotContainRoleUser() throws Exception { @Test void sendTestEmail_shouldReturn200_whenAuthenticated() throws Exception { - RegisterRequest reg = new RegisterRequest("Mail User", "mail-user@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Mail User", "mail-user@example.com", "pass1234", "pass1234", true); MvcResult regResult = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) @@ -321,7 +321,7 @@ void forgotPassword_shouldReturn200_regardlessOfEmailExistence() throws Exceptio @Test void updateProfile_shouldReturn200_whenAuthenticated() throws Exception { - RegisterRequest reg = new RegisterRequest("Profile User", "profile@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Profile User", "profile@example.com", "pass1234", "pass1234", true); MvcResult regResult = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) @@ -340,7 +340,7 @@ void updateProfile_shouldReturn200_whenAuthenticated() throws Exception { @Test void changePassword_shouldReturn200_andAllowLoginWithNewPassword() throws Exception { - RegisterRequest reg = new RegisterRequest("Password User", "password-change@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Password User", "password-change@example.com", "pass1234", "pass1234", true); MvcResult regResult = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) @@ -365,7 +365,7 @@ void changePassword_shouldReturn200_andAllowLoginWithNewPassword() throws Except @Test void changePassword_shouldReturn400_whenCurrentPasswordIsInvalid() throws Exception { - RegisterRequest reg = new RegisterRequest("Password User", "password-invalid@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Password User", "password-invalid@example.com", "pass1234", "pass1234", true); MvcResult regResult = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) @@ -383,7 +383,7 @@ void changePassword_shouldReturn400_whenCurrentPasswordIsInvalid() throws Except @Test void passkeyLoginOptions_shouldReturnFallbackWhenUserHasNoPasskeys() throws Exception { - RegisterRequest reg = new RegisterRequest("No Passkey User", "no-passkey@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("No Passkey User", "no-passkey@example.com", "pass1234", "pass1234", true); mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) @@ -407,7 +407,7 @@ void passkeyRegisterOptions_shouldReturn403WhenNotAuthenticated() throws Excepti @Test void passkeyMe_shouldReturnHasPasskeysFalseByDefault() throws Exception { - RegisterRequest reg = new RegisterRequest("Passkey Status User", "passkey-status@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Passkey Status User", "passkey-status@example.com", "pass1234", "pass1234", true); MvcResult regResult = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) diff --git a/src/test/java/com/jobtracker/integration/AuthRateLimiterIT.java b/src/test/java/com/jobtracker/integration/AuthRateLimiterIT.java index 1214195a..bfdbe3c0 100644 --- a/src/test/java/com/jobtracker/integration/AuthRateLimiterIT.java +++ b/src/test/java/com/jobtracker/integration/AuthRateLimiterIT.java @@ -25,7 +25,7 @@ class AuthRateLimiterIT extends AbstractIntegrationTest { @Test void login_shouldReturn429_whenRateLimitIsExceeded() throws Exception { - RegisterRequest registerRequest = new RegisterRequest("Rate Limit User", "ratelimit@example.com", "pass1234", "pass1234"); + RegisterRequest registerRequest = new RegisterRequest("Rate Limit User", "ratelimit@example.com", "pass1234", "pass1234", true); LoginRequest loginRequest = new LoginRequest("ratelimit@example.com", "pass1234"); mockMvc.perform(post("/api/v1/auth/register") diff --git a/src/test/java/com/jobtracker/integration/GamificationControllerIT.java b/src/test/java/com/jobtracker/integration/GamificationControllerIT.java index d283115e..a8fafe8d 100644 --- a/src/test/java/com/jobtracker/integration/GamificationControllerIT.java +++ b/src/test/java/com/jobtracker/integration/GamificationControllerIT.java @@ -121,7 +121,7 @@ void getAchievements_shouldReturnCatalog() throws Exception { } private String registerAndGetAccessToken(String email) throws Exception { - RegisterRequest request = new RegisterRequest("Gamification User", email, "pass1234", "pass1234"); + RegisterRequest request = new RegisterRequest("Gamification User", email, "pass1234", "pass1234", true); MvcResult result = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) diff --git a/src/test/java/com/jobtracker/integration/GoogleDriveControllerIT.java b/src/test/java/com/jobtracker/integration/GoogleDriveControllerIT.java index 518c62e2..7a602abd 100644 --- a/src/test/java/com/jobtracker/integration/GoogleDriveControllerIT.java +++ b/src/test/java/com/jobtracker/integration/GoogleDriveControllerIT.java @@ -87,7 +87,7 @@ void setUp() throws Exception { userInterviewMetricsRepository.deleteAll(); userRepository.deleteAll(); - RegisterRequest reg = new RegisterRequest("Drive User", "driveuser@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Drive User", "driveuser@example.com", "pass1234", "pass1234", true); MvcResult result = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) diff --git a/src/test/java/com/jobtracker/integration/GptOAuthFlowIT.java b/src/test/java/com/jobtracker/integration/GptOAuthFlowIT.java index 23edf7d0..caa69161 100644 --- a/src/test/java/com/jobtracker/integration/GptOAuthFlowIT.java +++ b/src/test/java/com/jobtracker/integration/GptOAuthFlowIT.java @@ -223,7 +223,7 @@ void googleDriveCallback_shouldRemainPublic() throws Exception { } private AuthResponse registerUser(String email, String password) throws Exception { - RegisterRequest request = new RegisterRequest("GPT User", email, password, password); + RegisterRequest request = new RegisterRequest("GPT User", email, password, password, true); MvcResult result = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) diff --git a/src/test/java/com/jobtracker/integration/mcp/McpAuthIT.java b/src/test/java/com/jobtracker/integration/mcp/McpAuthIT.java index f091b9ee..6904cf7e 100644 --- a/src/test/java/com/jobtracker/integration/mcp/McpAuthIT.java +++ b/src/test/java/com/jobtracker/integration/mcp/McpAuthIT.java @@ -59,7 +59,7 @@ void setUp() throws Exception { refreshTokenRepository.deleteAll(); userRepository.deleteAll(); - RegisterRequest reg = new RegisterRequest("MCP Test User", "mcp-test@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("MCP Test User", "mcp-test@example.com", "pass1234", "pass1234", true); MvcResult result = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) diff --git a/src/test/java/com/jobtracker/integration/mcp/McpToolsIT.java b/src/test/java/com/jobtracker/integration/mcp/McpToolsIT.java index 3c4402f9..af08f7e4 100644 --- a/src/test/java/com/jobtracker/integration/mcp/McpToolsIT.java +++ b/src/test/java/com/jobtracker/integration/mcp/McpToolsIT.java @@ -101,7 +101,7 @@ void setUp() throws Exception { refreshTokenRepository.deleteAll(); userRepository.deleteAll(); - RegisterRequest reg = new RegisterRequest("Tools Test User", "tools-test@example.com", "pass1234", "pass1234"); + RegisterRequest reg = new RegisterRequest("Tools Test User", "tools-test@example.com", "pass1234", "pass1234", true); MvcResult result = mockMvc.perform(post("/api/v1/auth/register") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(reg))) diff --git a/src/test/java/com/jobtracker/unit/AuthServiceTest.java b/src/test/java/com/jobtracker/unit/AuthServiceTest.java index 508d8088..e4da1839 100644 --- a/src/test/java/com/jobtracker/unit/AuthServiceTest.java +++ b/src/test/java/com/jobtracker/unit/AuthServiceTest.java @@ -56,7 +56,7 @@ class AuthServiceTest { @Test void register_shouldReturnAuthResponse_whenValidRequest() { - RegisterRequest request = new RegisterRequest("John", "john@example.com", "pass1234", "pass1234"); + RegisterRequest request = new RegisterRequest("John", "john@example.com", "pass1234", "pass1234", true); User savedUser = buildUser(USER_UUID, "john@example.com"); when(userRepository.existsByEmail(request.email())).thenReturn(false); @@ -71,7 +71,7 @@ void register_shouldReturnAuthResponse_whenValidRequest() { "john@example.com", LocalTime.of(9, 0), Set.of("USER"), - false)); + false, true)); AuthResponse result = authService.register(request); @@ -85,7 +85,7 @@ void register_shouldReturnAuthResponse_whenValidRequest() { @Test void register_shouldThrow_whenPasswordsDoNotMatch() { - RegisterRequest request = new RegisterRequest("John", "john@example.com", "pass1234", "different"); + RegisterRequest request = new RegisterRequest("John", "john@example.com", "pass1234", "different", true); assertThatThrownBy(() -> authService.register(request)) .isInstanceOf(BadRequestException.class) .hasMessageContaining("Passwords do not match"); @@ -93,7 +93,7 @@ void register_shouldThrow_whenPasswordsDoNotMatch() { @Test void register_shouldThrow_whenEmailAlreadyExists() { - RegisterRequest request = new RegisterRequest("John", "john@example.com", "pass1234", "pass1234"); + RegisterRequest request = new RegisterRequest("John", "john@example.com", "pass1234", "pass1234", true); when(userRepository.existsByEmail(request.email())).thenReturn(true); assertThatThrownBy(() -> authService.register(request)) .isInstanceOf(ConflictException.class) @@ -115,7 +115,7 @@ void login_shouldReturnAuthResponse_whenValidCredentials() { "john@example.com", LocalTime.of(9, 0), Set.of("USER"), - false)); + false, true)); AuthResponse result = authService.login(request); diff --git a/src/test/java/com/jobtracker/unit/mcp/McpProfileToolsTest.java b/src/test/java/com/jobtracker/unit/mcp/McpProfileToolsTest.java index 2e9fb7d6..2440cfab 100644 --- a/src/test/java/com/jobtracker/unit/mcp/McpProfileToolsTest.java +++ b/src/test/java/com/jobtracker/unit/mcp/McpProfileToolsTest.java @@ -62,7 +62,7 @@ void currentUser_serializesAuthenticatedUser() throws Exception { "john@example.com", java.time.LocalTime.of(19, 0), java.util.Set.of("USER", "BETA"), - true); + true, true); when(securityUtils.getCurrentUser()).thenReturn(user); when(authMapper.toUserResponse(user)).thenReturn(expected);