package com.wishurgift.entry.controller;

import com.wishurgift.entry.validator.CommentValidator;
import com.wishurgift.entry.validator.ElementUpdateValidator;
import com.wishurgift.entry.validator.ImageValidator;
import com.wishurgift.helper.CommentMaker;
import com.wishurgift.helper.ControllerHelper;
import com.wishurgift.helper.ElementMaker;
import com.wishurgift.helper.UserMaker;
import com.wishurgift.service.CommentService;
import com.wishurgift.service.ElementService;
import com.wishurgift.service.dto.*;
import com.wishurgift.service.dto.request.CommentRequestDTO;
import com.wishurgift.service.dto.request.ElementRequestDTO;
import com.wishurgift.service.dto.request.ImageRequestDTO;
import com.wishurgift.utils.Constant;
import com.wishurgift.wrapper.Page;
import com.wishurgift.wrapper.Result;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class ElementControllerTest {

    @Mock
    private ElementService elementService;

    @Mock
    private CommentService commentService;

    @Mock
    private ElementUpdateValidator elementUpdateValidator;

    @Mock
    private ImageValidator imageValidator;

    @Mock
    private CommentValidator commentValidator;

    @InjectMocks
    private ElementController controller;

    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void updateTest() {
        long id = 8;
        ElementRequestDTO request = ElementMaker.makeElementRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        ElementDTO expected = ElementMaker.makeElementDTO();

        Mockito.when(elementUpdateValidator.isNotValid(request)).thenReturn(false);
        Mockito.when(elementService.update(principal, id, request)).thenReturn(expected);

        Response response = controller.update(id, request, securityContext);
        ElementDTO actual = ControllerHelper.extractSuccessResult(response, ElementDTO.class);
        assertEquals(expected, actual);
    }

    @Test
    public void invalidIdUpdateTest() {
        long id = -8;
        ElementRequestDTO request = ElementMaker.makeElementRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.update(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.INVALID_ID));
    }

    @Test
    public void invalidRequestUpdateTest() {
        long id = 8;
        ElementRequestDTO request = ElementMaker.makeElementRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        List<String> trace = new ArrayList<>();
        trace.add("trace1");
        trace.add("trace2");

        Mockito.when(elementUpdateValidator.isNotValid(request)).thenReturn(true);
        Mockito.when(elementUpdateValidator.getAllErrors()).thenReturn(trace);

        Response response = controller.update(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(trace.size(), actual.getTrace().size());
        trace.forEach(elt -> assertTrue(actual.getTrace().contains(elt)));
    }

    @Test
    public void userNotFoundUpdateTest() {
        long id = 8;
        ElementRequestDTO request = ElementMaker.makeElementRequestDTO();
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();

        Mockito.when(elementUpdateValidator.isNotValid(request)).thenReturn(false);

        Response response = controller.update(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getCode(), actual.getCode());
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.USER_NOT_FOUND));
    }

    @Test
    public void failUpdateTest() {
        long id = 8;
        ElementRequestDTO request = ElementMaker.makeElementRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();

        Mockito.when(elementUpdateValidator.isNotValid(request)).thenReturn(false);
        Mockito.when(elementService.update(principal, id, request)).thenReturn(null);

        Response response = controller.update(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNAUTHORIZED.getCode(), actual.getCode());
        assertEquals(Result.Error.UNAUTHORIZED.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

    @Test
    public void getTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        ElementDTO expected = ElementMaker.makeElementDTO();

        Mockito.when(elementService.getElement(principal, id)).thenReturn(expected);

        Response response = controller.get(id, securityContext);
        ElementDTO actual = ControllerHelper.extractSuccessResult(response, ElementDTO.class);
        assertEquals(expected, actual);
    }

    @Test
    public void invalidIdGetTest() {
        long id = -8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.get(id, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.INVALID_ID));
    }

    @Test
    public void failGetTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();

        Mockito.when(elementService.getElement(principal, id)).thenReturn(null);

        Response response = controller.get(id, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNABLE_TO_GET_DATA.getCode(), actual.getCode());
        assertEquals(Result.Error.UNABLE_TO_GET_DATA.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

    @Test
    public void getNoUserTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();
        ElementDTO expected = ElementMaker.makeElementDTO();

        Mockito.when(elementService.getElement(null, id)).thenReturn(expected);

        Response response = controller.get(id, securityContext);
        ElementDTO actual = ControllerHelper.extractSuccessResult(response, ElementDTO.class);
        assertEquals(expected, actual);
    }

    @Test
    public void invalidIdGetNoUserTest() {
        long id = -8;
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();

        Response response = controller.get(id, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.INVALID_ID));
    }

    @Test
    public void failGetNoUserTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();

        Mockito.when(elementService.getElement(null, id)).thenReturn(null);

        Response response = controller.get(id, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNABLE_TO_GET_DATA.getCode(), actual.getCode());
        assertEquals(Result.Error.UNABLE_TO_GET_DATA.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

    @Test
    public void removeTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();

        Mockito.when(elementService.remove(principal, id)).thenReturn(true);

        Response response = controller.remove(id, securityContext);
        ControllerHelper.successResult(response);
    }

    @Test
    public void idInvalidRemoveTest() {
        long id = -8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.remove(id, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.INVALID_ID));
    }

    @Test
    public void userNotFoundRemoveTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();

        Response response = controller.remove(id, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getCode(), actual.getCode());
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.USER_NOT_FOUND));
    }

    @Test
    public void failRemoveTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();

        Mockito.when(elementService.remove(principal, id)).thenReturn(false);

        Response response = controller.remove(id, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNAUTHORIZED.getCode(), actual.getCode());
        assertEquals(Result.Error.UNAUTHORIZED.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

    @Test
    public void statusTest() {
        long id = 8;
        String status = "idea";
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        Constant.Status newStatus = Constant.Status.IDEA;
        ElementDTO expected = ElementMaker.makeElementDTO();

        Mockito.when(elementService.setStatus(principal, id, newStatus)).thenReturn(expected);

        Response response = controller.status(id, status, securityContext);
        ElementDTO actual = ControllerHelper.extractSuccessResult(response, ElementDTO.class);
        assertEquals(expected, actual);
    }

    @Test
    public void invalIdStatusTest() {
        long id = -8;
        String status = "idea";
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.status(id, status, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.INVALID_ID));
    }

    @Test
    public void invalStatusStatusTest() {
        long id = 8;
        String status = "nop";
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.status(id, status, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

    @Test
    public void userNotFoundtatusTest() {
        long id = 8;
        String status = "idea";
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();

        Response response = controller.status(id, status, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getCode(), actual.getCode());
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.USER_NOT_FOUND));
    }

    @Test
    public void failStatusTest() {
        long id = 8;
        String status = "idea";
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        Constant.Status newStatus = Constant.Status.IDEA;

        Mockito.when(elementService.setStatus(principal, id, newStatus)).thenReturn(null);

        Response response = controller.status(id, status, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNAUTHORIZED.getCode(), actual.getCode());
        assertEquals(Result.Error.UNAUTHORIZED.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

    @Test
    public void imageTest() {
        long id = 8;
        ImageRequestDTO request = ElementMaker.makeImageRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        ImageDTO expected = ElementMaker.makeImageDTO();

        Mockito.when(imageValidator.isNotValid(request)).thenReturn(false);
        Mockito.when(elementService.addImage(principal, id, request)).thenReturn(expected);

        Response response = controller.image(id, request, securityContext);
        ImageDTO actual = ControllerHelper.extractSuccessResult(response, ImageDTO.class);
        assertEquals(expected, actual);
    }

    @Test
    public void invalidIdImageTest() {
        long id = -8;
        ImageRequestDTO request = ElementMaker.makeImageRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.image(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.INVALID_ID));
    }

    @Test
    public void invalidRequestImageTest() {
        long id = 8;
        ImageRequestDTO request = ElementMaker.makeImageRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        List<String> trace = new ArrayList<>();
        trace.add("trace1");
        trace.add("trace2");

        Mockito.when(imageValidator.isNotValid(request)).thenReturn(true);
        Mockito.when(imageValidator.getAllErrors()).thenReturn(trace);

        Response response = controller.image(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(trace.size(), actual.getTrace().size());
        trace.forEach(elt -> assertTrue(actual.getTrace().contains(elt)));
    }

    @Test
    public void userNotFoundImageTest() {
        long id = 8;
        ImageRequestDTO request = ElementMaker.makeImageRequestDTO();
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();

        Mockito.when(imageValidator.isNotValid(request)).thenReturn(false);

        Response response = controller.image(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getCode(), actual.getCode());
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.USER_NOT_FOUND));
    }

    @Test
    public void failImageTest() {
        long id = 8;
        ImageRequestDTO request = ElementMaker.makeImageRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();

        Mockito.when(imageValidator.isNotValid(request)).thenReturn(false);
        Mockito.when(elementService.addImage(principal, id, request)).thenReturn(null);

        Response response = controller.image(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNAUTHORIZED.getCode(), actual.getCode());
        assertEquals(Result.Error.UNAUTHORIZED.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

    @Test
    public void commentTest() {
        long id = 8;
        CommentRequestDTO request = CommentMaker.makeCommentRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        CommentDTO expected = CommentMaker.makeCommentDTO();

        Mockito.when(commentValidator.isNotValid(request)).thenReturn(false);
        Mockito.when(commentService.insert(principal, id, request)).thenReturn(expected);

        Response response = controller.comment(id, request, securityContext);
        CommentDTO actual = ControllerHelper.extractSuccessResult(response, CommentDTO.class);
        assertEquals(expected, actual);
    }

    @Test
    public void invalidIdCommentTest() {
        long id = -8;
        CommentRequestDTO request = CommentMaker.makeCommentRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.comment(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.INVALID_ID));
    }

    @Test
    public void invalidRequestCommentTest() {
        long id = 8;
        CommentRequestDTO request = CommentMaker.makeCommentRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        List<String> trace = new ArrayList<>();
        trace.add("trace1");
        trace.add("trace2");

        Mockito.when(commentValidator.isNotValid(request)).thenReturn(true);
        Mockito.when(commentValidator.getAllErrors()).thenReturn(trace);

        Response response = controller.comment(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(trace.size(), actual.getTrace().size());
        trace.forEach(elt -> assertTrue(actual.getTrace().contains(elt)));
    }

    @Test
    public void userNotFoundCommentTest() {
        long id = 8;
        CommentRequestDTO request = CommentMaker.makeCommentRequestDTO();
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();

        Mockito.when(commentValidator.isNotValid(request)).thenReturn(false);

        Response response = controller.comment(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getCode(), actual.getCode());
        assertEquals(Result.Error.UNABLE_TO_CONNECT.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.USER_NOT_FOUND));
    }

    @Test
    public void failCommentTest() {
        long id = 8;
        CommentRequestDTO request = CommentMaker.makeCommentRequestDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();

        Mockito.when(commentValidator.isNotValid(request)).thenReturn(false);
        Mockito.when(commentService.insert(principal, id, request)).thenReturn(null);

        Response response = controller.comment(id, request, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNAUTHORIZED.getCode(), actual.getCode());
        assertEquals(Result.Error.UNAUTHORIZED.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

    @Test
    public void getCommentsTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        List<CommentDTO> list = new ArrayList<>();
        list.add(CommentMaker.makeCommentDTO());
        list.add(CommentMaker.makeCommentDTO());
        list.get(1).setId(2);
        list.get(1).setText("otherText");
        Page<CommentDTO> expected = Page.unpaged(list);

        Mockito.when(commentService.getByElement(principal, id)).thenReturn(expected);

        Response response = controller.getComments(id, securityContext);
        Page<CommentDTO> actual = ControllerHelper.extractSuccessResult(response, Page.class);
        assertEquals(expected.getSize(), actual.getSize());
        assertEquals(expected.getPage(), actual.getPage());
        assertEquals(expected.getTotal(), actual.getTotal());
        assertEquals(expected.getList().size(), actual.getList().size());
        assertEquals(expected.getList(), actual.getList());
    }

    @Test
    public void getCommentsNoUserTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();
        List<CommentDTO> list = new ArrayList<>();
        list.add(CommentMaker.makeCommentDTO());
        list.add(CommentMaker.makeCommentDTO());
        list.get(1).setId(2);
        list.get(1).setText("otherText");
        Page<CommentDTO> expected = Page.unpaged(list);

        Mockito.when(commentService.getByElement(null, id)).thenReturn(expected);

        Response response = controller.getComments(id, securityContext);
        Page<CommentDTO> actual = ControllerHelper.extractSuccessResult(response, Page.class);
        assertEquals(expected.getSize(), actual.getSize());
        assertEquals(expected.getPage(), actual.getPage());
        assertEquals(expected.getTotal(), actual.getTotal());
        assertEquals(expected.getList().size(), actual.getList().size());
        assertEquals(expected.getList(), actual.getList());
    }

    @Test
    public void invlalidIdGetCommentsTest() {
        long id = -8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.getComments(id, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.INVALID_ID));
    }

    @Test
    public void failGetCommentsTest() {
        long id = 8;
        UserDTO user = UserMaker.makeUserDTO();
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Mockito.when(commentService.getByElement(user, id)).thenReturn(null);

        Response response = controller.getComments(id, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNABLE_TO_GET_DATA.getCode(), actual.getCode());
        assertEquals(Result.Error.UNABLE_TO_GET_DATA.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

    @Test
    public void getCommentPageTest() {
        long id = 8;
        int page = 1;
        int size = 2;
        long total = 5;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        List<CommentDTO> list = new ArrayList<>();
        list.add(CommentMaker.makeCommentDTO());
        list.add(CommentMaker.makeCommentDTO());
        list.get(1).setId(2);
        list.get(1).setText("otherText");
        Page<CommentDTO> expected = Page.paged(page, total, list);

        Mockito.when(commentService.getByElement(principal, page, size, id)).thenReturn(expected);

        Response response = controller.getCommentsPage(id, page, size, securityContext);
        Page<CommentDTO> actual = ControllerHelper.extractSuccessResult(response, Page.class);
        assertEquals((Integer) size, actual.getSize());
        assertEquals((Integer) page, actual.getPage());
        assertEquals(total, actual.getTotal());
        assertEquals(expected.getList().size(), actual.getList().size());
        assertEquals(expected.getList(), actual.getList());
    }

    @Test
    public void getCommentPageNoUserTest() {
        long id = 8;
        int page = 1;
        int size = 2;
        long total = 5;
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();
        List<CommentDTO> list = new ArrayList<>();
        list.add(CommentMaker.makeCommentDTO());
        list.add(CommentMaker.makeCommentDTO());
        list.get(1).setId(2);
        list.get(1).setText("otherText");
        Page<CommentDTO> expected = Page.paged(page, total, list);

        Mockito.when(commentService.getByElement(null, page, size, id)).thenReturn(expected);

        Response response = controller.getCommentsPage(id, page, size, securityContext);
        Page<CommentDTO> actual = ControllerHelper.extractSuccessResult(response, Page.class);
        assertEquals((Integer) size, actual.getSize());
        assertEquals((Integer) page, actual.getPage());
        assertEquals(total, actual.getTotal());
        assertEquals(expected.getList().size(), actual.getList().size());
        assertEquals(expected.getList(), actual.getList());
    }

    @Test
    public void invalidIdGetCommentsPageTest() {
        int id = -8;
        int page = 1;
        int size = 2;
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.getCommentsPage(id, page, size, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.INVALID_ID));
    }

    @Test
    public void invalidPageGetCommentsPageTest() {
        int id = 8;
        int page = 0;
        int size = 2;
        SecurityContext securityContext = UserMaker.makeSecurityContext();

        Response response = controller.getCommentsPage(id, page, size, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.INVALID_REQUEST.getCode(), actual.getCode());
        assertEquals(Result.Error.INVALID_REQUEST.getMessage(), actual.getMessage());
        assertEquals(1, actual.getTrace().size());
        assertTrue(actual.getTrace().contains(Constant.PAGE_NUMBER_INVALID));
    }

    @Test
    public void failGetCommentsPageTest() {
        long id = 8;
        int page = 1;
        int size = 2;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();

        Mockito.when(commentService.getByElement(principal, page, size, id)).thenReturn(null);

        Response response = controller.getCommentsPage(id, page, size, securityContext);
        ErrorDTO actual = ControllerHelper.extractErrorResult(response);
        assertEquals(Result.Error.UNABLE_TO_GET_DATA.getCode(), actual.getCode());
        assertEquals(Result.Error.UNABLE_TO_GET_DATA.getMessage(), actual.getMessage());
        assertTrue(actual.getTrace().isEmpty());
    }

}
