content: package xyz.zhangyi.ddd.eas.valueadded.trainingcontext.domain.ticket;
  
  import org.junit.Test;
  import xyz.zhangyi.ddd.eas.valueadded.trainingcontext.domain.candidate.Candidate;
  import xyz.zhangyi.ddd.eas.valueadded.trainingcontext.domain.exception.NominationException;
  import xyz.zhangyi.ddd.eas.valueadded.trainingcontext.domain.learning.LearningService;
  import xyz.zhangyi.ddd.eas.valueadded.trainingcontext.domain.notification.NotificationService;
  import xyz.zhangyi.ddd.eas.valueadded.trainingcontext.domain.training.TrainingId;
  
  import static org.assertj.core.api.Assertions.assertThatThrownBy;
  import static org.mockito.Mockito.*;
  
  public class NominationServiceTest {
      @Test
      public void should_nominate_candidate_to_be_nominee() {
          // given
          TicketId ticketId = TicketId.next();
          TrainingId trainingId = TrainingId.next();
          Ticket ticket = new Ticket(ticketId, trainingId, TicketStatus.WaitForConfirm);
          Candidate candidate = new Candidate(("200901010007"), "admin", "admin@eas.com", trainingId);
          Nominator nominator = new Nominator("200901010007", "admin", "admin@eas.com", TrainingRole.Coordinator);
  
          LearningService mockLearningService = mock(LearningService.class);
          when(mockLearningService.beLearned(candidate.employeeId(), trainingId)).thenReturn(false);
  
          TicketService mockTicketService = mock(TicketService.class);
          when(mockTicketService.nominate(ticketId, nominator, candidate)).thenReturn(ticket);
  
          NotificationService mockNotificationService = mock(NotificationService.class);
  
          NominationService nominationService = new NominationService();
          nominationService.setLearningService(mockLearningService);
          nominationService.setTicketService(mockTicketService);
          nominationService.setNotificationService(mockNotificationService);
  
          // when
          nominationService.nominate(ticketId, trainingId, candidate, nominator);
  
          // then
          verify(mockLearningService).beLearned(candidate.employeeId(), trainingId);
          verify(mockTicketService).nominate(ticketId, nominator, candidate);
          verify(mockNotificationService).notifyNominee(ticket, nominator, candidate.toNominee());
      }
  
      @Test
      public void should_throw_NominationException_if_candidate_had_been_learned() {
          // given
          TicketId ticketId = TicketId.next();
          TrainingId trainingId = TrainingId.next();
          Ticket ticket = new Ticket(ticketId, trainingId, TicketStatus.WaitForConfirm);
          Candidate candidate = new Candidate(("200901010007"), "admin", "admin@eas.com", trainingId);
          Nominator nominator = new Nominator("200901010007", "admin", "admin@eas.com", TrainingRole.Coordinator);
  
          LearningService mockLearningService = mock(LearningService.class);
          when(mockLearningService.beLearned(candidate.employeeId(), trainingId)).thenReturn(true);
  
          TicketService mockTicketService = mock(TicketService.class);
          when(mockTicketService.nominate(ticketId, nominator, candidate)).thenReturn(ticket);
  
          NotificationService mockNotificationService = mock(NotificationService.class);
  
          NominationService nominationService = new NominationService();
          nominationService.setLearningService(mockLearningService);
          nominationService.setTicketService(mockTicketService);
          nominationService.setNotificationService(mockNotificationService);
  
          // then
          assertThatThrownBy(() -> nominationService.nominate(ticketId, trainingId, candidate, nominator))
                  .isInstanceOf(NominationException.class)
                  .hasMessageContaining(String.format("can not nominate the candidate %s who had learned in the training", candidate.name()));
  
          // then
          verify(mockLearningService).beLearned(candidate.employeeId(), trainingId);
          verify(mockTicketService, never()).nominate(ticketId, nominator, candidate);
          verify(mockNotificationService, never()).notifyNominee(ticket, nominator, candidate.toNominee());
      }
  }