test: add UserSettingServiceTest unit test
This commit is contained in:
parent
def12a1bdb
commit
818aa27eb1
@ -0,0 +1,202 @@
|
|||||||
|
package com.walkguide.service;
|
||||||
|
|
||||||
|
import com.walkguide.dto.request.UserSettingsUpdateRequest;
|
||||||
|
import com.walkguide.dto.response.UserSettingsResponse;
|
||||||
|
import com.walkguide.entity.UserSettings;
|
||||||
|
import com.walkguide.repository.UserSettingsRepository;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
@DisplayName("UserSettingsService Unit Tests")
|
||||||
|
class UserSettingsServiceTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
UserSettingsRepository userSettingsRepository;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
UserSettingsService userSettingsService;
|
||||||
|
|
||||||
|
private UserSettings existingSettings;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
existingSettings = UserSettings.builder()
|
||||||
|
.id(1L)
|
||||||
|
.userId(10L)
|
||||||
|
.ttsLanguage("id-ID")
|
||||||
|
.ttsPitch(1.0)
|
||||||
|
.ttsSpeed(0.9)
|
||||||
|
.warnNoGuardian(true)
|
||||||
|
.hapticEnabled(true)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== getSettings TESTS =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getSettings - harus return settings yang ada di DB")
|
||||||
|
void getSettings_existingSettings_shouldReturnExistingData() {
|
||||||
|
when(userSettingsRepository.findByUserId(10L)).thenReturn(Optional.of(existingSettings));
|
||||||
|
|
||||||
|
UserSettingsResponse result = userSettingsService.getSettings(10L);
|
||||||
|
|
||||||
|
assertThat(result).isNotNull();
|
||||||
|
assertThat(result.getId()).isEqualTo(1L);
|
||||||
|
assertThat(result.getTtsLanguage()).isEqualTo("id-ID");
|
||||||
|
assertThat(result.getTtsPitch()).isEqualTo(1.0);
|
||||||
|
assertThat(result.getTtsSpeed()).isEqualTo(0.9);
|
||||||
|
assertThat(result.getWarnNoGuardian()).isTrue();
|
||||||
|
assertThat(result.getHapticEnabled()).isTrue();
|
||||||
|
|
||||||
|
// Tidak boleh membuat settings baru jika sudah ada
|
||||||
|
verify(userSettingsRepository, never()).save(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getSettings - jika belum ada, harus auto-create settings default dan simpan ke DB")
|
||||||
|
void getSettings_noExistingSettings_shouldCreateDefaultAndSave() {
|
||||||
|
UserSettings defaultSettings = UserSettings.builder()
|
||||||
|
.id(2L).userId(20L)
|
||||||
|
.ttsLanguage("id-ID").ttsPitch(1.0).ttsSpeed(0.9)
|
||||||
|
.warnNoGuardian(true).hapticEnabled(true).build();
|
||||||
|
|
||||||
|
when(userSettingsRepository.findByUserId(20L)).thenReturn(Optional.empty());
|
||||||
|
when(userSettingsRepository.save(any(UserSettings.class))).thenReturn(defaultSettings);
|
||||||
|
|
||||||
|
UserSettingsResponse result = userSettingsService.getSettings(20L);
|
||||||
|
|
||||||
|
assertThat(result).isNotNull();
|
||||||
|
verify(userSettingsRepository).save(any(UserSettings.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getSettings - settings yang di-auto-create harus memiliki userId yang benar")
|
||||||
|
void getSettings_autoCreate_shouldHaveCorrectUserId() {
|
||||||
|
when(userSettingsRepository.findByUserId(30L)).thenReturn(Optional.empty());
|
||||||
|
when(userSettingsRepository.save(any(UserSettings.class)))
|
||||||
|
.thenAnswer(inv -> inv.getArgument(0));
|
||||||
|
|
||||||
|
userSettingsService.getSettings(30L);
|
||||||
|
|
||||||
|
ArgumentCaptor<UserSettings> captor = ArgumentCaptor.forClass(UserSettings.class);
|
||||||
|
verify(userSettingsRepository).save(captor.capture());
|
||||||
|
assertThat(captor.getValue().getUserId()).isEqualTo(30L);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== updateSettings TESTS =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("updateSettings - semua field diisi harus mengupdate semua nilai")
|
||||||
|
void updateSettings_allFields_shouldUpdateAllValues() {
|
||||||
|
UserSettingsUpdateRequest req = new UserSettingsUpdateRequest();
|
||||||
|
req.setTtsLanguage("en-US");
|
||||||
|
req.setTtsPitch(1.5);
|
||||||
|
req.setTtsSpeed(1.2);
|
||||||
|
req.setWarnNoGuardian(false);
|
||||||
|
req.setHapticEnabled(false);
|
||||||
|
|
||||||
|
when(userSettingsRepository.findByUserId(10L)).thenReturn(Optional.of(existingSettings));
|
||||||
|
when(userSettingsRepository.save(any(UserSettings.class)))
|
||||||
|
.thenAnswer(inv -> inv.getArgument(0));
|
||||||
|
|
||||||
|
UserSettingsResponse result = userSettingsService.updateSettings(10L, req);
|
||||||
|
|
||||||
|
assertThat(result.getTtsLanguage()).isEqualTo("en-US");
|
||||||
|
assertThat(result.getTtsPitch()).isEqualTo(1.5);
|
||||||
|
assertThat(result.getTtsSpeed()).isEqualTo(1.2);
|
||||||
|
assertThat(result.getWarnNoGuardian()).isFalse();
|
||||||
|
assertThat(result.getHapticEnabled()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("updateSettings - field null tidak boleh mengubah nilai yang sudah ada (partial update)")
|
||||||
|
void updateSettings_partialUpdate_nullFieldsShouldNotOverride() {
|
||||||
|
UserSettingsUpdateRequest req = new UserSettingsUpdateRequest();
|
||||||
|
req.setTtsLanguage("en-US"); // hanya ini yang diubah
|
||||||
|
req.setTtsPitch(null);
|
||||||
|
req.setTtsSpeed(null);
|
||||||
|
req.setWarnNoGuardian(null);
|
||||||
|
req.setHapticEnabled(null);
|
||||||
|
|
||||||
|
when(userSettingsRepository.findByUserId(10L)).thenReturn(Optional.of(existingSettings));
|
||||||
|
when(userSettingsRepository.save(any(UserSettings.class)))
|
||||||
|
.thenAnswer(inv -> inv.getArgument(0));
|
||||||
|
|
||||||
|
UserSettingsResponse result = userSettingsService.updateSettings(10L, req);
|
||||||
|
|
||||||
|
assertThat(result.getTtsLanguage()).isEqualTo("en-US");
|
||||||
|
// Nilai lama harus tetap
|
||||||
|
assertThat(result.getTtsPitch()).isEqualTo(1.0);
|
||||||
|
assertThat(result.getTtsSpeed()).isEqualTo(0.9);
|
||||||
|
assertThat(result.getWarnNoGuardian()).isTrue();
|
||||||
|
assertThat(result.getHapticEnabled()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("updateSettings - jika belum ada settings, harus buat baru dan update")
|
||||||
|
void updateSettings_noExistingSettings_shouldCreateNewAndUpdate() {
|
||||||
|
UserSettingsUpdateRequest req = new UserSettingsUpdateRequest();
|
||||||
|
req.setTtsLanguage("ja-JP");
|
||||||
|
req.setHapticEnabled(false);
|
||||||
|
|
||||||
|
when(userSettingsRepository.findByUserId(40L)).thenReturn(Optional.empty());
|
||||||
|
when(userSettingsRepository.save(any(UserSettings.class)))
|
||||||
|
.thenAnswer(inv -> inv.getArgument(0));
|
||||||
|
|
||||||
|
UserSettingsResponse result = userSettingsService.updateSettings(40L, req);
|
||||||
|
|
||||||
|
ArgumentCaptor<UserSettings> captor = ArgumentCaptor.forClass(UserSettings.class);
|
||||||
|
verify(userSettingsRepository).save(captor.capture());
|
||||||
|
|
||||||
|
assertThat(captor.getValue().getUserId()).isEqualTo(40L);
|
||||||
|
assertThat(captor.getValue().getTtsLanguage()).isEqualTo("ja-JP");
|
||||||
|
assertThat(captor.getValue().getHapticEnabled()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("updateSettings - harus memanggil repository.save dan return hasil yang diupdate")
|
||||||
|
void updateSettings_shouldPersistAndReturnUpdatedResponse() {
|
||||||
|
UserSettingsUpdateRequest req = new UserSettingsUpdateRequest();
|
||||||
|
req.setTtsSpeed(0.5);
|
||||||
|
|
||||||
|
when(userSettingsRepository.findByUserId(10L)).thenReturn(Optional.of(existingSettings));
|
||||||
|
when(userSettingsRepository.save(any(UserSettings.class)))
|
||||||
|
.thenAnswer(inv -> inv.getArgument(0));
|
||||||
|
|
||||||
|
userSettingsService.updateSettings(10L, req);
|
||||||
|
|
||||||
|
verify(userSettingsRepository, times(1)).save(any(UserSettings.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("updateSettings - semua field null harus tidak mengubah apapun")
|
||||||
|
void updateSettings_allNull_shouldNotChangeAnything() {
|
||||||
|
UserSettingsUpdateRequest req = new UserSettingsUpdateRequest();
|
||||||
|
// semua null
|
||||||
|
|
||||||
|
when(userSettingsRepository.findByUserId(10L)).thenReturn(Optional.of(existingSettings));
|
||||||
|
when(userSettingsRepository.save(any(UserSettings.class)))
|
||||||
|
.thenAnswer(inv -> inv.getArgument(0));
|
||||||
|
|
||||||
|
UserSettingsResponse result = userSettingsService.updateSettings(10L, req);
|
||||||
|
|
||||||
|
assertThat(result.getTtsLanguage()).isEqualTo("id-ID");
|
||||||
|
assertThat(result.getTtsPitch()).isEqualTo(1.0);
|
||||||
|
assertThat(result.getTtsSpeed()).isEqualTo(0.9);
|
||||||
|
assertThat(result.getWarnNoGuardian()).isTrue();
|
||||||
|
assertThat(result.getHapticEnabled()).isTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user