/**
* ***************************************************************************
* Copyright (c) 2010 Qcadoo Limited
* Project: Qcadoo MES
* Version: 1.4
*
* This file is part of Qcadoo.
*
* Qcadoo is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation; either version 3 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* ***************************************************************************
*/
package com.qcadoo.mes.assignmentToShift.hooks;
import static com.qcadoo.testing.model.EntityTestUtils.mockEntity;
import static com.qcadoo.testing.model.EntityTestUtils.stubBelongsToField;
import static com.qcadoo.testing.model.EntityTestUtils.stubDateField;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.refEq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.util.Date;
import java.util.List;
import org.joda.time.LocalDate;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.test.util.ReflectionTestUtils;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.qcadoo.mes.assignmentToShift.constants.AssignmentToShiftFields;
import com.qcadoo.mes.assignmentToShift.dataProviders.AssignmentToShiftCriteria;
import com.qcadoo.mes.assignmentToShift.dataProviders.AssignmentToShiftDataProvider;
import com.qcadoo.mes.assignmentToShift.states.constants.AssignmentToShiftState;
import com.qcadoo.mes.assignmentToShift.states.constants.AssignmentToShiftStateChangeDescriber;
import com.qcadoo.mes.basic.shift.Shift;
import com.qcadoo.mes.basic.shift.ShiftsFactory;
import com.qcadoo.mes.states.service.StateChangeEntityBuilder;
import com.qcadoo.model.api.DataDefinition;
import com.qcadoo.model.api.Entity;
import com.qcadoo.model.api.FieldDefinition;
public class AssignmentToShiftHooksTest {
private static final LocalDate START_DATE = LocalDate.now();
private AssignmentToShiftHooks assignmentToShiftHooks;
@Mock
private AssignmentToShiftStateChangeDescriber describer;
@Mock
private StateChangeEntityBuilder stateChangeEntityBuilder;
@Mock
private AssignmentToShiftDataProvider assignmentToShiftDataProvider;
@Mock
private ShiftsFactory shiftsFactory;
@Mock
private Shift shiftPojo;
private Entity assignmentToShift, shift, factory;
@Before
public void init() {
assignmentToShiftHooks = new AssignmentToShiftHooks();
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(assignmentToShiftHooks, "stateChangeEntityBuilder", stateChangeEntityBuilder);
ReflectionTestUtils.setField(assignmentToShiftHooks, "describer", describer);
ReflectionTestUtils.setField(assignmentToShiftHooks, "assignmentToShiftDataProvider", assignmentToShiftDataProvider);
ReflectionTestUtils.setField(assignmentToShiftHooks, "shiftsFactory", shiftsFactory);
assignmentToShift = mockEntity(mock(DataDefinition.class));
shift = mockEntity(mock(DataDefinition.class));
factory = mockEntity(mock(DataDefinition.class));
given(shift.copy()).willReturn(shift);
given(shiftsFactory.buildFrom(any(Entity.class))).willReturn(shiftPojo);
stubDateField(assignmentToShift, AssignmentToShiftFields.START_DATE, START_DATE.toDate());
stubBelongsToField(assignmentToShift, AssignmentToShiftFields.SHIFT, shift);
stubBelongsToField(assignmentToShift, AssignmentToShiftFields.FACTORY, factory);
stubFind(null);
stubFindAll(ImmutableList.<Entity> of());
}
private void stubFindAll(final List<Entity> results) {
given(
assignmentToShiftDataProvider.findAll(any(AssignmentToShiftCriteria.class), any(Optional.class),
any(Optional.class))).willReturn(Lists.newArrayList(results));
}
private void stubFind(final Entity result) {
given(assignmentToShiftDataProvider.find(any(AssignmentToShiftCriteria.class), any(Optional.class))).willReturn(
Optional.fromNullable(result));
}
@Test
public void shouldSetInitialState() {
// when
assignmentToShiftHooks.setInitialState(assignmentToShift);
// then
verify(stateChangeEntityBuilder).buildInitial(describer, assignmentToShift, AssignmentToShiftState.DRAFT);
}
@Test
public void shouldReturnTrueWhenCheckUniqueEntityIfEntityIsNotSaved() {
// when
boolean result = assignmentToShiftHooks.checkUniqueEntity(assignmentToShift);
// then
Assert.assertTrue(result);
verify(assignmentToShift, never()).addError(Mockito.any(FieldDefinition.class), Mockito.anyString());
}
@Test
public void shouldReturnFalseWhenCheckUniqueEntityIfEntityIsntSaved() {
// given
stubFind(mockEntity());
// when
boolean result = assignmentToShiftHooks.checkUniqueEntity(assignmentToShift);
// then
Assert.assertFalse(result);
verify(assignmentToShift, times(4)).addError(Mockito.any(FieldDefinition.class), Mockito.anyString());
}
@Test
public void shouldReturnFalseWhenCheckUniqueEntityIfEntityIsSaved() {
// given
stubFind(mockEntity());
// when
boolean result = assignmentToShiftHooks.checkUniqueEntity(assignmentToShift);
// then
Assert.assertFalse(result);
verify(assignmentToShift, times(4)).addError(Mockito.any(FieldDefinition.class), Mockito.anyString());
}
@Test
public final void shouldPickUpNextDay() {
// given
Entity startProjection1 = mockStartDateProjection(START_DATE.plusDays(1));
Entity startProjection2 = mockStartDateProjection(START_DATE.plusDays(2));
Entity startProjection3 = mockStartDateProjection(START_DATE.plusDays(3));
stubFindAll(Lists.newArrayList(startProjection1, startProjection2, startProjection3));
given(shiftPojo.worksAt(START_DATE)).willReturn(true);
given(shiftPojo.worksAt(START_DATE.plusDays(1))).willReturn(false);
given(shiftPojo.worksAt(START_DATE.plusDays(2))).willReturn(true);
given(shiftPojo.worksAt(START_DATE.plusDays(3))).willReturn(false);
given(shiftPojo.worksAt(START_DATE.plusDays(4))).willReturn(false);
given(shiftPojo.worksAt(START_DATE.plusDays(5))).willReturn(true);
// when
assignmentToShiftHooks.setNextDay(assignmentToShift);
// then
ArgumentCaptor<Date> dateCaptor = ArgumentCaptor.forClass(Date.class);
verify(assignmentToShift).setField(eq(AssignmentToShiftFields.START_DATE), dateCaptor.capture());
Date pickedUpNextStartDate = dateCaptor.getValue();
Assert.assertTrue(START_DATE.plusDays(5).toDate().compareTo(pickedUpNextStartDate) == 0);
}
@Test
public final void shouldPickUpNextDayIfThereIsNoOccupiedDates() {
// given
given(shiftPojo.worksAt(START_DATE)).willReturn(true);
given(shiftPojo.worksAt(START_DATE.plusDays(1))).willReturn(false);
given(shiftPojo.worksAt(START_DATE.plusDays(2))).willReturn(true);
given(shiftPojo.worksAt(START_DATE.plusDays(3))).willReturn(false);
given(shiftPojo.worksAt(START_DATE.plusDays(4))).willReturn(false);
given(shiftPojo.worksAt(START_DATE.plusDays(5))).willReturn(true);
// when
assignmentToShiftHooks.setNextDay(assignmentToShift);
// then
ArgumentCaptor<Date> dateCaptor = ArgumentCaptor.forClass(Date.class);
verify(assignmentToShift).setField(eq(AssignmentToShiftFields.START_DATE), dateCaptor.capture());
Date pickedUpNextStartDate = dateCaptor.getValue();
Assert.assertTrue(START_DATE.plusDays(2).toDate().compareTo(pickedUpNextStartDate) == 0);
}
@Test
public final void shouldNotPickUpAnyDateIfShiftNeverWork() {
// given
Entity startProjection1 = mockStartDateProjection(START_DATE.plusDays(1));
Entity startProjection2 = mockStartDateProjection(START_DATE.plusDays(2));
Entity startProjection3 = mockStartDateProjection(START_DATE.plusDays(3));
stubFindAll(Lists.newArrayList(startProjection1, startProjection2, startProjection3));
// when
assignmentToShiftHooks.setNextDay(assignmentToShift);
// then
verify(assignmentToShift).setField(eq(AssignmentToShiftFields.START_DATE), refEq(null));
}
private Entity mockStartDateProjection(final LocalDate localDate) {
Entity projection = mockEntity();
stubDateField(projection, AssignmentToShiftFields.START_DATE, localDate.toDate());
return projection;
}
}