package org.takiguchi.cerberus.cerberusapp.service.validator;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.takiguchi.cerberus.cerberusapp.model.Application;
import org.takiguchi.cerberus.cerberusapp.model.ServiceType;
import org.takiguchi.cerberus.cerberusapp.service.exception.ValidationException;

import java.util.UUID;
import java.util.stream.Stream;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowableOfType;
import static org.takiguchi.cerberus.cerberusapp.model.Application.anApplication;
import static org.takiguchi.cerberus.cerberusapp.model.ServiceType.FAKE;

class ApplicationValidatorTest {
    private ApplicationValidator validator;

    @BeforeEach
    void setUp() {
        validator = new ApplicationValidator();
    }

    @ParameterizedTest
    @MethodSource("should_throw_a_validation_exception_data_provider")
    void should_throw_a_validation_exception(Application application, String errorMessage) {
        // when
        ValidationException exception = catchThrowableOfType(() -> validator.validate(application), ValidationException.class);

        // then
        assertThat(exception).isNotNull()
                .hasMessage(errorMessage);
    }

    private static Stream<Arguments> should_throw_a_validation_exception_data_provider() {
        return Stream.of(
                Arguments.of(
                        null,
                        "Application is null."
                ),
                Arguments.of(
                        anApplication().build(),
                        "Application name is mandatory."
                ),
                Arguments.of(
                        anApplication()
                                .withId(UUID.randomUUID())
                                .build(),
                        "Application name is mandatory."
                ),
                Arguments.of(
                        anApplication()
                            .withName("name")
                            .build(),
                        "Application service name is mandatory."
                ),
                Arguments.of(
                        anApplication()
                                .withServiceName("serviceName")
                                .build(),
                        "Application name is mandatory."
                ),
                Arguments.of(
                        anApplication()
                                .withServiceType(FAKE)
                                .build(),
                        "Application name is mandatory."
                ),
                Arguments.of(
                        anApplication()
                            .withId(UUID.randomUUID())
                            .withName("name")
                            .build(),
                        "Application service name is mandatory."
                ),
                Arguments.of(
                        anApplication()
                                .withId(UUID.randomUUID())
                                .withServiceName("serviceName")
                                .build(),
                        "Application name is mandatory."
                ),
                Arguments.of(
                        anApplication()
                                .withId(UUID.randomUUID())
                                .withName("name")
                                .withServiceName("serviceName")
                                .build(),
                        "Application service type is mandatory."
                )
        );
    }
}