/*
 * 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.vm.infrastructure.persistence;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;

import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import com.scytl.products.oscore.logging.api.domain.Level;
import com.scytl.products.oscore.logging.api.domain.LogContent;
import com.scytl.products.oscore.logging.api.writer.SecureLoggingWriter;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.infrastructure.persistence.BaseRepositoryImplTest;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;
import com.scytl.products.ov.vm.domain.model.credential.Credential;
import com.scytl.products.ov.vm.domain.model.credential.CredentialRepository;

/**
 * Junits for the class {@link CredentialRepositoryImpl}
 */
@RunWith(MockitoJUnitRunner.class)
public class CredentialRepositoryImplTest extends BaseRepositoryImplTest<Credential, Integer> {

	@InjectMocks
	private static CredentialRepository credentialRepository = new CredentialRepositoryImpl();

	@Mock
	private TypedQuery<Credential> queryMock;
	
	@Mock
	private TypedQuery<Long> queryMockLong;

	@Mock
	private SecureLoggingWriter secureLoggerWriter;

	@Mock
	private TrackIdInstance trackId;

	/**
	 * Creates a new object of the testing class.
	 */
	public CredentialRepositoryImplTest() throws InstantiationException, IllegalAccessException {
		super(Credential.class, credentialRepository.getClass());
	}

	@Before
	public void setup() {
		doNothing().when(secureLoggerWriter).log(any(Level.class), any(LogContent.class));
	}

	@Test
	public void testFindByTenantIdElectionEventIdVotingCardId() throws ResourceNotFoundException {
		String tenantId = "1";
		String electionEventId = "2";
		String credentialId = "3";
		
		Credential credentialMock = new Credential();
		credentialMock.setCredentialId("credentialId");
		credentialMock.setData("data");
		credentialMock.setElectionEventId(electionEventId);
		credentialMock.setId(3);
		credentialMock.setTenantId(tenantId);
		
		when(entityManagerMock.createQuery(Matchers.anyString(), eq(Credential.class))).thenReturn(queryMock);
		when(queryMock.setParameter(Matchers.anyString(), Matchers.anyString())).thenReturn(queryMock);
		when(queryMock.getSingleResult()).thenReturn(credentialMock);

		Credential credentialResult = credentialRepository.findByTenantIdElectionEventIdCredentialId(tenantId, electionEventId, credentialId);
		
		assertEquals(electionEventId, credentialResult.getElectionEventId());
		assertEquals(tenantId, credentialResult.getTenantId());
	}

	@Test
	public void testFindByTenantIdElectionEventIdVotingCardIdNotFound() throws ResourceNotFoundException {
		String tenantId = "2";
		String electionEventId = "2";
		String credentialId = "2";
		when(entityManagerMock.createQuery(Matchers.anyString(), eq(Credential.class))).thenReturn(queryMock);
		when(queryMock.setParameter(Matchers.anyString(), Matchers.anyString())).thenReturn(queryMock);
		when(queryMock.getSingleResult()).thenThrow(new NoResultException());

		expectedException.expect(ResourceNotFoundException.class);

		assertNotNull(
			credentialRepository.findByTenantIdElectionEventIdCredentialId(tenantId, electionEventId, credentialId));
	}
	
	@Test
	public void testHasWithTenantIdElectionEventIdCredentialIdSuccessful()
	{
		String tenantId = "2";
		String electionEventId = "2";
		String credentialId = "2";
		
		when(entityManagerMock.createQuery(Matchers.anyString(), eq(Long.class))).thenReturn(queryMockLong);
		when(queryMockLong.setParameter(Matchers.anyString(), Matchers.anyString())).thenReturn(queryMockLong);
		when(queryMockLong.getSingleResult()).thenReturn(10l);

		boolean actualResult = credentialRepository.hasWithTenantIdElectionEventIdCredentialId(tenantId, electionEventId, credentialId);
		
		assertTrue(actualResult);
	}
}
