Subject: [PATCH] boot4_4_fix_userCache --- Index: src/test/java/ru/javaops/bootjava/user/web/ProfileControllerTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/test/java/ru/javaops/bootjava/user/web/ProfileControllerTest.java b/src/test/java/ru/javaops/bootjava/user/web/ProfileControllerTest.java --- a/src/test/java/ru/javaops/bootjava/user/web/ProfileControllerTest.java (revision 97c957acb43aba3fea4fa1413ae0cc4b4a0e4395) +++ b/src/test/java/ru/javaops/bootjava/user/web/ProfileControllerTest.java (date 1765565342495) @@ -87,6 +87,25 @@ .andExpect(status().isUnprocessableContent()); } + @Test + void updateEmail() throws Exception { + perform(MockMvcRequestBuilders.get(REST_URL) + .with(userHttpBasic(user))) + .andExpect(status().isOk()); + + UserTo updatedTo = new UserTo(null, "newName", NEW_MAIL, "newPassword"); + perform(MockMvcRequestBuilders.put(REST_URL).contentType(MediaType.APPLICATION_JSON) + .with(userHttpBasic(user)) + .content(JsonUtil.writeValue(updatedTo))) + .andDo(print()) + .andExpect(status().isNoContent()); + USER_MATCHER.assertMatch(repository.getExisted(USER_ID), UsersUtil.updateFromTo(new User(user), updatedTo)); + + perform(MockMvcRequestBuilders.get(REST_URL) + .with(userHttpBasic(user))) + .andExpect(status().isUnauthorized()); + } + @Test @WithUserDetails(value = USER_MAIL) void updateInvalid() throws Exception { Index: src/test/resources/application-test.yaml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/test/resources/application-test.yaml b/src/test/resources/application-test.yaml --- a/src/test/resources/application-test.yaml (revision 97c957acb43aba3fea4fa1413ae0cc4b4a0e4395) +++ b/src/test/resources/application-test.yaml (date 1765563122713) @@ -1,1 +1,1 @@ -spring.cache.type: none \ No newline at end of file +#spring.cache.type: none \ No newline at end of file Index: src/test/java/ru/javaops/bootjava/AbstractControllerTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/test/java/ru/javaops/bootjava/AbstractControllerTest.java b/src/test/java/ru/javaops/bootjava/AbstractControllerTest.java --- a/src/test/java/ru/javaops/bootjava/AbstractControllerTest.java (revision 97c957acb43aba3fea4fa1413ae0cc4b4a0e4395) +++ b/src/test/java/ru/javaops/bootjava/AbstractControllerTest.java (date 1765565240110) @@ -3,12 +3,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.RequestPostProcessor; import org.springframework.transaction.annotation.Transactional; import ru.javaops.bootjava.app.config.WebConfig; +import ru.javaops.bootjava.user.model.User; //https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-testing-spring-boot-applications @SpringBootTest @@ -25,4 +28,8 @@ builder.header(WebConfig.VERSION_HEADER, WebConfig.CURRENT_VERSION); return mockMvc.perform(builder); } + + protected static RequestPostProcessor userHttpBasic(User user) { + return SecurityMockMvcRequestPostProcessors.httpBasic(user.getEmail(), user.getPassword()); + } } Index: src/test/java/ru/javaops/bootjava/user/web/AdminUserControllerTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/test/java/ru/javaops/bootjava/user/web/AdminUserControllerTest.java b/src/test/java/ru/javaops/bootjava/user/web/AdminUserControllerTest.java --- a/src/test/java/ru/javaops/bootjava/user/web/AdminUserControllerTest.java (revision 97c957acb43aba3fea4fa1413ae0cc4b4a0e4395) +++ b/src/test/java/ru/javaops/bootjava/user/web/AdminUserControllerTest.java (date 1765565383082) @@ -110,6 +110,27 @@ USER_MATCHER.assertMatch(repository.getExisted(USER_ID), getUpdated()); } + @Test + void updateEmail() throws Exception { + perform(MockMvcRequestBuilders.get(ProfileController.REST_URL) + .with(userHttpBasic(user))) + .andExpect(status().isOk()); + + User updated = getUpdated(); + updated.setEmail(NEW_MAIL); + perform(MockMvcRequestBuilders.put(REST_URL_SLASH + USER_ID) + .with(userHttpBasic(admin)) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonWithPassword(updated, "newPass"))) + .andDo(print()) + .andExpect(status().isNoContent()); + USER_MATCHER.assertMatch(repository.getExisted(USER_ID), updated); + + perform(MockMvcRequestBuilders.get(ProfileController.REST_URL) + .with(userHttpBasic(user))) + .andExpect(status().isUnauthorized()); + } + @Test @WithUserDetails(value = ADMIN_MAIL) void createWithLocation() throws Exception { Index: src/test/java/ru/javaops/bootjava/user/UserTestData.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/test/java/ru/javaops/bootjava/user/UserTestData.java b/src/test/java/ru/javaops/bootjava/user/UserTestData.java --- a/src/test/java/ru/javaops/bootjava/user/UserTestData.java (revision 97c957acb43aba3fea4fa1413ae0cc4b4a0e4395) +++ b/src/test/java/ru/javaops/bootjava/user/UserTestData.java (date 1765550513700) @@ -19,6 +19,7 @@ public static final String USER_MAIL = "user@yandex.ru"; public static final String ADMIN_MAIL = "admin@gmail.com"; public static final String GUEST_MAIL = "guest@gmail.com"; + public static final String NEW_MAIL = "new@gmail.com"; public static final User user = new User(USER_ID, "User", USER_MAIL, "password", Role.USER); public static final User admin = new User(ADMIN_ID, "Admin", ADMIN_MAIL, "admin", Role.ADMIN, Role.USER); Index: src/main/java/ru/javaops/bootjava/user/web/AdminUserController.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/main/java/ru/javaops/bootjava/user/web/AdminUserController.java b/src/main/java/ru/javaops/bootjava/user/web/AdminUserController.java --- a/src/main/java/ru/javaops/bootjava/user/web/AdminUserController.java (revision 97c957acb43aba3fea4fa1413ae0cc4b4a0e4395) +++ b/src/main/java/ru/javaops/bootjava/user/web/AdminUserController.java (date 1765564226899) @@ -29,13 +29,11 @@ return super.get(id); } - @Override @DeleteMapping("/{id}") @ResponseStatus(HttpStatus.NO_CONTENT) public void delete(@PathVariable int id) { User user = repository.getExisted(id); - super.delete(id); - userCache.removeUserFromCache(user.getEmail()); + super.delete(id, user.getEmail()); } @GetMapping @@ -60,8 +58,8 @@ public void update(@Valid @RequestBody User user, @PathVariable int id) { log.info("update {} with id={}", user, id); assureIdConsistent(user, id); - repository.prepareAndSave(user); - userCache.removeUserFromCache(user.getEmail()); + User dbUser = repository.getExisted(id); + super.update(user, dbUser.getEmail()); } @GetMapping("/by-email") Index: src/main/java/ru/javaops/bootjava/user/web/AbstractUserController.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/main/java/ru/javaops/bootjava/user/web/AbstractUserController.java b/src/main/java/ru/javaops/bootjava/user/web/AbstractUserController.java --- a/src/main/java/ru/javaops/bootjava/user/web/AbstractUserController.java (revision 97c957acb43aba3fea4fa1413ae0cc4b4a0e4395) +++ b/src/main/java/ru/javaops/bootjava/user/web/AbstractUserController.java (date 1765563996194) @@ -32,8 +32,14 @@ return repository.getExisted(id); } - public void delete(int id) { + public void delete(int id, String invalidateEmail) { log.info("delete {}", id); repository.deleteExisted(id); + userCache.removeUserFromCache(invalidateEmail); + } + + public void update(User user, String invalidateEmail) { + repository.prepareAndSave(user); + userCache.removeUserFromCache(invalidateEmail); } } \ No newline at end of file Index: src/main/java/ru/javaops/bootjava/user/web/ProfileController.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/src/main/java/ru/javaops/bootjava/user/web/ProfileController.java b/src/main/java/ru/javaops/bootjava/user/web/ProfileController.java --- a/src/main/java/ru/javaops/bootjava/user/web/ProfileController.java (revision 97c957acb43aba3fea4fa1413ae0cc4b4a0e4395) +++ b/src/main/java/ru/javaops/bootjava/user/web/ProfileController.java (date 1765563996179) @@ -35,8 +35,7 @@ @DeleteMapping @ResponseStatus(HttpStatus.NO_CONTENT) public void delete(@AuthenticationPrincipal AuthUser authUser) { - super.delete(authUser.id()); - userCache.removeUserFromCache(authUser.getUsername()); + super.delete(authUser.id(), authUser.getUsername()); } @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) @@ -57,7 +56,6 @@ log.info("update {} with id={}", userTo, authUser.id()); assureIdConsistent(userTo, authUser.id()); User user = authUser.getUser(); - repository.prepareAndSave(UsersUtil.updateFromTo(user, userTo)); - userCache.removeUserFromCache(authUser.getUsername()); + super.update(UsersUtil.updateFromTo(user, userTo), authUser.getUsername()); } } \ No newline at end of file