This commit is contained in:
+42
-2
@@ -1,4 +1,44 @@
|
||||
package dev.ksan.etfoglasiserver.controller;
|
||||
|
||||
public class DeviceTokenControllerTest {
|
||||
}
|
||||
import dev.ksan.etfoglasiserver.model.RegisterTokenRequest;
|
||||
import dev.ksan.etfoglasiserver.service.DeviceTokenService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class DeviceTokenControllerTest {
|
||||
|
||||
@Mock
|
||||
DeviceTokenService deviceTokenService;
|
||||
|
||||
@InjectMocks
|
||||
DeviceTokenController controller;
|
||||
|
||||
@Test
|
||||
void register_savesNewToken() {
|
||||
|
||||
UserDetails principal = mock(UserDetails.class);
|
||||
when(principal.getUsername()).thenReturn("test@test.com");
|
||||
|
||||
RegisterTokenRequest req = new RegisterTokenRequest();
|
||||
req.setToken("fcm-123");
|
||||
|
||||
ResponseEntity<Void> res = controller.register(req, principal);
|
||||
|
||||
assertEquals(204, res.getStatusCode().value());
|
||||
|
||||
verify(deviceTokenService).registerToken(
|
||||
"test@test.com",
|
||||
"fcm-123"
|
||||
);
|
||||
}
|
||||
}
|
||||
+225
-2
@@ -1,4 +1,227 @@
|
||||
package dev.ksan.etfoglasiserver.controller;
|
||||
|
||||
public class UserControllerIntegrationTest {
|
||||
}
|
||||
import dev.ksan.etfoglasiserver.dto.JwtResponseDTO;
|
||||
import dev.ksan.etfoglasiserver.dto.UserCreationDTO;
|
||||
import dev.ksan.etfoglasiserver.dto.UserDTO;
|
||||
import dev.ksan.etfoglasiserver.dto.UserLoginDTO;
|
||||
import dev.ksan.etfoglasiserver.model.NotificationMethod;
|
||||
import dev.ksan.etfoglasiserver.model.User;
|
||||
import dev.ksan.etfoglasiserver.repository.UserRepo;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@Import(UserController.class)
|
||||
class UserControllerIntegrationTest {
|
||||
|
||||
@Autowired TestRestTemplate restTemplate;
|
||||
@Autowired UserRepo userRepo;
|
||||
@Autowired
|
||||
PasswordEncoder passwordEncoder;
|
||||
|
||||
private String token;
|
||||
private User testUser;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
userRepo.deleteAll();
|
||||
|
||||
testUser = new User();
|
||||
testUser.setEmail("test@test.com");
|
||||
testUser.setPassword(passwordEncoder.encode("password"));
|
||||
testUser.setNotificationMethod(NotificationMethod.PUSH_NOTIFICATION);
|
||||
userRepo.save(testUser);
|
||||
|
||||
ResponseEntity<JwtResponseDTO> res = restTemplate.postForEntity(
|
||||
"/api/login",
|
||||
new UserLoginDTO("test@test.com", "password"),
|
||||
JwtResponseDTO.class
|
||||
);
|
||||
token = res.getBody().getToken();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void login_returnsToken_withValidCredentials() {
|
||||
ResponseEntity<JwtResponseDTO> res = restTemplate.postForEntity(
|
||||
"/api/login",
|
||||
new UserLoginDTO("test@test.com", "password"),
|
||||
JwtResponseDTO.class
|
||||
);
|
||||
|
||||
assertEquals(200, res.getStatusCode().value());
|
||||
assertNotNull(res.getBody().getToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
void login_returns400_withWrongPassword() {
|
||||
ResponseEntity<?> res = restTemplate.postForEntity(
|
||||
"/api/login",
|
||||
new UserLoginDTO("test@test.com", "wrongpassword"),
|
||||
Object.class
|
||||
);
|
||||
|
||||
assertEquals(400, res.getStatusCode().value());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void register_createsUser_andReturns201() {
|
||||
ResponseEntity<UserDTO> res = restTemplate.postForEntity(
|
||||
"/api/register",
|
||||
new UserCreationDTO("new@test.com", "password123"),
|
||||
UserDTO.class
|
||||
);
|
||||
|
||||
assertEquals(201, res.getStatusCode().value());
|
||||
assertNotNull(res.getBody());
|
||||
assertEquals("new@test.com", res.getBody().getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
void register_returns400_withInvalidData() {
|
||||
ResponseEntity<?> res = restTemplate.postForEntity(
|
||||
"/api/register",
|
||||
new UserCreationDTO("", ""),
|
||||
Object.class
|
||||
);
|
||||
|
||||
assertEquals(400, res.getStatusCode().value());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void getMe_returnsUser_withValidToken() {
|
||||
ResponseEntity<UserDTO> res = restTemplate.exchange(
|
||||
"/api/users/me",
|
||||
HttpMethod.GET,
|
||||
withAuth(null),
|
||||
UserDTO.class
|
||||
);
|
||||
|
||||
assertEquals(200, res.getStatusCode().value());
|
||||
assertEquals("test@test.com", res.getBody().getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMe_returns401_withoutToken() {
|
||||
ResponseEntity<?> res = restTemplate.getForEntity("/api/users/me", Object.class);
|
||||
assertEquals(401, res.getStatusCode().value());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void updateUser_updatesEmail() {
|
||||
UserCreationDTO update = new UserCreationDTO("updated@test.com", null);
|
||||
|
||||
ResponseEntity<UserDTO> res = restTemplate.exchange(
|
||||
"/api/users/me",
|
||||
HttpMethod.PUT,
|
||||
withAuth(update),
|
||||
UserDTO.class
|
||||
);
|
||||
|
||||
assertEquals(200, res.getStatusCode().value());
|
||||
assertEquals("updated@test.com", res.getBody().getEmail());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateUser_returns401_withoutToken() {
|
||||
ResponseEntity<?> res = restTemplate.exchange(
|
||||
"/api/users/me",
|
||||
HttpMethod.PUT,
|
||||
new HttpEntity<>(new UserCreationDTO("x@x.com", null)),
|
||||
Object.class
|
||||
);
|
||||
|
||||
assertEquals(401, res.getStatusCode().value());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void updateNotificationType_setsNoNotification() {
|
||||
ResponseEntity<?> res = restTemplate.exchange(
|
||||
"/api/users/me/notification-type",
|
||||
HttpMethod.POST,
|
||||
withAuth(Map.of("notificationType", "NO_NOTIFICATION")),
|
||||
Object.class
|
||||
);
|
||||
|
||||
assertEquals(200, res.getStatusCode().value());
|
||||
|
||||
User updated = userRepo.findByEmail("test@test.com").get();
|
||||
assertEquals(NotificationMethod.NO_NOTIFICATION, updated.getNotificationMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateNotificationType_setsPushNotification() {
|
||||
// set to push first
|
||||
testUser.setNotificationMethod(NotificationMethod.PUSH_NOTIFICATION);
|
||||
userRepo.save(testUser);
|
||||
|
||||
restTemplate.exchange(
|
||||
"/api/users/me/notification-type",
|
||||
HttpMethod.POST,
|
||||
withAuth(Map.of("notificationType", "PUSH_NOTIFICATION")),
|
||||
Object.class
|
||||
);
|
||||
|
||||
User updated = userRepo.findByEmail("test@test.com").get();
|
||||
assertEquals(NotificationMethod.PUSH_NOTIFICATION, updated.getNotificationMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateNotificationType_returns401_withoutToken() {
|
||||
ResponseEntity<?> res = restTemplate.postForEntity(
|
||||
"/api/users/me/notification-type",
|
||||
Map.of("notificationType", "NO_NOTIFICATION"),
|
||||
Object.class
|
||||
);
|
||||
|
||||
assertEquals(401, res.getStatusCode().value());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void deleteUser_returns204_andRemovesUser() {
|
||||
ResponseEntity<Void> res = restTemplate.exchange(
|
||||
"/api/users/me",
|
||||
HttpMethod.DELETE,
|
||||
withAuth(null),
|
||||
Void.class
|
||||
);
|
||||
|
||||
assertEquals(204, res.getStatusCode().value());
|
||||
assertTrue(userRepo.findByEmail("test@test.com").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteUser_returns401_withoutToken() {
|
||||
ResponseEntity<?> res = restTemplate.exchange(
|
||||
"/api/users/me",
|
||||
HttpMethod.DELETE,
|
||||
HttpEntity.EMPTY,
|
||||
Object.class
|
||||
);
|
||||
|
||||
assertEquals(401, res.getStatusCode().value());
|
||||
}
|
||||
|
||||
|
||||
private <T> HttpEntity<T> withAuth(T body) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBearerAuth(token);
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
return new HttpEntity<>(body, headers);
|
||||
}
|
||||
}
|
||||
+71
-2
@@ -1,4 +1,73 @@
|
||||
package dev.ksan.etfoglasiserver.service;
|
||||
|
||||
public class NotificationServiceTest {
|
||||
}
|
||||
import com.google.firebase.messaging.FirebaseMessaging;
|
||||
import com.google.firebase.messaging.FirebaseMessagingException;
|
||||
import com.google.firebase.messaging.Message;
|
||||
import com.google.firebase.messaging.MessagingErrorCode;
|
||||
import dev.ksan.etfoglasiserver.model.DeviceToken;
|
||||
import dev.ksan.etfoglasiserver.model.User;
|
||||
import dev.ksan.etfoglasiserver.repository.DeviceTokenRepo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class NotificationServiceTest {
|
||||
|
||||
@Mock
|
||||
DeviceTokenRepo deviceTokenRepo;
|
||||
@Mock
|
||||
FirebaseMessaging firebaseMessaging;
|
||||
@InjectMocks
|
||||
NotificationService notificationService;
|
||||
|
||||
@Test
|
||||
void sendToUser_sendsMessageForEachToken() throws FirebaseMessagingException {
|
||||
User user = new User();
|
||||
DeviceToken t1 = new DeviceToken(); t1.setFcmToken("token-1");
|
||||
DeviceToken t2 = new DeviceToken(); t2.setFcmToken("token-2");
|
||||
|
||||
when(deviceTokenRepo.findByUserId(user.getId()))
|
||||
.thenReturn(List.of(t1, t2));
|
||||
when(firebaseMessaging.send(any())).thenReturn("msg-id");
|
||||
|
||||
notificationService.sendToUser(user, "Hello", "World");
|
||||
|
||||
verify(firebaseMessaging, times(2)).send(any(Message.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendToUser_deletesStaleToken_whenUnregistered() throws FirebaseMessagingException {
|
||||
User user = new User();
|
||||
DeviceToken token = new DeviceToken();
|
||||
token.setFcmToken("stale-token");
|
||||
|
||||
when(deviceTokenRepo.findByUserId(user.getId()))
|
||||
.thenReturn(List.of(token));
|
||||
|
||||
FirebaseMessagingException ex = mock(FirebaseMessagingException.class);
|
||||
when(ex.getMessagingErrorCode()).thenReturn(MessagingErrorCode.UNREGISTERED);
|
||||
when(firebaseMessaging.send(any())).thenThrow(ex);
|
||||
|
||||
notificationService.sendToUser(user, "Hello", "World");
|
||||
|
||||
verify(deviceTokenRepo).delete(token);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendToUser_doesNothing_whenUserHasNoTokens() throws FirebaseMessagingException {
|
||||
User user = new User();
|
||||
when(deviceTokenRepo.findByUserId(user.getId())).thenReturn(List.of());
|
||||
|
||||
notificationService.sendToUser(user, "Hello", "World");
|
||||
|
||||
verify(firebaseMessaging, never()).send(any());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user