77import com .jobtracker .entity .GoogleDriveBaseResume ;
88import com .jobtracker .entity .GoogleDriveConnection ;
99import com .jobtracker .entity .JobApplication ;
10+ import com .jobtracker .entity .Role ;
11+ import com .jobtracker .entity .User ;
12+ import com .jobtracker .entity .enums .RoleName ;
1013import com .jobtracker .repository .ApplicationRepository ;
1114import com .jobtracker .repository .GoogleDriveBaseResumeRepository ;
1215import com .jobtracker .repository .GoogleDriveConnectionRepository ;
1316import com .jobtracker .repository .GoogleDriveOAuthStateRepository ;
1417import com .jobtracker .repository .PasswordResetTokenRepository ;
1518import com .jobtracker .repository .RefreshTokenRepository ;
19+ import com .jobtracker .repository .RoleRepository ;
1620import com .jobtracker .repository .UserAchievementRepository ;
1721import com .jobtracker .repository .UserGamificationRepository ;
1822import com .jobtracker .repository .UserRepository ;
3236import java .util .HashMap ;
3337import java .util .Map ;
3438import java .util .Optional ;
39+ import java .util .Set ;
3540import java .util .UUID ;
3641
3742import static org .assertj .core .api .Assertions .assertThat ;
@@ -56,9 +61,11 @@ class GoogleDriveControllerIT extends AbstractIntegrationTest {
5661 @ Autowired private GoogleDriveConnectionRepository googleDriveConnectionRepository ;
5762 @ Autowired private GoogleDriveBaseResumeRepository googleDriveBaseResumeRepository ;
5863 @ Autowired private GoogleDriveOAuthStateRepository googleDriveOAuthStateRepository ;
64+ @ Autowired private RoleRepository roleRepository ;
5965 @ Autowired private FakeGoogleDriveApiClient googleDriveApiClient ;
6066
61- private String accessToken ;
67+ private String betaAccessToken ;
68+ private String nonBetaAccessToken ;
6269
6370 @ BeforeEach
6471 void setUp () throws Exception {
@@ -79,20 +86,52 @@ void setUp() throws Exception {
7986 .andReturn ();
8087
8188 AuthResponse auth = objectMapper .readValue (result .getResponse ().getContentAsString (), AuthResponse .class );
82- accessToken = auth .accessToken ();
89+ nonBetaAccessToken = auth .accessToken ();
90+
91+ User user = userRepository .findByEmail ("driveuser@example.com" ).orElseThrow ();
92+ Role betaRole = roleRepository .findByName (RoleName .BETA )
93+ .orElseGet (() -> {
94+ Role role = new Role ();
95+ role .setName (RoleName .BETA );
96+ return roleRepository .save (role );
97+ });
98+ user .setRoles (Set .of (
99+ user .getRoles ().stream ().findFirst ().orElseThrow (),
100+ betaRole ));
101+ userRepository .save (user );
102+
103+ MvcResult loginResult = mockMvc .perform (post ("/api/v1/auth/login" )
104+ .contentType (MediaType .APPLICATION_JSON )
105+ .content ("""
106+ {
107+ "email": "driveuser@example.com",
108+ "password": "pass1234"
109+ }
110+ """ ))
111+ .andReturn ();
112+
113+ AuthResponse betaAuth = objectMapper .readValue (loginResult .getResponse ().getContentAsString (), AuthResponse .class );
114+ betaAccessToken = betaAuth .accessToken ();
83115 }
84116
85117 @ Test
86118 void startOauth_shouldReturnAuthorizationUrl () throws Exception {
87119 mockMvc .perform (post ("/api/v1/google-drive/oauth/start" )
88- .header ("Authorization" , "Bearer " + accessToken ))
120+ .header ("Authorization" , "Bearer " + betaAccessToken ))
89121 .andExpect (status ().isOk ())
90122 .andExpect (jsonPath ("$.authorizationUrl" ).value (org .hamcrest .Matchers .containsString ("https://accounts.google.com/o/oauth2/v2/auth" )))
91123 .andExpect (jsonPath ("$.state" ).isNotEmpty ())
92124 .andExpect (jsonPath ("$.redirectUri" ).value ("http://localhost:8080/api/v1/google-drive/oauth/callback" ))
93125 .andExpect (jsonPath ("$.scopes[0]" ).value ("https://www.googleapis.com/auth/drive" ));
94126 }
95127
128+ @ Test
129+ void startOauth_shouldReturn403_whenUserDoesNotHaveBetaRole () throws Exception {
130+ mockMvc .perform (post ("/api/v1/google-drive/oauth/start" )
131+ .header ("Authorization" , "Bearer " + nonBetaAccessToken ))
132+ .andExpect (status ().isForbidden ());
133+ }
134+
96135 @ Test
97136 void oauthCallback_shouldPersistConnectionAndRedirectToFrontend () throws Exception {
98137 googleDriveApiClient .tokens = new GoogleDriveApiClient .OAuthTokens (
@@ -105,7 +144,7 @@ void oauthCallback_shouldPersistConnectionAndRedirectToFrontend() throws Excepti
105144 new GoogleDriveApiClient .GoogleDriveAccountProfile ("perm-123" , "connected@example.com" , "Drive User" );
106145
107146 MvcResult startResult = mockMvc .perform (post ("/api/v1/google-drive/oauth/start" )
108- .header ("Authorization" , "Bearer " + accessToken ))
147+ .header ("Authorization" , "Bearer " + betaAccessToken ))
109148 .andExpect (status ().isOk ())
110149 .andReturn ();
111150
@@ -135,7 +174,7 @@ void updateRootFolder_shouldReturnUpdatedStatus() throws Exception {
135174 ));
136175
137176 mockMvc .perform (put ("/api/v1/google-drive/root-folder" )
138- .header ("Authorization" , "Bearer " + accessToken )
177+ .header ("Authorization" , "Bearer " + betaAccessToken )
139178 .contentType (MediaType .APPLICATION_JSON )
140179 .content ("{\" folderIdOrUrl\" :\" folder-123\" }" ))
141180 .andExpect (status ().isOk ())
@@ -150,7 +189,7 @@ void disconnect_shouldRemoveConnectionAndReturnMessage() throws Exception {
150189 assertThat (googleDriveConnectionRepository .findAll ()).hasSize (1 );
151190
152191 mockMvc .perform (delete ("/api/v1/google-drive/connection" )
153- .header ("Authorization" , "Bearer " + accessToken ))
192+ .header ("Authorization" , "Bearer " + betaAccessToken ))
154193 .andExpect (status ().isOk ())
155194 .andExpect (jsonPath ("$.message" ).value ("Google Drive connection removed" ));
156195
@@ -160,7 +199,7 @@ void disconnect_shouldRemoveConnectionAndReturnMessage() throws Exception {
160199 @ Test
161200 void disconnect_shouldSucceedEvenWithNoExistingConnection () throws Exception {
162201 mockMvc .perform (delete ("/api/v1/google-drive/connection" )
163- .header ("Authorization" , "Bearer " + accessToken ))
202+ .header ("Authorization" , "Bearer " + betaAccessToken ))
164203 .andExpect (status ().isOk ())
165204 .andExpect (jsonPath ("$.message" ).value ("Google Drive connection removed" ));
166205 }
@@ -177,7 +216,7 @@ void addBaseResume_shouldPersistResumeAndReturn201() throws Exception {
177216 ));
178217
179218 mockMvc .perform (post ("/api/v1/google-drive/base-resumes" )
180- .header ("Authorization" , "Bearer " + accessToken )
219+ .header ("Authorization" , "Bearer " + betaAccessToken )
181220 .contentType (MediaType .APPLICATION_JSON )
182221 .content ("{\" documentIdOrUrl\" :\" doc-abc\" }" ))
183222 .andExpect (status ().isCreated ())
@@ -200,7 +239,7 @@ void addBaseResume_shouldRejectNonGoogleDocsFile() throws Exception {
200239 ));
201240
202241 mockMvc .perform (post ("/api/v1/google-drive/base-resumes" )
203- .header ("Authorization" , "Bearer " + accessToken )
242+ .header ("Authorization" , "Bearer " + betaAccessToken )
204243 .contentType (MediaType .APPLICATION_JSON )
205244 .content ("{\" documentIdOrUrl\" :\" pdf-file\" }" ))
206245 .andExpect (status ().isBadRequest ());
@@ -213,7 +252,7 @@ void deleteBaseResume_shouldRemoveResumeAndReturn200() throws Exception {
213252 googleDriveBaseResumeRepository .save (resume );
214253
215254 mockMvc .perform (delete ("/api/v1/google-drive/base-resumes/" + resume .getId ())
216- .header ("Authorization" , "Bearer " + accessToken ))
255+ .header ("Authorization" , "Bearer " + betaAccessToken ))
217256 .andExpect (status ().isOk ())
218257 .andExpect (jsonPath ("$.message" ).value ("Base resume deleted successfully" ));
219258
@@ -223,7 +262,7 @@ void deleteBaseResume_shouldRemoveResumeAndReturn200() throws Exception {
223262 @ Test
224263 void deleteBaseResume_shouldReturn404ForUnknownId () throws Exception {
225264 mockMvc .perform (delete ("/api/v1/google-drive/base-resumes/" + UUID .randomUUID ())
226- .header ("Authorization" , "Bearer " + accessToken ))
265+ .header ("Authorization" , "Bearer " + betaAccessToken ))
227266 .andExpect (status ().isNotFound ());
228267 }
229268
@@ -249,7 +288,7 @@ void copyResume_shouldCreateFolderAndCopyDocument() throws Exception {
249288 ));
250289
251290 mockMvc .perform (post ("/api/v1/google-drive/applications/" + application .getId () + "/resume-copies" )
252- .header ("Authorization" , "Bearer " + accessToken )
291+ .header ("Authorization" , "Bearer " + betaAccessToken )
253292 .contentType (MediaType .APPLICATION_JSON )
254293 .content ("{\" baseResumeId\" :\" " + resume .getId () + "\" }" ))
255294 .andExpect (status ().isCreated ())
@@ -273,7 +312,7 @@ void copyResume_shouldReturn400WhenNoRootFolderConfigured() throws Exception {
273312 application = applicationRepository .save (application );
274313
275314 mockMvc .perform (post ("/api/v1/google-drive/applications/" + application .getId () + "/resume-copies" )
276- .header ("Authorization" , "Bearer " + accessToken )
315+ .header ("Authorization" , "Bearer " + betaAccessToken )
277316 .contentType (MediaType .APPLICATION_JSON )
278317 .content ("{\" baseResumeId\" :\" " + resume .getId () + "\" }" ))
279318 .andExpect (status ().isBadRequest ());
0 commit comments