Skip to content

Commit c2034f0

Browse files
committed
#178: add tests for save times
1 parent 0e6a284 commit c2034f0

File tree

2 files changed

+114
-14
lines changed

2 files changed

+114
-14
lines changed

src/main/java/de/doubleslash/keeptime/controller/HeimatController.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -228,16 +228,7 @@ public List<HeimatErrors> saveDay(final List<UserMapping> items, LocalDate date)
228228
List<HeimatErrors> errors = new ArrayList<>();
229229

230230
items.stream().filter(tr -> tr.shouldSync).forEach(item -> {
231-
if (item.userNotes.isEmpty()) {
232-
errors.add(new HeimatErrors(item, "No notes were given"));
233-
return;
234-
}
235231
final int durationInMinutes = item.userMinutes;
236-
if (durationInMinutes <= 0 || durationInMinutes % 15 != 0) {
237-
errors.add(new HeimatErrors(item, "Duration '" + durationInMinutes + "' is not valid for project"));
238-
return;
239-
}
240-
241232
final HeimatTime heimatTime = new HeimatTime(item.mapping.heimatTaskId, date, null, null, durationInMinutes,
242233
item.userNotes, 0L);
243234

src/test/java/de/doubleslash/keeptime/controller/HeimatControllerTest.java

Lines changed: 114 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.junit.jupiter.api.BeforeEach;
1515
import org.junit.jupiter.api.Test;
1616
import org.mockito.ArgumentCaptor;
17+
import org.mockito.InOrder;
1718
import org.mockito.Mockito;
1819

1920
import java.time.LocalDate;
@@ -24,7 +25,7 @@
2425

2526
import static org.hamcrest.MatcherAssert.assertThat;
2627
import static org.junit.jupiter.api.Assertions.*;
27-
import static org.mockito.Mockito.when;
28+
import static org.mockito.Mockito.*;
2829

2930
class HeimatControllerTest {
3031

@@ -355,10 +356,118 @@ void shouldGenerateLinkForDay() {
355356
final String urlForDay = heimatController.getUrlForDay(LocalDate.of(1999, 4, 2));
356357
assertThat(urlForDay, Matchers.is("https://doubleslash.de/core/heimat/time/main/day/1999/4/2"));
357358
}
358-
// Save
359-
// shouldSaveTimes
360-
// shouldDeleteExistingTimesBeforeSavingWhenTimesAlreadyExist
361-
// shouldContinueOnErrorAndReturnErrorsWhenErrorsOccurred
359+
360+
/* Save */
361+
@Test
362+
void shouldSaveTimes() {
363+
// ARRANGE
364+
workItems.add(new Work(now.minusMinutes(13), now, workProject1, "Notes 1"));
365+
externalMappings.add(project1To1Mapping);
366+
final List<HeimatController.Mapping> tableRows = heimatController.getTableRows(now.toLocalDate(), workItems);
367+
final HeimatController.Mapping mapping = tableRows.get(0);
368+
369+
// ACT
370+
final String userNote = "User entered note";
371+
final int userMinutes = 15;
372+
final List<HeimatController.HeimatErrors> errors = heimatController.saveDay(
373+
List.of(new HeimatController.UserMapping(mapping, true, userNote, userMinutes)), now.toLocalDate());
374+
375+
// ASSERT
376+
ArgumentCaptor<HeimatTime> saveMappingsCaptor = ArgumentCaptor.forClass(HeimatTime.class);
377+
Mockito.verify(mockedHeimatAPI).addMyTime(saveMappingsCaptor.capture());
378+
assertAll( //
379+
() -> assertThat(errors, Matchers.empty()) //
380+
, () -> assertThat(saveMappingsCaptor.getValue().taskId(),
381+
Matchers.is(project1To1Mapping.getExternalTaskId())) //
382+
, () -> assertThat(saveMappingsCaptor.getValue().note(), Matchers.is(userNote)) //
383+
, () -> assertThat(saveMappingsCaptor.getValue().durationInMinutes(), Matchers.is(userMinutes)) //
384+
);
385+
}
386+
387+
@Test
388+
void shouldNotSaveTimeWhenUserDoesNotWantToSync() {
389+
// ARRANGE
390+
workItems.add(new Work(now.minusMinutes(13), now, workProject1, "Notes 1"));
391+
externalMappings.add(project1To1Mapping);
392+
final List<HeimatController.Mapping> tableRows = heimatController.getTableRows(now.toLocalDate(), workItems);
393+
final HeimatController.Mapping mapping = tableRows.get(0);
394+
395+
// ACT
396+
final String userNote = "User entered note";
397+
final int userMinutes = 15;
398+
final boolean shouldSync = false;
399+
heimatController.saveDay(List.of(new HeimatController.UserMapping(mapping, shouldSync, userNote, userMinutes)),
400+
now.toLocalDate());
401+
402+
// ASSERT
403+
Mockito.verify(mockedHeimatAPI, Mockito.never()).addMyTime(any(HeimatTime.class));
404+
}
405+
406+
@Test
407+
void shouldDeleteExistingTimesBeforeSavingWhenTimesAlreadyExist() {
408+
// updating existing times is not supported. therefore, we delete existing and create new.
409+
// ARRANGE
410+
workItems.add(new Work(now.minusMinutes(13), now, workProject1, "Notes 1"));
411+
externalMappings.add(project1To1Mapping);
412+
413+
final HeimatTime existingTime1 = new HeimatTime(project1To1Mapping.getExternalTaskId(), now.toLocalDate(), null,
414+
null, 60, "Existing note 1", 12);
415+
final HeimatTime existingTime2 = new HeimatTime(project1To1Mapping.getExternalTaskId(), now.toLocalDate(), null,
416+
null, 30, "Existing note 2", 13);
417+
when(mockedHeimatAPI.getMyTimes(now.toLocalDate())).thenReturn(Arrays.asList(existingTime1, existingTime2));
418+
419+
final List<HeimatController.Mapping> tableRows = heimatController.getTableRows(now.toLocalDate(), workItems);
420+
final HeimatController.Mapping mapping = tableRows.get(0);
421+
422+
// ACT
423+
final String userNote = "User entered note";
424+
final int userMinutes = 15;
425+
final List<HeimatController.HeimatErrors> errors = heimatController.saveDay(
426+
List.of(new HeimatController.UserMapping(mapping, true, userNote, userMinutes)), now.toLocalDate());
427+
428+
// ASSERT
429+
InOrder inOrder = inOrder(mockedHeimatAPI);
430+
inOrder.verify(mockedHeimatAPI).deleteMyTime(existingTime1.id());
431+
inOrder.verify(mockedHeimatAPI).deleteMyTime(existingTime2.id());
432+
433+
ArgumentCaptor<HeimatTime> saveMappingsCaptor = ArgumentCaptor.forClass(HeimatTime.class);
434+
inOrder.verify(mockedHeimatAPI).addMyTime(saveMappingsCaptor.capture());
435+
assertAll( //
436+
() -> assertThat(errors, Matchers.empty()) //
437+
, () -> assertThat(saveMappingsCaptor.getValue().taskId(),
438+
Matchers.is(project1To1Mapping.getExternalTaskId())) //
439+
, () -> assertThat(saveMappingsCaptor.getValue().note(), Matchers.is(userNote)) //
440+
, () -> assertThat(saveMappingsCaptor.getValue().durationInMinutes(), Matchers.is(userMinutes)) //
441+
);
442+
}
443+
444+
@Test
445+
void shouldReturnErrorsWhenErrorsOccurred() {
446+
// ARRANGE
447+
workItems.add(new Work(now.minusMinutes(13), now, workProject1, "Notes 1"));
448+
externalMappings.add(project1To1Mapping);
449+
final List<HeimatController.Mapping> tableRows = heimatController.getTableRows(now.toLocalDate(), workItems);
450+
final HeimatController.Mapping mapping = tableRows.get(0);
451+
final String exceptionMessage = "SomethingDidNotWork";
452+
doThrow(new RuntimeException(exceptionMessage)).when(mockedHeimatAPI).addMyTime(any(HeimatTime.class));
453+
454+
// ACT
455+
final String userNote = "User entered note";
456+
final int userMinutes = 15;
457+
final HeimatController.UserMapping userMapping = new HeimatController.UserMapping(mapping, true, userNote,
458+
userMinutes);
459+
final List<HeimatController.HeimatErrors> errors = heimatController.saveDay(List.of(userMapping),
460+
now.toLocalDate());
461+
462+
// ASSERT
463+
ArgumentCaptor<HeimatTime> saveMappingsCaptor = ArgumentCaptor.forClass(HeimatTime.class);
464+
Mockito.verify(mockedHeimatAPI).addMyTime(saveMappingsCaptor.capture());
465+
assertAll( //
466+
() -> assertThat(errors, Matchers.hasSize(1)) //
467+
, () -> assertThat(errors.get(0).errorMessage(), Matchers.containsString(exceptionMessage)) //
468+
, () -> assertThat(errors.get(0).mapping(), Matchers.is(userMapping)) //
469+
);
470+
}
362471
// shouldOnlyUpdateHeimatWhenSomethingHasChanged (not needed - user should decide)
363472

364473
}

0 commit comments

Comments
 (0)