package com.wishurgift.entry.controller;

import com.wishurgift.helper.ControllerHelper;
import com.wishurgift.helper.ElementMaker;
import com.wishurgift.helper.UserMaker;
import com.wishurgift.service.ImageService;
import com.wishurgift.service.dto.ErrorDTO;
import com.wishurgift.service.dto.ImageDTO;
import com.wishurgift.service.dto.UserDTO;
import com.wishurgift.utils.Constant;
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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class ImageControllerTest {

    @Mock
    ImageService imageService;

    @InjectMocks
    ImageController controller;

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

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

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

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

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

        Response response = controller.delete(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 userNotFoundDeleteTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeInvalidSecurityContext();

        Response response = controller.delete(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 failDeleteTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();

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

        Response response = controller.delete(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 getTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        ImageDTO expected = ElementMaker.makeImageDTO();

        Mockito.when(imageService.getImage(principal, id)).thenReturn(expected);

        Response response = controller.get(id, securityContext);
        ImageDTO actual = ControllerHelper.extractSuccessResult(response, ImageDTO.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(imageService.getImage(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());
    }

}
