package org.codenergic.theskeleton.tokenstore;

import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.GreenMailUtil;
import com.icegreen.greenmail.util.ServerSetupTest;
import it.ozimov.springboot.mail.configuration.EnableEmailTools;
import org.codenergic.theskeleton.core.mail.EmailConfig;
import org.codenergic.theskeleton.core.mail.EmailService;
import org.codenergic.theskeleton.core.mail.EmailServiceTest;
import org.codenergic.theskeleton.core.mail.impl.EmailServiceImpl;
import org.codenergic.theskeleton.registration.RegistrationException;
import org.codenergic.theskeleton.tokenstore.impl.TokenStoreServiceImpl;
import org.codenergic.theskeleton.tokenstore.TokenStoreRepository;
import org.codenergic.theskeleton.tokenstore.TokenStoreService;
import org.codenergic.theskeleton.tokenstore.TokenStoreType;
import org.codenergic.theskeleton.user.UserEntity;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.context.junit4.SpringRunner;

import javax.mail.internet.MimeMessage;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { EmailServiceTest.EmailTestConfiguration.class, EmailConfig.class, EmailServiceImpl.class },
	webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class TokenStoreServiceTest {

	@Mock
	private TokenStoreRepository tokenStoreRepository;
	@Autowired
	private EmailService emailService;

	private TokenStoreService tokenStoreService;
	private PasswordEncoder passwordEncoder = NoOpPasswordEncoder.getInstance();
	private GreenMail greenMail;

	@Before
	public void init() {
		MockitoAnnotations.initMocks(this);
		tokenStoreService = new TokenStoreServiceImpl(emailService, tokenStoreRepository);
		greenMail = new GreenMail(ServerSetupTest.SMTP);
		greenMail.start();
	}

	@After
	public void stop() {
		greenMail.stop();
	}

	@Test
	public void testSendEmailActivation() {
		UserEntity user = new UserEntity()
			.setId(UUID.randomUUID().toString())
			.setUsername("user")
			.setPassword(passwordEncoder.encode("user"))
			.setEmail("user@codenergic.org");
		tokenStoreService.sendTokenNotification(TokenStoreType.USER_ACTIVATION, user);
		tokenStoreService.sendTokenNotification(TokenStoreType.CHANGE_PASSWORD, user);

		assertThat(greenMail.waitForIncomingEmail(1000, 2)).isTrue();
		MimeMessage messageActivation = greenMail.getReceivedMessages()[0];
		assertThat(GreenMailUtil.getBody(messageActivation)).contains("activate?at=");
		MimeMessage messageChangePassword = greenMail.getReceivedMessages()[1];
		assertThat(GreenMailUtil.getBody(messageChangePassword)).contains("update?rt=");

		user.setEmail("@codenergic.org");
		assertThatThrownBy(() -> tokenStoreService.sendTokenNotification(TokenStoreType.USER_ACTIVATION, user))
			.isInstanceOf(RegistrationException.class);
		assertThatThrownBy(() -> tokenStoreService.sendTokenNotification(TokenStoreType.CHANGE_PASSWORD, user))
			.isInstanceOf(RegistrationException.class);
	}

	@Configuration
	@EnableAutoConfiguration
	@EnableEmailTools
	public static class EmailTestConfiguration {

	}
}

@@ -1553,16 +1553,39 @@
 essage;%0A
+import java.util.Date;%0A
 import j
@@ -1599,16 +1599,16 @@
 l.UUID;%0A
-
 %0Aimport 
@@ -1723,16 +1723,142 @@
 hrownBy;
+%0Aimport static org.mockito.Mockito.doAnswer;%0Aimport static org.mockito.Mockito.verify;%0Aimport static org.mockito.Mockito.when;
 %0A%0A@RunWi
@@ -2615,16 +2615,16 @@
 top() %7B%0A
-
 %09%09greenM
@@ -2639,16 +2639,870 @@
 ();%0A%09%7D%0A%0A
+%09@Test%0A%09public void testDeleteTokenByUser() %7B%0A%09%09UserEntity user = new UserEntity().setId(%22123%22);%0A%09%09doAnswer(i -%3E null).when(tokenStoreRepository).deleteTokenStoreEntityByUser(user);%0A%09%09tokenStoreService.deleteTokenByUser(user);%0A%09%09verify(tokenStoreRepository).deleteTokenStoreEntityByUser(user);%0A%09%7D%0A%0A%09@Test%0A%09public void testFindTokenAndType() %7B%0A%09%09when(tokenStoreRepository.findByTokenAndType(%22token%22, TokenStoreType.USER_ACTIVATION))%0A%09%09%09.thenReturn(new TokenStoreEntity().setToken(%22123%22).setExpiryDate(new Date()));%0A%09%09TokenStoreEntity token = tokenStoreService.findByTokenAndType(%22token%22, TokenStoreType.USER_ACTIVATION);%0A%09%09assertThat(token.getToken()).isEqualTo(%22123%22);%0A%09%09assertThat(token.getExpiryDate().getTime()).isLessThanOrEqualTo(new Date().getTime());%0A%09%09verify(tokenStoreRepository).findByTokenAndType(%22token%22, TokenStoreType.USER_ACTIVATION);%0A%09%7D%0A%0A
 %09@Test%0A%09

Improve token store service test and coverage