View Javadoc
1   package fr.tiogars.chat.domains.settings.user.controllers;
2   
3   import static org.mockito.ArgumentMatchers.any;
4   import static org.mockito.ArgumentMatchers.eq;
5   import static org.mockito.Mockito.never;
6   import static org.mockito.Mockito.verify;
7   import static org.mockito.Mockito.when;
8   import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
9   import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
10  import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
11  import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
12  
13  import java.security.Principal;
14  import java.time.Instant;
15  import java.util.Optional;
16  
17  import org.junit.jupiter.api.Test;
18  import org.springframework.beans.factory.annotation.Autowired;
19  import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
20  import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
21  import org.springframework.context.annotation.Import;
22  import org.springframework.http.MediaType;
23  import org.springframework.security.core.userdetails.UserDetailsService;
24  import org.springframework.test.context.bean.override.mockito.MockitoBean;
25  import org.springframework.test.web.servlet.MockMvc;
26  
27  import fr.tiogars.chat.config.ApiCorsConfiguration;
28  import fr.tiogars.chat.domains.auth.services.JwtTokenService;
29  import fr.tiogars.chat.domains.settings.user.entities.UserSettings;
30  import fr.tiogars.chat.domains.settings.user.models.UpdateUserSettingsRequest;
31  import fr.tiogars.chat.domains.settings.user.services.UserSettingsService;
32  
33  @WebMvcTest({
34          MyUserSettingsReadController.class,
35          MyUserSettingsUpdateController.class,
36          UserSettingsReadController.class,
37          UserSettingsUpdateController.class,
38          AnonymousUserSettingsReadController.class,
39          AnonymousUserSettingsUpdateController.class
40  })
41  @AutoConfigureMockMvc(addFilters = false)
42  @Import(ApiCorsConfiguration.class)
43  class UserSettingsControllerTest {
44  
45      private static final Instant TIMESTAMP = Instant.parse("2026-01-02T03:04:05Z");
46      private static final Principal ALICE = () -> "alice";
47  
48      @Autowired
49      private MockMvc mockMvc;
50  
51      @MockitoBean
52      private UserSettingsService service;
53  
54      @MockitoBean
55      private JwtTokenService jwtTokenService;
56  
57      @MockitoBean
58      private UserDetailsService userDetailsService;
59  
60      @Test
61      void readMine_returnsSettingsOfAuthenticatedAccount() throws Exception {
62          when(service.findByUsername("alice")).thenReturn(Optional.of(settings(7L, null, "dark")));
63  
64          mockMvc.perform(get("/api/v1/settings/user/me").principal(ALICE))
65                  .andExpect(status().isOk())
66                  .andExpect(jsonPath("$.userId").value(7))
67                  .andExpect(jsonPath("$.viewMode").value("dark"));
68      }
69  
70      @Test
71      void updateMine_updatesSettingsOfAuthenticatedAccount() throws Exception {
72          when(service.updateByUsername(eq("alice"), any(UpdateUserSettingsRequest.class)))
73                  .thenReturn(Optional.of(settings(7L, null, "light")));
74  
75          mockMvc.perform(put("/api/v1/settings/user/me")
76                  .principal(ALICE)
77                  .contentType(MediaType.APPLICATION_JSON)
78                  .content("{\"viewMode\":\"light\"}"))
79                  .andExpect(status().isOk())
80                  .andExpect(jsonPath("$.viewMode").value("light"));
81      }
82  
83      @Test
84      void updateMine_rejectsUnknownViewMode() throws Exception {
85          mockMvc.perform(put("/api/v1/settings/user/me")
86                  .principal(ALICE)
87                  .contentType(MediaType.APPLICATION_JSON)
88                  .content("{\"viewMode\":\"neon\"}"))
89                  .andExpect(status().isBadRequest());
90  
91          verify(service, never()).updateByUsername(any(), any());
92      }
93  
94      @Test
95      void readUser_returnsNotFoundWhenAccountIsNotManaged() throws Exception {
96          when(service.findByUserId(1L)).thenReturn(Optional.empty());
97  
98          mockMvc.perform(get("/api/v1/settings/user/users/1"))
99                  .andExpect(status().isNotFound());
100     }
101 
102     @Test
103     void updateUser_updatesSettingsOfUserRoleAccount() throws Exception {
104         when(service.updateByUserId(eq(9L), any(UpdateUserSettingsRequest.class)))
105                 .thenReturn(Optional.of(settings(9L, null, "dark")));
106 
107         mockMvc.perform(put("/api/v1/settings/user/users/9")
108                 .contentType(MediaType.APPLICATION_JSON)
109                 .content("{\"viewMode\":\"dark\"}"))
110                 .andExpect(status().isOk())
111                 .andExpect(jsonPath("$.userId").value(9))
112                 .andExpect(jsonPath("$.viewMode").value("dark"));
113     }
114 
115     @Test
116     void readAnonymous_returnsRoleSettings() throws Exception {
117         when(service.findAnonymous()).thenReturn(settings(null, "ANONYMOUS", "system"));
118 
119         mockMvc.perform(get("/api/v1/settings/user/anonymous"))
120                 .andExpect(status().isOk())
121                 .andExpect(jsonPath("$.roleCode").value("ANONYMOUS"))
122                 .andExpect(jsonPath("$.viewMode").value("system"));
123     }
124 
125     @Test
126     void updateAnonymous_updatesRoleSettings() throws Exception {
127         when(service.updateAnonymous(any(UpdateUserSettingsRequest.class)))
128                 .thenReturn(settings(null, "ANONYMOUS", "dark"));
129 
130         mockMvc.perform(put("/api/v1/settings/user/anonymous")
131                 .contentType(MediaType.APPLICATION_JSON)
132                 .content("{\"viewMode\":\"dark\"}"))
133                 .andExpect(status().isOk())
134                 .andExpect(jsonPath("$.viewMode").value("dark"));
135     }
136 
137     private static UserSettings settings(Long userId, String roleCode, String viewMode) {
138         return new UserSettings(userId, roleCode, viewMode, TIMESTAMP, TIMESTAMP);
139     }
140 }