@Test
  public final void shouldNotSaveFormBecauseOfDeviationCausesValidationErrors() {
    // given
    stubProgressType(ProgressType.PLANNED);
    stubTechnologyOperation(null);

    Entity deviationCauseEntity = mockEntity(dataDefinition);
    Entity invalidDeviationCauseEntity = mockEntity(dataDefinition);
    given(invalidDeviationCauseEntity.isValid()).willReturn(false);
    given(dataDefinition.save(deviationCauseEntity)).willReturn(invalidDeviationCauseEntity);

    AwesomeDynamicListComponent deviationCausesAdl = mock(AwesomeDynamicListComponent.class);
    stubViewComponent(CORRECTION_CAUSE_TYPES_ADL_REF, deviationCausesAdl);
    stubHasManyField(
        ppsEntity,
        ProductionPerShiftFields.PLANNED_PROGRESS_CORRECTION_TYPES,
        Lists.newArrayList(deviationCauseEntity));

    // when
    progressPerShiftViewSaver.save(view);

    // then
    verify(txStatus, never()).setRollbackOnly();

    verify(dataDefinition).save(deviationCauseEntity);
    verify(dataDefinition, never()).save(ppsEntity);
    verify(deviationCausesAdl).setFieldValue(Lists.newArrayList(invalidDeviationCauseEntity));
    verify(form)
        .addMessage("qcadooView.message.saveFailedMessage", ComponentState.MessageType.FAILURE);
  }
  @Test
  public final void shouldNotSaveFormAndCorrectedProgressesDueToDailyProgressesValidationErrors() {
    // given
    Long tocId = 1001L;

    Entity pfd1dp1 = mockDailyProgress();
    Entity pfd1dp2 = mockDailyProgress();
    Entity pfd1 = mockProgressForDayEntity(pfd1dp1, pfd1dp2);

    Entity pfd2dp1 = mockDailyProgress();
    Entity pfd2 = mockProgressForDayEntity(pfd2dp1);
    given(pfd2.isValid()).willReturn(false);
    Entity invalidPfd2dp1 = mockDailyProgress();
    given(invalidPfd2dp1.isValid()).willReturn(false);
    given(dataDefinition.save(pfd2dp1)).willReturn(invalidPfd2dp1);

    stubProgressForDaysAdlEntities(pfd1, pfd2);

    stubProgressType(ProgressType.PLANNED);

    Entity technologyOperation = mockEntity(tocId, dataDefinition);
    given(technologyOperation.isValid()).willReturn(true);
    stubTechnologyOperation(technologyOperation);

    given(ppsEntity.isValid()).willReturn(true);

    // when
    progressPerShiftViewSaver.save(view);

    // then
    verify(txStatus, times(4))
        .setRollbackOnly(); // one rollback for each DailyProgress + 1 global rollback
    verifyTocSetupAbsence(technologyOperation);

    verify(dataDefinition).save(pfd1dp1);
    verify(dataDefinition).save(pfd1dp2);
    verify(dataDefinition, never()).save(pfd1);
    verify(pfd1).setField(ProgressForDayFields.CORRECTED, false);
    verify(pfd1).setField(ProgressForDayFields.TECHNOLOGY_OPERATION_COMPONENT, tocId);

    verify(dataDefinition).save(pfd2dp1);
    verify(pfd2).setNotValid();
    verify(dataDefinition, never()).save(pfd2);
    verify(pfd2, never()).setField(ProgressForDayFields.CORRECTED, false);
    verify(pfd2, never()).setField(ProgressForDayFields.TECHNOLOGY_OPERATION_COMPONENT, tocId);

    verify(dataDefinition, never()).save(ppsEntity);

    verify(form)
        .addMessage("qcadooView.message.saveFailedMessage", ComponentState.MessageType.FAILURE);
  }
  @Test
  public final void shouldSaveFormAndCorrectedProgresses() {
    // given
    Long tocId = 1001L;

    Entity pfd1dp1 = mockDailyProgress();
    Entity pfd1dp2 = mockDailyProgress();
    Entity pfd1 = mockProgressForDayEntity(pfd1dp1, pfd1dp2);

    Entity pfd2dp1 = mockDailyProgress();
    Entity pfd2 = mockProgressForDayEntity(pfd2dp1);

    stubProgressForDaysAdlEntities(pfd1, pfd2);

    stubProgressType(ProgressType.CORRECTED);

    Entity technologyOperation = mockEntity(tocId, dataDefinition);
    given(technologyOperation.isValid()).willReturn(true);
    stubTechnologyOperation(technologyOperation);

    given(ppsEntity.isValid()).willReturn(true);

    List<Entity> plannedPfds = Lists.newArrayList(mockEntity(), mockEntity(), mockEntity());
    stubPfdDataProviderFindForoperation(plannedPfds);

    // when
    progressPerShiftViewSaver.save(view);

    // then
    verify(txStatus, times(3)).setRollbackOnly(); // one rollback for each DailyProgress
    List<Entity> expectedPfds =
        Lists.newLinkedList(Iterables.concat(plannedPfds, Lists.newArrayList(pfd1, pfd2)));
    verifyTocSetup(technologyOperation, expectedPfds, true);

    verify(dataDefinition).save(pfd1dp1);
    verify(dataDefinition).save(pfd1dp2);
    verify(dataDefinition).save(pfd1);
    verify(pfd1).setField(ProgressForDayFields.CORRECTED, true);
    verify(pfd1).setField(ProgressForDayFields.TECHNOLOGY_OPERATION_COMPONENT, tocId);

    verify(dataDefinition).save(pfd2dp1);
    verify(dataDefinition).save(pfd2);
    verify(pfd2).setField(ProgressForDayFields.CORRECTED, true);
    verify(pfd2).setField(ProgressForDayFields.TECHNOLOGY_OPERATION_COMPONENT, tocId);

    verify(dataDefinition).save(ppsEntity);

    verify(form).addMessage("qcadooView.message.saveMessage", ComponentState.MessageType.SUCCESS);
  }
  @Test
  public final void shouldSaveOnlyForm() {
    // given
    stubProgressType(ProgressType.PLANNED);
    stubTechnologyOperation(null);
    given(ppsEntity.isValid()).willReturn(true);

    // when
    progressPerShiftViewSaver.save(view);

    // then
    verify(txStatus, never()).setRollbackOnly();

    verify(dataDefinition).save(ppsEntity);
    verify(form).addMessage("qcadooView.message.saveMessage", ComponentState.MessageType.SUCCESS);
  }
  @Test
  public final void shouldNotSaveFormBecauseOfValidationErrors() {
    // given
    stubProgressType(ProgressType.PLANNED);
    stubTechnologyOperation(null);
    Entity invalidPpsEntity = mockEntity(dataDefinition);
    given(invalidPpsEntity.isValid()).willReturn(false);
    given(dataDefinition.save(ppsEntity)).willReturn(invalidPpsEntity);

    // when
    progressPerShiftViewSaver.save(view);

    // then
    verify(txStatus, never()).setRollbackOnly();

    verify(dataDefinition).save(ppsEntity);
    verify(form)
        .addMessage("qcadooView.message.saveFailedMessage", ComponentState.MessageType.FAILURE);
  }