1+ package me .oldboy .integration .controllers .api_wiremock_scenario ;
2+ 3+ import com .github .tomakehurst .wiremock .WireMockServer ;
4+ import com .github .tomakehurst .wiremock .client .WireMock ;
5+ import lombok .SneakyThrows ;
6+ import me .oldboy .config .test_data_source .TestContainerInit ;
7+ import me .oldboy .integration .annotation .IT ;
8+ import me .oldboy .jwt_test_utils .JwtTestUtils ;
9+ import org .jose4j .jwk .JsonWebKeySet ;
10+ import org .jose4j .jwk .RsaJsonWebKey ;
11+ import org .jose4j .jwk .RsaJwkGenerator ;
12+ import org .jose4j .jws .AlgorithmIdentifiers ;
13+ import org .jose4j .lang .JoseException ;
14+ import org .junit .jupiter .api .AfterEach ;
15+ import org .junit .jupiter .api .BeforeEach ;
16+ import org .junit .jupiter .api .Test ;
17+ import org .springframework .beans .factory .annotation .Autowired ;
18+ import org .springframework .http .MediaType ;
19+ import org .springframework .test .annotation .DirtiesContext ;
20+ import org .springframework .test .web .servlet .MockMvc ;
21+ import org .springframework .test .web .servlet .request .MockMvcRequestBuilders ;
22+ import org .springframework .test .web .servlet .setup .MockMvcBuilders ;
23+ import org .springframework .web .context .WebApplicationContext ;
24+ 25+ import java .util .HashMap ;
26+ import java .util .List ;
27+ import java .util .Map ;
28+ 29+ import static com .github .tomakehurst .wiremock .client .WireMock .*;
30+ import static me .oldboy .test_constant .TestConstantFields .EXIST_EMAIL_WITH_READ_AUTH ;
31+ import static org .hamcrest .Matchers .containsString ;
32+ import static org .springframework .security .test .web .servlet .setup .SecurityMockMvcConfigurers .springSecurity ;
33+ import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .get ;
34+ import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .content ;
35+ import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .status ;
36+ 37+ @ IT
38+ /*
39+ В нашем случае тесты проходя поодиночке или даже в комплексе под одним классом при параллельном
40+ запуске всех разом приводят к падению части из них. Spring Test кэширует контекст, что может
41+ привести к проблемам. Добавим аннотацию @DirtiesContext на уровне классов, чтобы принудительно
42+ пересоздавать контекст - это очень сильно замедлит выполнение тестов, но обеспечит изоляцию и
43+ прохождения всех тестов "разом", при одновременном запуске.
44+ */
45+ @ DirtiesContext (classMode = DirtiesContext .ClassMode .AFTER_EACH_TEST_METHOD )
46+ class WireMockAccountControllerIT extends TestContainerInit {
47+ 48+ @ Autowired
49+ private WebApplicationContext webApplicationContext ;
50+ private MockMvc mockMvc ;
51+ private WireMockServer wireMockServer ;
52+ private RsaJsonWebKey rsaJsonWebKey ;
53+ private Map <String , Object > realmAccessClaimsAdmin ;
54+ private Map <String , Object > realmAccessClaimsUser ;
55+ 56+ @ BeforeEach
57+ void setUp () throws JoseException {
58+ mockMvc = MockMvcBuilders .webAppContextSetup (webApplicationContext )
59+ .apply (springSecurity ())
60+ .build ();
61+ 62+ /* Инициализация WireMock сервера */
63+ wireMockServer = new WireMockServer (8089 ); // Если установить 0, то порт будет генерироваться случайный
64+ wireMockServer .start ();
65+ WireMock .configureFor ("localhost" , wireMockServer .port ());
66+ 67+ /* Генерация RSA ключа для JWT */
68+ if (rsaJsonWebKey == null ) {
69+ rsaJsonWebKey = RsaJwkGenerator .generateJwk (2048 );
70+ rsaJsonWebKey .setKeyId ("k1" );
71+ rsaJsonWebKey .setAlgorithm (AlgorithmIdentifiers .RSA_USING_SHA256 );
72+ rsaJsonWebKey .setUse ("sig" );
73+ }
74+ 75+ /* Настройка WireMock заглушки JWKS endpoint-a */
76+ stubFor (WireMock .get (urlEqualTo ("/auth/realms/test-realm/protocol/openid-connect/certs" ))
77+ .willReturn (aResponse ()
78+ .withHeader ("Content-Type" , "application/json" )
79+ .withBody (new JsonWebKeySet (rsaJsonWebKey ).toJson ())));
80+ 81+ String openidConfig = "{ " +
82+ "\" issuer\" : \" http://localhost:" + wireMockServer .port () + "/auth/realms/test-realm\" , " +
83+ "\" jwks_uri\" : \" http://localhost:" + wireMockServer .port () + "/auth/realms/test-realm/protocol/openid-connect/certs\" }" ;
84+ 85+ /* Настройка WireMock заглушки для .well-known/openid-configuration */
86+ stubFor (WireMock .get (urlEqualTo ("/auth/realms/test-realm/.well-known/openid-configuration" ))
87+ .willReturn (aResponse ()
88+ .withHeader ("Content-Type" , "application/json" )
89+ .withBody (openidConfig )));
90+ 91+ realmAccessClaimsAdmin = new HashMap <>();
92+ realmAccessClaimsAdmin .put ("roles" , List .of ("ROLE_READ" , "ROLE_ADMIN" ));
93+ 94+ realmAccessClaimsUser = new HashMap <>();
95+ realmAccessClaimsUser .put ("roles" , List .of ("ROLE_USER" ));
96+ }
97+ 98+ @ AfterEach
99+ public void tearDown () {
100+ if (wireMockServer != null ) {
101+ wireMockServer .resetAll ();
102+ wireMockServer .stop ();
103+ wireMockServer = null ;
104+ }
105+ }
106+ 107+ @ Test
108+ @ SneakyThrows
109+ void getAccountDetails_ShouldReturnOk_AndAccountRecord_CorrectJwt_Test () {
110+ /* Генерация JWT токена */
111+ String jwt = JwtTestUtils .generateJWT (EXIST_EMAIL_WITH_READ_AUTH , rsaJsonWebKey , wireMockServer , realmAccessClaimsUser );
112+ 113+ mockMvc .perform (MockMvcRequestBuilders .get ("/api/myAccount" )
114+ .header ("Authorization" , "Bearer " + jwt ))
115+ .andExpect (status ().isOk ())
116+ .andExpect (content ().contentType (MediaType .APPLICATION_JSON ))
117+ .andExpect (content ().string (containsString ("accountNumber" )))
118+ .andExpect (content ().string (containsString ("accountType" )))
119+ .andExpect (content ().string (containsString ("branchAddress" )))
120+ .andExpect (content ().string (containsString ("createDt" )));
121+ }
122+ 123+ @ Test
124+ @ SneakyThrows
125+ void getAccountDetails_ShouldReturnUnauthorized_NotCorrectJwt_Test () {
126+ /* Генерация JWT токена */
127+ String jwt = "Bad-Jwt" ;
128+ 129+ mockMvc .perform (MockMvcRequestBuilders .get ("/api/myAccount" )
130+ .header ("Authorization" , "Bearer " + jwt ))
131+ .andExpect (status ().isUnauthorized ())
132+ .andExpect (content ().string ("" ));
133+ }
134+ 135+ @ Test
136+ @ SneakyThrows
137+ void getAccountDetails_ShouldReturn_401_EmptyJwt_Test () {
138+ mockMvc .perform (get ("/api/myAccount" ))
139+ .andExpect (status ().is4xxClientError ())
140+ .andExpect (content ().string ("" ));
141+ }
142+ }
0 commit comments