/****************************************************************************
* Copyright Avaya Inc., All Rights Reserved.
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Avaya Inc.
* The copyright notice above does not evidence any actual or intended publication of such source code.
* Some third-party source code components may have been modified from their original versions by Avaya Inc.
* The modifications are Copyright Avaya Inc., All Rights Reserved.
* Avaya Confidential & Restricted. May not be distributed further without written permission of
* the Avaya owner.
****************************************************************************/
package com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.resource;

import static com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.util.Feature.CREATE_STANDARD;
import static com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.util.Feature.DELETE_STANDARD;
import static com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.util.Feature.LISTALL_STANDARD;
import static com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.util.Feature.LIST_STANDARD;
import static com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.util.Feature.UPDATE_STANDARD;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Response;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import com.avaya.collaboration.authorization.AuthorizationHelperException;
import com.avaya.collaboration.authorization.resource.AuthorizationData;
import com.avaya.collaboration.authorization.resource.AuthorizationResourceHelper;
import com.avaya.collaboration.authorization.resource.AuthorizationScope;
import com.avaya.collaboration.authorization.spi.ResourceHelperProvider;
import com.avaya.collaboration.util.logger.Logger;
import com.avaya.zephyr.common.testutils.deencapsulation.Deencapsulation;
import com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.holder.TaskHolder;
import com.avaya.zephyr.services.sample_services.Authorization.TaskRepository.json.Task;
import com.google.gson.GsonBuilder;

@RunWith(MockitoJUnitRunner.class)
public final class TaskResourceTest
{
    private static final String BEARER_TOKEN = "bearerToken";
    TaskResource taskResource;
    @Mock
    ResourceHelperProvider resourceHelperDelegateMock;
    @Mock
    AuthorizationData authorizationDataMock;
    @Mock
    AuthorizationScope authorizationScopeMock;
    @Mock
    HttpServletRequest requestMock;
    @Mock
    Logger loggerMock;

