/*
 * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
 * Ministerpräsidenten des Landes Schleswig-Holstein
 * Staatskanzlei
 * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
 *
 * Lizenziert unter der EUPL, Version 1.2 oder - sobald
 * diese von der Europäischen Kommission genehmigt wurden -
 * Folgeversionen der EUPL ("Lizenz");
 * Sie dürfen dieses Werk ausschließlich gemäß
 * dieser Lizenz nutzen.
 * Eine Kopie der Lizenz finden Sie hier:
 *
 * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
 *
 * Sofern nicht durch anwendbare Rechtsvorschriften
 * gefordert oder in schriftlicher Form vereinbart, wird
 * die unter der Lizenz verbreitete Software "so wie sie
 * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
 * ausdrücklich oder stillschweigend - verbreitet.
 * Die sprachspezifischen Genehmigungen und Beschränkungen
 * unter der Lizenz sind dem Lizenztext zu entnehmen.
 */
package de.ozgcloud.admin;

import static de.ozgcloud.admin.RootModelAssembler.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;

import java.util.List;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties;
import org.springframework.hateoas.Link;

import de.ozgcloud.admin.common.user.CurrentUserService;

class RootModelAssemblerTest {

	private static final String BASE_PATH = "/api/base";

	@Spy
	@InjectMocks
	private RootModelAssembler modelAssembler;

	@Mock
	private RepositoryRestProperties restProperties;
	@Mock
	private CurrentUserService currentUserService;

	@DisplayName("Entity Model")
	@Nested
	class TestEntityModel {

		private final List<Link> links = List.of(Link.of(RootController.PATH));

		@BeforeEach
		void beforeEach() {
			doReturn(links).when(modelAssembler).buildRootModelLinks();
		}

		@Test
		void shouldHaveRoot() {
			var givenRoot = RootTestFactory.create();

			var resultRoot = modelAssembler.toModel(givenRoot).getContent();

			assertThat(resultRoot).isEqualTo(givenRoot);
		}

		@Test
		void shouldHaveLinks() {
			var modelLinks = modelAssembler.toModel(RootTestFactory.create()).getLinks();

			assertThat(modelLinks).containsAll(links);
		}
	}

	@DisplayName("Root Model Links")
	@Nested
	class TestBuildRootModelLinks {

		@Test
		void shouldCheckConfigurationPermission() {
			modelAssembler.buildRootModelLinks();

			verify(currentUserService).hasConfigurationPermission();
		}

		@Nested
		class TestOnHasConfigurationPermission {

			@BeforeEach
			void hasConfigurationPermission() {
				when(currentUserService.hasConfigurationPermission()).thenReturn(true);
				when(restProperties.getBasePath()).thenReturn(BASE_PATH);
			}

			@Test
			void shouldHaveHrefToConfiguration() {
				var links = modelAssembler.buildRootModelLinks();

				assertThat(links).containsExactly(
						Link.of(RootController.PATH),
						Link.of(BASE_PATH, REL_CONFIGURATION));
			}
		}

		@Nested
		class TestOnNotHasConfigurationPermission {

			@BeforeEach
			void hasNotConfigurationPermission() {
				when(currentUserService.hasConfigurationPermission()).thenReturn(false);
			}

			@Test
			void shouldHaveOnlySelfLink() {
				var links = modelAssembler.buildRootModelLinks();

				assertThat(links).containsExactly(
						Link.of(RootController.PATH));
			}
		}

	}

}