@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {

  @Mock private DateTimeProvider dateTimeProvider;

  private Instant now = Instant.parse("2015-12-03T10:15:30.00Z");
  private Instant smallDelay = now.minus(4, ChronoUnit.SECONDS);
  private Instant warningDelay = now.minus(8, ChronoUnit.SECONDS);
  private Instant errorDelay = now.minus(12, ChronoUnit.SECONDS);

  @Test
  public void getStatus_shouldReturnOkImageName_whenNoTimeout() {
    Service sut = getService(smallDelay);
    assertEquals("img/green.png", sut.getStatus());
  }

  @Test
  public void getStatus_shouldReturnWarningImageName_whenWarningTimeout() {
    Service sut = getService(warningDelay);
    assertEquals("img/yellow.png", sut.getStatus());
  }

  @Test
  public void getStatus_shouldReturnErrorImageName_whenErrorTimeout() {
    Service sut = getService(errorDelay);
    assertEquals("img/red.png", sut.getStatus());
  }

  @Test
  public void getStatus_shouldReturnUnknownImageName_whenNoLastMessagePresent() {
    Service sut = new Service("service");
    assertEquals("img/unknown.png", sut.getStatus());
  }

  private Service getService(Instant delay) {
    Mockito.when(dateTimeProvider.now()).thenReturn(now);
    Mockito.when(
            dateTimeProvider.betweenDateAndNow(
                Matchers.any(Instant.class), Matchers.eq(ChronoUnit.SECONDS)))
        .thenReturn(ChronoUnit.SECONDS.between(delay, now));
    return new Service("service", dateTimeProvider);
  }
}
@RunWith(MockitoJUnitRunner.class)
public class UpdateMessageListenerTest {

  @Mock private TextMessage textMessage;
  @Mock private MapMessage mapMessage;
  @Mock private DateTimeProvider dateTimeProvider;

  private Services services = new Services();
  private ReportMessages messages = new ReportMessages();
  private UpdateMessageListener sut;
  private Instant now = Instant.parse("2015-12-03T10:15:30.00Z");
  private Instant sendTime = now.minus(4, ChronoUnit.SECONDS);

  @Before
  public void setup() {
    sut = new UpdateMessageListener(services, messages, dateTimeProvider);
  }

  @Test
  public void serviceUpdateMessage_shouldBeReflectedInServicesObject_whenTextMessageReceived()
      throws JMSException {
    Mockito.when(textMessage.getStringProperty("sender")).thenReturn("service");
    Mockito.when(dateTimeProvider.now()).thenReturn(now);
    sut.onMessage(textMessage);

    List<Service> allServices = services.getAllServices();
    assertEquals(1, allServices.size());
    assertEquals("service - 2015-12-03T10:15:30Z", allServices.get(0).getServiceDetails());
  }

  @Test
  public void reportMessage_shouldBeReflectedInReportMessagesObject_whenMapMessageReceived()
      throws JMSException {
    Mockito.when(mapMessage.getStringProperty("sender")).thenReturn("service");
    Mockito.when(mapMessage.getString("message")).thenReturn("db load error");
    Mockito.when(mapMessage.getString("timestamp")).thenReturn("999");
    Mockito.when(mapMessage.getString("severity")).thenReturn("error");

    Mockito.when(dateTimeProvider.now()).thenReturn(now);
    Mockito.when(dateTimeProvider.stringToInstant("999")).thenReturn(sendTime);
    sut.onMessage(mapMessage);

    List<ReportMessage> reportMessages = messages.getMessages();
    assertEquals(1, reportMessages.size());

    ReportMessage reportMessage = reportMessages.get(0);
    assertEquals("service", reportMessage.getSender());
    assertEquals("db load error", reportMessage.getMessage());
    assertEquals("error", reportMessage.getSeverity());
    assertEquals(now, reportMessage.getReceivedOn());
    assertEquals(sendTime, reportMessage.getTimestamp());
  }
}
  private void getLicenseWithNewState(License license) throws IOException, MessagingException {
    Date validFrom = license.getValidFrom();
    Date validTill = license.getValidTill();

    if (validFrom != null && validTill != null) {
      Instant now = Instant.now();
      Instant lastValid = validTill.toInstant();
      Instant lastActive = lastValid.minus(2, ChronoUnit.DAYS);
      if (now.isBefore(lastActive)) {
        license.setState(State.ACTIVE);
      }
      if (now.isAfter(lastActive) && now.isBefore(lastValid)) {
        license.setState(State.EXPIRATION_NEARING);
        // send mail to Admin notifying about soon expiring license
        mailService.sendExpirationNearingMail(license);
      }
      if (now.isAfter(lastValid)) {
        license.setState(State.TERMINATED);
      }
    }
  }