package com.epam.rft.atsy.persistence.repositories;


import com.epam.rft.atsy.persistence.entities.ApplicationEntity;
import com.epam.rft.atsy.persistence.entities.CandidateEntity;
import com.epam.rft.atsy.persistence.entities.ChannelEntity;
import com.epam.rft.atsy.persistence.entities.PositionEntity;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.jdbc.Sql;

import java.util.Date;
import java.util.List;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;

@Sql("classpath:sql/application/application.sql")
public class ApplicationsRepositoryIT extends AbstractRepositoryIT {

    public static final long CANDIDATE_A_ID = 1L;
    public static final long CANDIDATE_B_ID = 2L;
    public static final long CANDIDATE_C_ID = 3L;

    @Autowired
    private ApplicationsRepository repository;

    @Autowired
    private CandidateRepository candidateRepository;

    @Test
    public void findByCandidateEntityShouldNotFindApplicationForCandidateWithoutApplications() {
        // Given
        CandidateEntity candidateB = this.candidateRepository.findOne(CANDIDATE_B_ID);

        // When
        List<ApplicationEntity> result = this.repository.findByCandidateEntity(candidateB);

        // Then
        assertThat(result, notNullValue());
        assertThat(result, empty());
    }

    @Test
    public void findByCandidateEntityShouldFindSingleApplicationForCandidateWithSingleApplication() {
        // Given
        CandidateEntity candidateEntityA = this.candidateRepository.findOne(CANDIDATE_A_ID);
        ChannelEntity expectedChannelEntity = ChannelEntity.builder()
                .id(1L)
                .name("direkt")
                .build();
        PositionEntity expectedPositionEntity = PositionEntity.builder()
                .id(1L)
                .name("Fejlesztő")
                .build();
        Date currentDate = new Date();

        // When
        List<ApplicationEntity> result = this.repository.findByCandidateEntity(candidateEntityA);

        // Then
        assertThat(result, notNullValue());
        assertThat(result.size(), is(1));

        assertApplicationEntity(result.get(0), candidateEntityA, expectedChannelEntity, expectedPositionEntity, currentDate);
    }

    @Test
    public void findByCandidateEntityShouldFindThreeApplicationForCandidateWithThreeApplication() {
        // Given
        CandidateEntity candidateEntityC = this.candidateRepository.findOne(CANDIDATE_C_ID);
        ChannelEntity expectedChannelEntity = ChannelEntity.builder()
                .id(2L)
                .name("profession hírdetés")
                .build();
        ChannelEntity expectedSecondChannelEntity = ChannelEntity.builder()
                .id(3L)
                .name("profession adatbázis")
                .build();
        ChannelEntity expectedThirdChannelEntity = ChannelEntity.builder()
                .id(4L)
                .name("facebook")
                .build();
        PositionEntity expectedPositionEntity = PositionEntity.builder()
                .id(1L)
                .name("Fejlesztő")
                .build();
        Date currentDate = new Date();

        // When
        List<ApplicationEntity> result = this.repository.findByCandidateEntity(candidateEntityC);

        // Then
        assertThat(result, notNullValue());
        assertThat(result.size(), is(3));

        assertApplicationEntity(result.get(0), candidateEntityC, expectedChannelEntity, expectedPositionEntity, currentDate);
        assertApplicationEntity(result.get(1), candidateEntityC, expectedSecondChannelEntity, expectedPositionEntity, currentDate);
        assertApplicationEntity(result.get(2), candidateEntityC, expectedThirdChannelEntity, expectedPositionEntity, currentDate);
    }

    private void assertApplicationEntity(ApplicationEntity application, CandidateEntity expectedCandidateEntity, ChannelEntity expectedChannelEntity, PositionEntity expectedPositionEntity, Date currentDate) {
        assertThat(application, notNullValue());

        assertThat(application.getCandidateEntity(), notNullValue());
        assertThat(application.getCandidateEntity(), is(expectedCandidateEntity));

        assertThat(application.getChannelEntity(), notNullValue());
        assertThat(application.getChannelEntity(), is(expectedChannelEntity));

        assertThat(application.getPositionEntity(), notNullValue());
        assertThat(application.getPositionEntity(), is(expectedPositionEntity));

        assertThat(application.getCreationDate(), notNullValue());
        assertThat(application.getCreationDate(), lessThanOrEqualTo(currentDate));
    }

}

@@ -435,16 +435,105 @@
 c.Sql;%0A%0A
+import java.time.LocalDateTime;%0Aimport java.time.ZoneId;%0Aimport java.time.ZonedDateTime;%0A
 import j
@@ -2072,32 +2072,42 @@
 ();%0A        Date
+ nearNow =
  currentDate = n
@@ -2098,36 +2098,31 @@
  currentDate
- = new Date(
+Minus(5
 );%0A%0A        
@@ -2439,35 +2439,31 @@
 tionEntity, 
-currentDate
+nearNow
 );%0A    %7D%0A%0A  
@@ -3342,24 +3342,34 @@
         Date
+ nearNow =
  currentDate
@@ -3372,20 +3372,15 @@
 Date
- = new Date(
+Minus(5
 );%0A%0A
@@ -3705,35 +3705,31 @@
 tionEntity, 
-currentDate
+nearNow
 );%0A        a
@@ -3833,35 +3833,31 @@
 tionEntity, 
-currentDate
+nearNow
 );%0A        a
@@ -3964,27 +3964,23 @@
 Entity, 
-currentDate
+nearNow
 );%0A    %7D
@@ -4175,27 +4175,25 @@
 y, Date 
-currentDate
+threshold
 ) %7B%0A    
@@ -4812,37 +4812,167 @@
 (), 
-lessThanOrEqualTo(currentDate
+greaterThan(threshold));%0A    %7D%0A%0A    private Date currentDateMinus(long seconds) %7B%0A        return Date.from(ZonedDateTime.now().minusSeconds(seconds).toInstant(
 ));%0A

change date check in application repository test to a meaningful validation