Skip to content

Commit d094fd3

Browse files
committed
feat: AuthControllerTest
1 parent f2ffe74 commit d094fd3

8 files changed

Lines changed: 189 additions & 22 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.syncapi;
2+
3+
import org.springframework.http.MediaType;
4+
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
5+
import tools.jackson.core.JacksonException;
6+
import tools.jackson.databind.ObjectMapper;
7+
8+
import java.util.UUID;
9+
10+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
11+
12+
public class TestUtil {
13+
public static String generateRandomEmail() {
14+
return "user-" + UUID.randomUUID() + "@example.com";
15+
}
16+
17+
public static String generateRandomName() {
18+
return "name-" + UUID.randomUUID();
19+
}
20+
21+
public static String generateRandomPasswordHash() {
22+
return "hash-" + UUID.randomUUID();
23+
}
24+
25+
public static String generateRandomPassword() {
26+
return "pass-" + UUID.randomUUID();
27+
}
28+
29+
public static String toJson(Object object) {
30+
try {
31+
return new ObjectMapper().writeValueAsString(object);
32+
} catch (JacksonException e) {
33+
throw new RuntimeException("Failed to serialize object to JSON", e);
34+
}
35+
}
36+
37+
public static <T> T fromJson(String json, Class<T> clazz) {
38+
try {
39+
return new ObjectMapper().readValue(json, clazz);
40+
} catch (JacksonException e) {
41+
throw new RuntimeException("Failed to deserialize JSON to object", e);
42+
}
43+
}
44+
45+
public static MockHttpServletRequestBuilder postJson(String url, Object body) {
46+
return post(url)
47+
.characterEncoding("UTF-8")
48+
.content(toJson(body))
49+
.contentType(MediaType.APPLICATION_JSON);
50+
}
51+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package com.syncapi.controller.auth;
2+
3+
import com.syncapi.AbstractIntegrationTest;
4+
import com.syncapi.dto.auth.LoginRequest;
5+
import com.syncapi.dto.auth.RegisterRequest;
6+
import com.syncapi.entity.User;
7+
import com.syncapi.repository.UserRepository;
8+
import org.junit.jupiter.api.BeforeEach;
9+
import org.junit.jupiter.api.Test;
10+
import org.junit.jupiter.params.ParameterizedTest;
11+
import org.junit.jupiter.params.provider.MethodSource;
12+
import org.springframework.beans.factory.annotation.Autowired;
13+
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
14+
import org.springframework.http.MediaType;
15+
import org.springframework.test.web.servlet.MockMvc;
16+
import org.springframework.test.web.servlet.ResultActions;
17+
18+
import java.util.stream.Stream;
19+
20+
import static com.syncapi.TestUtil.*;
21+
import static org.assertj.core.api.Assertions.assertThat;
22+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
23+
24+
@AutoConfigureMockMvc
25+
class AuthControllerTest extends AbstractIntegrationTest {
26+
private static final String AUTH_URL = "/api/auth";
27+
28+
@Autowired
29+
private MockMvc mockMvc;
30+
31+
@Autowired
32+
private UserRepository userRepository;
33+
34+
@BeforeEach
35+
void setUp() {
36+
userRepository.deleteAll();
37+
}
38+
39+
@Test
40+
void shouldRegisterNewUser() throws Exception {
41+
// given
42+
String name = generateRandomName();
43+
String email = generateRandomEmail();
44+
RegisterRequest request = new RegisterRequest(name, email, generateRandomPassword());
45+
46+
// when
47+
ResultActions res = mockMvc.perform(postJson(AUTH_URL + "/register", request));
48+
49+
// then
50+
res.andExpect(status().isOk())
51+
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
52+
.andExpect(jsonPath("$.token").isString())
53+
.andExpect(jsonPath("$.token").isNotEmpty())
54+
.andExpect(jsonPath("$.email").value(email))
55+
.andExpect(jsonPath("$.name").value(name));
56+
57+
User user = userRepository.findByEmail(email).orElseThrow();
58+
assertThat(user.getName()).isEqualTo(name);
59+
assertThat(user.getPasswordHash()).isNotBlank();
60+
}
61+
62+
@Test
63+
void shouldFailWhenEmailAlreadyExists() throws Exception {
64+
// given
65+
String email = generateRandomEmail();
66+
RegisterRequest first = new RegisterRequest(generateRandomName(), email, generateRandomPassword());
67+
RegisterRequest second = new RegisterRequest(generateRandomName(), email, generateRandomPassword());
68+
69+
// when / then
70+
mockMvc.perform(postJson(AUTH_URL + "/register", first))
71+
.andExpect(status().isOk());
72+
mockMvc.perform(postJson(AUTH_URL + "/register", second))
73+
.andExpect(status().isBadRequest());
74+
}
75+
76+
@ParameterizedTest(name = "[{index}] invalid register request -> 400")
77+
@MethodSource("invalidRegisterRequests")
78+
void shouldFailValidationForInvalidRegisterRequest(RegisterRequest request) throws Exception {
79+
// when / then
80+
mockMvc.perform(postJson(AUTH_URL + "/register", request))
81+
.andExpect(status().isBadRequest());
82+
}
83+
84+
private static Stream<RegisterRequest> invalidRegisterRequests() {
85+
return Stream.of(
86+
new RegisterRequest("", generateRandomEmail(), generateRandomPassword()), // blank name
87+
new RegisterRequest(null, generateRandomEmail(), generateRandomPassword()), // null name
88+
new RegisterRequest("John", "not-an-email", generateRandomPassword()), // invalid email
89+
new RegisterRequest("John", "", generateRandomPassword()), // blank email
90+
new RegisterRequest("John", generateRandomEmail(), "123") // short password
91+
);
92+
}
93+
94+
@Test
95+
void shouldLoginSuccessfully() throws Exception {
96+
// given
97+
String email = generateRandomEmail();
98+
String password = generateRandomPassword();
99+
RegisterRequest register = new RegisterRequest("Login User", email, password);
100+
101+
mockMvc.perform(postJson(AUTH_URL + "/register", register))
102+
.andExpect(status().isOk());
103+
104+
LoginRequest login = new LoginRequest(email, password);
105+
106+
// when
107+
ResultActions res = mockMvc.perform(postJson(AUTH_URL + "/login", login));
108+
109+
// then
110+
res.andExpect(status().isOk())
111+
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
112+
.andExpect(jsonPath("$.token").isString())
113+
.andExpect(jsonPath("$.token").isNotEmpty())
114+
.andExpect(jsonPath("$.email").value(email));
115+
}
116+
117+
@ParameterizedTest(name = "[{index}] invalid login -> 400")
118+
@MethodSource("invalidLoginRequests")
119+
void shouldFailLoginForInvalidCredentials(LoginRequest request) throws Exception {
120+
// when / then
121+
mockMvc.perform(postJson(AUTH_URL + "/login", request))
122+
.andExpect(status().isBadRequest());
123+
}
124+
125+
private static Stream<LoginRequest> invalidLoginRequests() {
126+
return Stream.of(
127+
new LoginRequest("not-an-email", "password"), // invalid email
128+
new LoginRequest("", "password"), // blank email
129+
new LoginRequest(generateRandomEmail(), ""), // blank password
130+
new LoginRequest(generateRandomEmail(), "wrong-password") // wrong password
131+
);
132+
}
133+
}

‎src/test/java/com/syncapi/repository/EnvironmentRepositoryTest.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import java.util.List;
1313
import java.util.Optional;
1414

15-
import static com.syncapi.repository.RepositoryTestUtil.*;
15+
import static com.syncapi.TestUtil.*;
1616
import static org.assertj.core.api.Assertions.assertThat;
1717

1818
public class EnvironmentRepositoryTest extends AbstractIntegrationTest {

‎src/test/java/com/syncapi/repository/FolderRepositoryTest.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import java.util.List;
1212

13-
import static com.syncapi.repository.RepositoryTestUtil.*;
13+
import static com.syncapi.TestUtil.*;
1414
import static org.assertj.core.api.Assertions.assertThat;
1515

1616
class FolderRepositoryTest extends AbstractIntegrationTest {

‎src/test/java/com/syncapi/repository/RepositoryTestUtil.java‎

Lines changed: 0 additions & 17 deletions
This file was deleted.

‎src/test/java/com/syncapi/repository/RequestRepositoryTest.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import java.util.List;
1515
import java.util.Map;
1616

17-
import static com.syncapi.repository.RepositoryTestUtil.*;
17+
import static com.syncapi.TestUtil.*;
1818
import static org.assertj.core.api.Assertions.assertThat;
1919

2020
class RequestRepositoryTest extends AbstractIntegrationTest {

‎src/test/java/com/syncapi/repository/UserRepositoryTest.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import java.util.Optional;
1010

11-
import static com.syncapi.repository.RepositoryTestUtil.*;
11+
import static com.syncapi.TestUtil.*;
1212
import static org.assertj.core.api.Assertions.assertThat;
1313
import static org.junit.jupiter.api.Assertions.assertThrows;
1414

‎src/test/java/com/syncapi/repository/WorkspaceRepositoryTest.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import java.util.List;
1212

13-
import static com.syncapi.repository.RepositoryTestUtil.*;
13+
import static com.syncapi.TestUtil.*;
1414
import static org.assertj.core.api.Assertions.assertThat;
1515

1616
class WorkspaceRepositoryTest extends AbstractIntegrationTest {

0 commit comments

Comments
 (0)