package com.example.backend;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;

import com.example.backend.categories.model.CategoryEntity;
import com.example.backend.categories.service.CategoryService;
import com.example.backend.core.error.NotFoundException;

@SpringBootTest
class CategoryServiceTests {
    @Autowired
    private CategoryService categoryService;

    private CategoryEntity category;

    @BeforeEach
    void createData() {
        removeData();

        category = categoryService.create(new CategoryEntity("Фэнтези"));
        categoryService.create(new CategoryEntity("Художественная литература"));
        categoryService.create(new CategoryEntity("Книги для подростков"));
    }

    @AfterEach
    void removeData() {
        categoryService.getAll().forEach(item -> categoryService.delete(item.getId()));
    }

    @Test
    void getTest() {
        Assertions.assertThrows(NotFoundException.class, () -> categoryService.get(0L));
    }

    @Test
    void createTest() {
        Assertions.assertEquals(3, categoryService.getAll().size());
        Assertions.assertEquals(category, categoryService.get(category.getId()));
    }

    @Test
    void createNotUniqueTest() {
        final CategoryEntity nonUniqueCategory = new CategoryEntity("Фэнтези");
        Assertions.assertThrows(IllegalArgumentException.class, () -> categoryService.create(nonUniqueCategory));
    }

    @Test
    void createNullableTest() {
        final CategoryEntity nullableCategory = new CategoryEntity(null);
        Assertions.assertThrows(DataIntegrityViolationException.class, () -> categoryService.create(nullableCategory));
    }

    @Test
    void updateTest() {
        final String test = "TEST";
        final String oldName = category.getName();
        final CategoryEntity newEntity = categoryService.update(category.getId(), new CategoryEntity(test));
        Assertions.assertEquals(3, categoryService.getAll().size());
        Assertions.assertEquals(newEntity, categoryService.get(category.getId()));
        Assertions.assertEquals(test, newEntity.getName());
        Assertions.assertNotEquals(oldName, newEntity.getName());
    }

    @Test
    void deleteTest() {
        categoryService.delete(category.getId());
        Assertions.assertEquals(2, categoryService.getAll().size());

        final CategoryEntity newEntity = categoryService.create(new CategoryEntity(category.getName()));
        Assertions.assertEquals(3, categoryService.getAll().size());
        Assertions.assertNotEquals(category.getId(), newEntity.getId());
    }
}
