test: add UserSettingServiceTest unit test

This commit is contained in:
5803024019 2026-05-15 22:14:05 +07:00
parent def12a1bdb
commit 818aa27eb1

View File

@ -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();
}
}