    @Before
    public void before()
    {
        taskResource = new TaskResource(TaskHolder.getInstance(),
                new GsonBuilder().setPrettyPrinting().create(), loggerMock);
        final Task task = new Task("taskId", "userId", "title", "description", false,
                new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date()));
        TaskHolder.getInstance().addTask(task);
        Deencapsulation.setField(AuthorizationResourceHelper.class, "resourceHelperDelegate",
                resourceHelperDelegateMock);
    }

    @After
    public void after()
    {
        TaskHolder.getInstance().deleteTask("userId", "taskId");
    }

    @Test
    public void getTasks_NoBearerToken_200OK()
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn(null);
        final Response response = taskResource.getTasks(requestMock);
        assertEquals(200, response.getStatus());
    }

    @Test
    public void getTasks_RequestWithValidScopeList_200OK() throws Exception
    {
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { LISTALL_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(LISTALL_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        final Response response = taskResource.getTasks(requestMock);
        assertEquals(200, response.getStatus());
    }

    @Test
    public void getTasks_RequestWithInvalidScopeList_401() throws Exception
    {
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { "InvalidFeatureValue" });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn("InvalidFeatureName");
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        final Response response = taskResource.getTasks(requestMock);
        assertEquals(403, response.getStatus());
    }

    @Test
    public void getTasks_AuthorizationHelperException_500() throws Exception
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token"))
                .thenThrow(new AuthorizationHelperException("AuthorizationHelperException"));
        final Response response = taskResource.getTasks(requestMock);
        assertEquals(500, response.getStatus());
    }

    @Test
    public void getTaskByUserId_NoBearerToken_401()
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn(null);
        final Response response = taskResource.getTasks(requestMock);
        assertEquals(200, response.getStatus());
    }

    @Test
    public void getTaskByUserId_RequestWithInvalidScopeList_401() throws Exception
    {
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { "InvalidFeatureValue" });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn("InvalidFeatureName");
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        final Response response = taskResource.getTaskByUserId(requestMock, "user");
        assertEquals(403, response.getStatus());
    }

    @Test
    public void getTaskByUserId_RequestWithValidScopeListValidUser_200OK() throws Exception
    {
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { LIST_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock)
                .thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(LIST_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId");
        final Response response = taskResource.getTaskByUserId(requestMock, "userId");
        assertEquals(200, response.getStatus());
    }

    @Test
    public void getTaskByUserId_RequestWithValidScopeListInvalidUser_401() throws Exception
    {
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { LIST_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock)
                .thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(LIST_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId");
        final Response response = taskResource.getTaskByUserId(requestMock, "userId1");
        assertEquals(403, response.getStatus());
    }

    @Test
    public void getTaskByUserId_NoTaskFoundForUser_400() throws Exception
    {
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { LIST_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock)
                .thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(LIST_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId1");
        final Response response = taskResource.getTaskByUserId(requestMock, "userId1");
        assertEquals(200, response.getStatus());
    }

    @Test
    public void getTaskByUserId_AuthorizationHelperException_500() throws Exception
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token"))
                .thenThrow(new AuthorizationHelperException("AuthorizationHelperException"));
        final Response response = taskResource.getTaskByUserId(requestMock, "user");
        assertEquals(500, response.getStatus());
    }

    @Test
    public void create_NoBearerToken_401()
    {
        final Task task = new Task("taskId", "userId", "title", "description", false,
                new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date()));
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn(null);
        final Response response = taskResource.create(requestMock, "user", task);
        assertEquals(403, response.getStatus());
    }

    @Test
    public void create_RequestWithInvalidScopeList_403() throws Exception
    {
        final Task task = new Task("taskId", "userId", "title", "description", false,
                new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date()));
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { "InvalidFeatureValue" });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn("InvalidFeatureName");
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        final Response response = taskResource.create(requestMock, "user", task);
        assertEquals(403, response.getStatus());
    }

    @Test
    public void create_RequestWithValidScopeListValidUser_200OK() throws Exception
    {
        final Task task = new Task("taskId", "userId", "title", "description", false,
                new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date()));
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { CREATE_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock)
                .thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(CREATE_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId123");
        when(requestMock.getParameter("title")).thenReturn("title");
        final Response response = taskResource.create(requestMock, "userId123", task);
        assertEquals(200, response.getStatus());
    }

    @Test
    public void create_RequestWithValidScopeListValidUserNoTitle_400() throws Exception
    {
        final Task task = new Task("taskId", "userId", null, "description", false,
                new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date()));
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { CREATE_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock)
                .thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(CREATE_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId123");
        final Response response = taskResource.create(requestMock, "userId123", task);
        assertEquals(400, response.getStatus());
    }

    @Test
    public void create_RequestWithValidScopeListInvalidUser_401() throws Exception
    {
        final Task task = new Task("taskId", "userId", "title", "description", false,
                new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date()));
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { CREATE_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock)
                .thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(CREATE_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId123");
        final Response response = taskResource.create(requestMock, "userId1234", task);
        assertEquals(403, response.getStatus());
    }

    @Test
    public void create_AuthorizationHelperException_500() throws Exception
    {
        final Task task = new Task("taskId", "userId", "title", "description", false,
                new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date()));
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token"))
                .thenThrow(new AuthorizationHelperException("AuthorizationHelperException"));
        final Response response = taskResource.create(requestMock, "user", task);
        assertEquals(500, response.getStatus());
    }

    @Test
    public void delete_NoUserId_400()
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        final Response response = taskResource.delete(requestMock, null, "taskId");
        assertEquals(400, response.getStatus());
    }

    @Test
    public void delete_NoTaskId_400()
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        final Response response = taskResource.delete(requestMock, "userId", null);
        assertEquals(400, response.getStatus());
    }

    @Test
    public void delete_NoBearerToken_401()
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn(null);
        final Response response = taskResource.delete(requestMock, "user", "task");
        assertEquals(403, response.getStatus());
    }

    @Test
    public void delete_RequestWithValidScopeList_200OK() throws Exception
    {
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { DELETE_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock)
                .thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(DELETE_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId");
        final Response response = taskResource.delete(requestMock, "userId", "taskId");
        assertEquals(200, response.getStatus());
    }

    @Test
    public void delete_NoTaskToDelete_403() throws Exception
    {
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { DELETE_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock)
                .thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(DELETE_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId11");
        final Response response = taskResource.delete(requestMock, "userId11", "taskId");
        assertEquals(403, response.getStatus());
    }

    @Test
    public void delete_AuthorizationHelperException_500() throws Exception
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token"))
                .thenThrow(new AuthorizationHelperException("AuthorizationHelperException"));
        final Response response = taskResource.delete(requestMock, "user", "task");
        assertEquals(500, response.getStatus());
    }

    @Test
    public void update_NoUserId_400()
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        final Response response = taskResource.update(requestMock, null, "taskId", null);
        assertEquals(400, response.getStatus());
    }

    @Test
    public void update_NoTaskId_400()
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        final Response response = taskResource.update(requestMock, "userId", "", null);
        assertEquals(400, response.getStatus());
    }

    @Test
    public void update_NoTaskToUpdate_400()
    {
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        final Response response = taskResource.update(requestMock, "userId", "taskId", null);
        assertEquals(400, response.getStatus());
    }

    @Test
    public void update_DifferentUserToUpdate_400()
    {
        final Task task = new Task("taskId", "userId", "title", "description", false, "createdAtString");
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        final Response response = taskResource.update(requestMock, "user", "task", task);
        assertEquals(400, response.getStatus());
    }

    @Test
    public void update_NoBearerToken_401()
    {
        final Response response = taskResource.update(requestMock, "userId", "taskId", null);
        assertEquals(403, response.getStatus());
    }

    @Test
    public void update_NotAuthorized_401() throws Exception
    {
        final Task task = new Task("taskId", "userId", "title", "description", false, "createdAtString");
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { "InvalidFeatureValue" });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn("InvalidFeatureName");
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        final Response response = taskResource.update(requestMock, "userId", "taskId", task);
        assertEquals(403, response.getStatus());
    }

    @Test
    public void update_NoTaskFoundtoUpdate_403() throws Exception
    {
        TaskHolder.getInstance().deleteTask("userId", "taskId");
        final Task task = new Task("taskId", "userId", "title", "description", false, "createdAtString");
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { UPDATE_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(UPDATE_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId");
        final Response response = taskResource.update(requestMock, "userId", "taskId", task);
        assertEquals(403, response.getStatus());
    }

    @Test
    public void update_AuthorizationHelperException_500() throws Exception
    {
        final Task task = new Task("taskId", "userId", "title", "description", false, "createdAtString");
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token"))
                .thenThrow(new AuthorizationHelperException("AuthorizationHelperException"));
        final Response response = taskResource.update(requestMock, "userId", "taskId", task);
        assertEquals(500, response.getStatus());
    }

    @Test
    public void update_SuccessfulUpdate_200() throws Exception
    {
        final Task task = new Task("taskId", "userId", "title", "description", false, "createdAtString");
        final List<AuthorizationScope> clientScopeList = new ArrayList<AuthorizationScope>();
        clientScopeList.add(authorizationScopeMock);
        List<String> featureValues = Arrays.asList(new String[]
        { UPDATE_STANDARD.getFeatureValue() });
        when(requestMock.getAttribute(BEARER_TOKEN)).thenReturn("token");
        when(resourceHelperDelegateMock.getAuthorizationData("token")).thenReturn(authorizationDataMock);
        when(authorizationDataMock.getClientScopeList()).thenReturn(clientScopeList);
        when(authorizationScopeMock.getFeatureName()).thenReturn(UPDATE_STANDARD.getFeatureName());
        when(authorizationScopeMock.getFeatureValues()).thenReturn(featureValues);
        when(authorizationDataMock.getSubject()).thenReturn("userId");
        final Response response = taskResource.update(requestMock, "userId", "taskId", task);
        assertEquals(200, response.getStatus());
    }
}
