package com.wishurgift.entry.controller;

import com.wishurgift.helper.ControllerHelper;
import com.wishurgift.helper.StatisticMaker;
import com.wishurgift.helper.UserMaker;
import com.wishurgift.service.StatisticService;
import com.wishurgift.service.dto.ErrorDTO;
import com.wishurgift.service.dto.StatisticDTO;
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 StatisticControllerTest {

    @Mock
    private StatisticService statisticService;

    @InjectMocks
    private StatisticController controller;

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

    @Test
    public void statsTest() {
        long id = 8;
        SecurityContext securityContext = UserMaker.makeSecurityContext();
        UserDTO principal = UserMaker.makeUserDTO();
        StatisticDTO expected = StatisticMaker.makeStatisticDTO();

        Mockito.when(statisticService.getStatistic(principal, id)).thenReturn(expected);

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

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

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

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

        Mockito.when(statisticService.getStatistic(principal, id)).thenReturn(null);

        Response response = controller.stats(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());
    }

}
