/*
 * Queue - A Queueing system that can be used to handle labs in higher education
 * Copyright (C) 2016-2021  Delft University of Technology
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
package nl.tudelft.queue.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;

import javax.transaction.Transactional;

import nl.tudelft.labracore.lib.security.user.DefaultRole;
import nl.tudelft.labracore.lib.security.user.Person;
import nl.tudelft.queue.dto.create.CourseRequestCreateDTO;
import nl.tudelft.queue.properties.MailProperties;
import nl.tudelft.queue.properties.QueueProperties;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

import test.test.TestQueueApplication;

@Transactional
@SpringBootTest(classes = TestQueueApplication.class)
public class MailServiceTest {
	@Autowired
	private MailService ms;

	@Autowired
	private QueueProperties qp;

	@Autowired
	private MailProperties mp;

	@MockBean
	private MailSender mailSender;

	private final Person person = Person.builder()
			.id(8932L)
			.defaultRole(DefaultRole.ADMIN)
			.displayName("Mr. Admin")
			.email("admin@tudelft.nl")
			.username("adminnnn")
			.build();

	private final CourseRequestCreateDTO dto = CourseRequestCreateDTO.builder()
			.name("Test Course")
			.code("TEST10")
			.build();

	private ArgumentCaptor<SimpleMailMessage> msgArg;

	@BeforeEach
	void setUp() {
		msgArg = ArgumentCaptor.forClass(SimpleMailMessage.class);
	}

	@Test
	void sendCourseEmailGoesToSupportEmail() {
		ms.sendCourseRequest(person, dto);

		verify(mailSender).send(msgArg.capture());

		assertThat(msgArg.getValue().getTo()).containsOnly(mp.getSupportEmail());
	}

	@Test
	void sendCourseEmailComesFromOriginMail() {
		ms.sendCourseRequest(person, dto);

		verify(mailSender).send(msgArg.capture());

		assertThat(msgArg.getValue().getFrom()).isEqualTo(mp.getOriginEmail());
	}

	@Test
	void sendCourseEmailSubjectContainsCourseName() {
		ms.sendCourseRequest(person, dto);

		verify(mailSender).send(msgArg.capture());

		assertThat(msgArg.getValue().getSubject()).contains(dto.getName());
	}

	@Test
	void sendCourseEmailTextContainsUserInfo() {
		ms.sendCourseRequest(person, dto);

		verify(mailSender).send(msgArg.capture());

		assertThat(msgArg.getValue().getText()).contains(person.getDisplayName());
		assertThat(msgArg.getValue().getText()).contains(person.getEmail());
	}

	@Test
	void sendCourseEmailTextContainsLink() {
		ms.sendCourseRequest(person, dto);

		verify(mailSender).send(msgArg.capture());

		assertThat(msgArg.getValue().getText()).contains(qp.getDeployUrl());
	}

	@Test
	void sendCourseEmailReplyToContainsUserEmail() {
		ms.sendCourseRequest(person, dto);

		verify(mailSender).send(msgArg.capture());

		assertThat(msgArg.getValue().getReplyTo()).isEqualTo(person.getEmail());
	}
}
