/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.au.services.domain.service.validation;

import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import com.scytl.products.ov.au.services.domain.model.authentication.AuthenticationToken;
import com.scytl.products.ov.au.services.domain.service.authenticationcontent.AuthenticationContentService;
import com.scytl.products.ov.commons.beans.domain.model.authentication.AuthenticationContent;
import com.scytl.products.ov.commons.beans.exceptions.AuthTokenValidationException;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;

@RunWith(MockitoJUnitRunner.class)
public class AuthenticationTokenExpirationTimeValidationTest {

	@InjectMocks
	AuthenticationTokenExpirationTimeValidation validation = new AuthenticationTokenExpirationTimeValidation();

	@Mock
	AuthenticationToken authenticationTokenMock;

	@Mock
	AuthenticationContentService authenticationContentServiceMock;

	@Mock
	private AuthenticationContent authenticationContentMock;

	@Rule
	public ExpectedException expectedException = ExpectedException.none();

	@Test
	public void givenAuthenticationTokenWhenValidTimestampThenValidationSuccess() throws ResourceNotFoundException {
		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";

		final String now = String.valueOf(System.currentTimeMillis());
		when(authenticationTokenMock.getTimestamp()).thenReturn(now);
		when(authenticationContentServiceMock.getAuthenticationContent(anyString(), anyString())).thenReturn(
			authenticationContentMock);
		when(authenticationContentMock.getTokenExpirationTime()).thenReturn(100000);
		
		assertTrue(validation.execute(tenantId, electionEventId, votingCardId, authenticationTokenMock).isResult());

	}

	@Test
	public void givenAuthenticationTokenWhenNegativeTimestampThenValidationFail() throws ResourceNotFoundException {
		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";

		when(authenticationTokenMock.getTimestamp()).thenReturn(String.valueOf(Long.MIN_VALUE));
		when(authenticationContentServiceMock.getAuthenticationContent(anyString(), anyString())).thenReturn(
			authenticationContentMock);
		when(authenticationContentMock.getTokenExpirationTime()).thenReturn(1);
		expectedException.expect(AuthTokenValidationException.class);
		validation.execute(tenantId, electionEventId, votingCardId, authenticationTokenMock);
	}

	@Test
	public void givenAuthenticationTokenWhenNegativeDifferenceTimestampThenValidationFail()
			throws ResourceNotFoundException {
		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";

		when(authenticationTokenMock.getTimestamp()).thenReturn(String.valueOf(Long.MAX_VALUE));
		when(authenticationContentServiceMock.getAuthenticationContent(anyString(), anyString())).thenReturn(
			authenticationContentMock);
		when(authenticationContentMock.getTokenExpirationTime()).thenReturn(100000);
		expectedException.expect(AuthTokenValidationException.class);
		validation.execute(tenantId, electionEventId, votingCardId, authenticationTokenMock);
	}

	@Test
	public void testAuthenticationTokenIsNotStillValid() throws ResourceNotFoundException {
		String tenantId = "1";
		String electionEventId = "1";
		String votingCardId = "1";

		final String someTimeAgo = String.valueOf(System.currentTimeMillis() - 1000L);
		when(authenticationTokenMock.getTimestamp()).thenReturn(someTimeAgo);
		when(authenticationContentServiceMock.getAuthenticationContent(anyString(), anyString())).thenReturn(
				authenticationContentMock);
		when(authenticationContentMock.getTokenExpirationTime()).thenReturn(0);
		expectedException.expect(AuthTokenValidationException.class);
		validation.execute(tenantId, electionEventId, votingCardId, authenticationTokenMock);

	}


}
