edu.byu.mpn.test.DeviceControllerUnitTest.java Source code

Java tutorial

Introduction

Here is the source code for edu.byu.mpn.test.DeviceControllerUnitTest.java

Source

/*
 *   Copyright 2016 Brigham Young University
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package edu.byu.mpn.test;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import edu.byu.jwt.domain.CasUser;
import edu.byu.jwt.domain.Wso2SubscribedClient;
import edu.byu.jwt.spring.domain.JwtUserDetails;
import edu.byu.mpn.da.interfaces.DeviceDao;
import edu.byu.mpn.domain.Device;
import edu.byu.mpn.helpers.ResponseMessage;
import edu.byu.mpn.rest.DeviceController;
import edu.byu.mpn.test.helpers.TestMpnClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;

import javax.ws.rs.core.Response;
import java.util.*;

import static org.junit.Assert.*;

/**
 * Created by cwoodfie on 4/12/16.
 */

@RunWith(JUnit4.class)
@SuppressWarnings("unchecked")
public class DeviceControllerUnitTest {
    private static final Logger LOG = LogManager.getLogger(DeviceControllerUnitTest.class);
    private static final Authentication AUTHENTICATION = new Authentication() {
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return null;
        }

        @Override
        public Object getCredentials() {
            return null;
        }

        @Override
        public Object getDetails() {
            return null;
        }

        @Override
        public Object getPrincipal() {
            Wso2SubscribedClient client = new Wso2SubscribedClient();
            CasUser clientOwner = new CasUser();
            clientOwner.setPersonId("admin");
            CasUser resourceOwner = new CasUser();
            resourceOwner.setPersonId("user");
            ArrayList<GrantedAuthority> resourceOwnerAuthorities = new ArrayList<GrantedAuthority>();
            resourceOwnerAuthorities.add(new GrantedAuthority() {
                @Override
                public String getAuthority() {
                    return "GRO_BYU_MPN_ADMIN";
                }
            });
            return new JwtUserDetails(client, clientOwner, resourceOwner, null, resourceOwnerAuthorities);
        }

        @Override
        public boolean isAuthenticated() {
            return false;
        }

        @Override
        public void setAuthenticated(boolean b) throws IllegalArgumentException {

        }

        @Override
        public String getName() {
            return null;
        }
    };
    private DeviceController controller;
    private DeviceDao deviceDao;
    private static final String VALID_TOKEN = "valid";
    private static final String VALID_TOKEN_2 = "valid2";

    @Before
    public void setup() {
        controller = new DeviceController();
        controller.setDeviceDao(deviceDao = new TestDeviceDao());
        controller.setMpnClient(new TestMpnClient());
        SecurityContextHolder.getContext().setAuthentication(AUTHENTICATION);
    }

    @Test
    public void testGetAllDevices() {
        //      Tests that empty database is empty
        assertTrue(((List<Device>) controller.getAllDevices("").getEntity()).isEmpty());
        assertTrue(((List<Device>) (controller.getAllDevices("personId1").getEntity())).isEmpty());

        //      Tests that database with one item has one item
        deviceDao.saveOrUpdateDevice(
                new Device(1, "deviceId1", "personId1", "token1", "corey's jPhone", "Android", null, null, null),
                "romrell4");
        assertEquals(1, ((List<Device>) controller.getAllDevices("").getEntity()).size());
        assertEquals(1, ((List<Device>) controller.getAllDevices("personId1").getEntity()).size());

        //      Tests that there is more than one device
        deviceDao.saveOrUpdateDevice(new Device(2, null, null, null, null, null, null, null, null), "romrell4");
        assertEquals(2, ((List<Device>) controller.getAllDevices("").getEntity()).size());
        assertEquals(1, ((List<Device>) controller.getAllDevices("personId1").getEntity()).size());
    }

    @Test
    public void testGetDeviceById() {
        //      Tests that controller returns 404 when device doesn't exist
        Response response = controller.getDeviceById(1, "");
        assertEquals(404, response.getStatus());
        assertEquals(404, controller.getDeviceById(2, "").getStatus());

        deviceDao.saveOrUpdateDevice(
                new Device(1, "deviceId1", "personId1", "token1", "corey's jPhone", "Android", null, null, null),
                "romrell4");
        //      Tests that controller returns 403 when user is unauthorized to access it
        response = controller.getDeviceById(1, "");
        assertEquals(403, response.getStatus());
        assertTrue(DeviceController.EX_NACHO_DEVICE.equals(((ResponseMessage) response.getEntity()).getMessage()));

        //      Tests that controller returns 200 when device does exist
        response = controller.getDeviceById(1, "personId1");
        assertEquals(200, response.getStatus());
        assertTrue("personId1".equals(((Device) response.getEntity()).getPersonId()));
        assertTrue("deviceId1".equals(((Device) response.getEntity()).getDeviceId()));
        assertTrue("corey's jPhone".equals(((Device) response.getEntity()).getDeviceName()));
    }

    @Test
    public void testCreateDevice() {
        //      Tests that proper error responses are returned for invalid requests
        //      null device
        Response response = controller.createDevice(null, false, null);
        assertEquals(400, response.getStatus());
        assertTrue(DeviceController.EX_EMPTY_REQUEST.equals(((ResponseMessage) response.getEntity()).getMessage()));
        //      Parameters missing
        assertEquals(400, controller
                .createDevice("personId", false, new Device(null, "personId", "token", "deviceName", "Android"))
                .getStatus());
        assertEquals(400, controller
                .createDevice("personId", false, new Device("deviceId", null, "token", "deviceName", "Android"))
                .getStatus());
        assertEquals(400, controller
                .createDevice("personId", false, new Device("deviceId", "personId", null, "deviceName", "Android"))
                .getStatus());
        assertEquals(400, controller
                .createDevice("personId", false, new Device("deviceId", "personId", "token", null, "Android"))
                .getStatus());
        assertEquals(400, controller
                .createDevice("personId", false, new Device("deviceId", "personId", "token", "deviceName", null))
                .getStatus());
        //      Invalid token
        assertEquals(400,
                controller
                        .createDevice("personId", false,
                                new Device("deviceId", "personId", "invalidTokenForApple", "deviceName", "Apple"))
                        .getStatus());
        //      PersonId doesn't match loggedInPersonId
        response = controller.createDevice("notPersonId", false,
                new Device("deviceId", "personId", "token", "deviceName", "Android"));
        assertEquals(403, response.getStatus());
        assertTrue(
                DeviceController.EX_NACHO_PERSONID.equals(((ResponseMessage) response.getEntity()).getMessage()));
        //      Invalid devicePlatform
        response = controller.createDevice("personId", false,
                new Device("deviceId", "personId", "token", "deviceName", "Windows"));
        assertEquals(501, response.getStatus());
        assertTrue(DeviceController.EX_UNSUPPORTED_PLATFORM
                .equals(((ResponseMessage) response.getEntity()).getMessage()));

        //      Tests that a valid request correctly creates a device
        response = controller.createDevice("personId", false,
                new Device("deviceId", "personId", "valid", "deviceName", "Android"));
        Device device = (Device) response.getEntity();
        assertEquals(201, response.getStatus());
        assertNotNull(device);
        assertNotNull(device.getId());
        assertNotNull(device.getDeviceId());
        assertNotNull(device.getPersonId());
        assertNotNull(device.getToken());
        assertNotNull(device.getEndpointArn());
        assertNotNull(device.getSubscriptionArn());
        assertNotNull(device.getDeviceName());
        assertNotNull(device.getDevicePlatform());
        assertNotNull(device.getDateRegistered());
        assertNotNull(device.getDateTimeUpdated());
        assertNotNull(device.getUpdatedById());
        //      Nothing should be null on Apple, endpointArn and subscriptionArn should be null on Android
        response = controller.createDevice("personId", false,
                new Device("deviceId", "personId", VALID_TOKEN_2, "deviceName", "Apple"));
        device = (Device) response.getEntity();
        assertEquals(201, response.getStatus());
        assertNotNull(device);
        assertNotNull(device.getId());
        assertNotNull(device.getDeviceId());
        assertNotNull(device.getPersonId());
        assertNotNull(device.getToken());
        assertNotNull(device.getEndpointArn());
        assertNotNull(device.getSubscriptionArn());
        assertNotNull(device.getDeviceName());
        assertNotNull(device.getDevicePlatform());
        assertNotNull(device.getDateRegistered());
        assertNotNull(device.getDateTimeUpdated());
        assertNotNull(device.getUpdatedById());
        //      Returns 200 when Device already exists
        response = controller.createDevice("personId", false,
                new Device("deviceId", "personId", VALID_TOKEN_2, "deviceName", "Apple"));
        assertEquals(200, response.getStatus());
    }

    @Test
    public void testUpdateDevice() {
        deviceDao.saveOrUpdateDevice(new Device(null, "deviceId", "personId", VALID_TOKEN, "deviceName", "Apple",
                new Date(), null, null), "what");
        Device device = deviceDao.getDeviceById(1);
        Date dateRegistered = device.getDateRegistered();
        Date dateTimeUpdated = device.getDateTimeUpdated();

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            LOG.error(e);
        }

        //      Tests that the proper error responses are returned
        Response response = controller.updateDevice(1, "personId", null);
        assertEquals(400, response.getStatus());
        assertTrue(DeviceController.EX_EMPTY_REQUEST.equals(((ResponseMessage) response.getEntity()).getMessage()));
        response = controller.updateDevice(1, "personId", new Device());
        assertEquals(400, response.getStatus());
        assertTrue(DeviceController.EX_MISSING_ID.equals(((ResponseMessage) response.getEntity()).getMessage()));
        response = controller.updateDevice(1, "personId",
                new Device(null, "personId", VALID_TOKEN, dateTimeUpdated));
        assertEquals(400, response.getStatus());
        assertTrue(DeviceController.EX_MISSING_ID.equals(((ResponseMessage) response.getEntity()).getMessage()));
        response = controller.updateDevice(1, "personId", new Device(2, "personId", VALID_TOKEN, dateTimeUpdated));
        assertEquals(400, response.getStatus());
        assertTrue(DeviceController.EX_ID_CONFLICT.equals(((ResponseMessage) response.getEntity()).getMessage()));
        response = controller.updateDevice(1, "personId", new Device(1, null, VALID_TOKEN, dateTimeUpdated));
        assertEquals(400, response.getStatus());
        assertTrue(
                DeviceController.EX_PERSONID_MISSING.equals(((ResponseMessage) response.getEntity()).getMessage()));
        response = controller.updateDevice(1, "personId", new Device(1, "personId", null, dateTimeUpdated));
        assertEquals(400, response.getStatus());
        assertTrue(DeviceController.EX_TOKEN_MISSING.equals(((ResponseMessage) response.getEntity()).getMessage()));
        assertEquals(400,
                controller.updateDevice(1, "personId", new Device(1, "personId", "invalid token", dateTimeUpdated))
                        .getStatus());
        response = controller.updateDevice(1, "notPersonId",
                new Device(1, "notPersonId", VALID_TOKEN, dateTimeUpdated));
        assertEquals(403, response.getStatus());
        assertTrue(DeviceController.EX_NACHO_DEVICE.equals(((ResponseMessage) response.getEntity()).getMessage()));
        response = controller.updateDevice(1, "notPersonId",
                new Device(1, "personId", VALID_TOKEN, dateTimeUpdated));
        assertEquals(403, response.getStatus());
        assertTrue(
                DeviceController.EX_NACHO_PERSONID.equals(((ResponseMessage) response.getEntity()).getMessage()));
        assertEquals(404,
                controller.updateDevice(2, "personId", new Device(2, "what", "what", new Date())).getStatus());

        //      When personId is changed, dateRegistered is updated
        device.setPersonId(null);
        assertEquals(200,
                controller
                        .updateDevice(1, "notPersonId", new Device(1, "notPersonId", VALID_TOKEN, dateTimeUpdated))
                        .getStatus());
        assertFalse(dateRegistered.equals(device.getDateRegistered()));
        assertFalse(dateTimeUpdated.equals(device.getDateTimeUpdated()));

        //      When device is edited but personId is not changed, dateRegistered stays the same
        dateRegistered = device.getDateRegistered();
        dateTimeUpdated = device.getDateTimeUpdated();

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            LOG.error(e);
        }

        assertEquals(200,
                controller
                        .updateDevice(1, "notPersonId", new Device(1, "notPersonId", VALID_TOKEN, dateTimeUpdated))
                        .getStatus());
        assertTrue(dateRegistered.equals(device.getDateRegistered()));
        assertFalse(dateTimeUpdated.equals(device.getDateTimeUpdated()));
        dateTimeUpdated = device.getDateTimeUpdated();

        //      Extra fields included in device aren't updated, deviceId and deviceName are
        device = deviceDao.getDeviceById(1);
        Device device1 = new Device(device);
        assertEquals(200,
                controller
                        .updateDevice(1, "notPersonId", new Device(1, "deviceId", "notPersonId", VALID_TOKEN,
                                "what", "what", "deviceName", "what", new Date(), dateTimeUpdated, "who"))
                        .getStatus());
        assertTrue(device1.equals(deviceDao.getDeviceById(1)));
        dateTimeUpdated = deviceDao.getDeviceById(1).getDateTimeUpdated();
        assertEquals(200, controller.updateDevice(1, "notPersonId", new Device(1, "notDeviceId", "notPersonId",
                VALID_TOKEN, null, null, "notDeviceName", null, null, dateTimeUpdated, null)).getStatus());
        assertFalse(device1.equals(deviceDao.getDeviceById(1)));
    }

    @Test
    public void testUnregisterDevice() {
        //      Tests that controller returns 404 when device doesn't exist
        Response response = controller.unregisterDevice(1, "personId1");
        assertEquals(404, response.getStatus());

        deviceDao.saveOrUpdateDevice(new Device("deviceId1", "personId1", "token1", "corey's jPhone", "Android"),
                "romrell4");

        //      Tests that controller returns 403 when someone tries to unregister device they don't own
        response = controller.unregisterDevice(1, "");
        assertEquals(403, response.getStatus());
        assertTrue(DeviceController.EX_NACHO_DEVICE.equals(((ResponseMessage) response.getEntity()).getMessage()));
        assertFalse(deviceDao.getAllRegisteredDevices().isEmpty());
        assertNotNull(deviceDao.getDeviceById(1).getPersonId());

        //      Tests that controller returns 200 when device does exist, and that it removes the personId
        response = controller.unregisterDevice(1, "personId1");
        assertEquals(200, response.getStatus());
        assertTrue(deviceDao.getAllRegisteredDevices().isEmpty());
        assertNull(deviceDao.getDeviceById(1).getPersonId());

        //      Tests that controller returns 200 when device is already unregistered
        response = controller.unregisterDevice(1, "");
        assertEquals(200, response.getStatus());
        assertTrue(deviceDao.getAllRegisteredDevices().isEmpty());
        assertNull(deviceDao.getDeviceById(1).getPersonId());
    }

    private class TestDeviceDao implements DeviceDao {
        private Map<Integer, Device> mockDatabase = new HashMap<Integer, Device>();
        private Integer idCounter = 0;

        @Override
        public List<Device> getAllDevices() {
            return new ArrayList<Device>(mockDatabase.values());
        }

        @Override
        public List<Device> getAllRegisteredDevices() {
            return new ArrayList<Device>(Collections2.filter(mockDatabase.values(), new Predicate<Device>() {
                @Override
                public boolean apply(Device device) {
                    return device.getPersonId() != null;
                }
            }));
        }

        @Override
        public List<Device> getAllRegisteredDevicesByPlatform(final String platform) {
            return new ArrayList<Device>(Collections2.filter(mockDatabase.values(), new Predicate<Device>() {
                @Override
                public boolean apply(Device device) {
                    return device.getDevicePlatform().equals(platform);
                }
            }));
        }

        @Override
        public List<Device> getAllDevicesByPersonIdAndPlatform(final String personId, final String platform) {
            return new ArrayList<Device>(Collections2.filter(mockDatabase.values(), new Predicate<Device>() {
                @Override
                public boolean apply(Device device) {
                    return device.getPersonId().equals(personId) && device.getDevicePlatform().equals(platform);
                }
            }));
        }

        @Override
        public List<Device> getAllDevicesByPersonId(final String personId) {
            return new ArrayList<Device>(Collections2.filter(mockDatabase.values(), new Predicate<Device>() {
                @Override
                public boolean apply(Device device) {
                    return personId.equals(device.getPersonId());
                }
            }));
        }

        @Override
        public Device getDeviceById(Integer id) {
            return mockDatabase.get(id);
        }

        @Override
        public List<Device> getAllDevicesWithInvalidToken(List<String> disabledEndpointArns) {
            return null;
        }

        @Override
        public Device getDeviceByTokenAndPlatform(String token, String platform) {
            for (Device device : mockDatabase.values()) {
                if (device.getToken().equals(token) && device.getDevicePlatform().equals(platform)) {
                    return device;
                }
            }
            return null;
        }

        @Override
        public void saveOrUpdateDevice(Device device, String personId) {
            if (device.getId() == null) {
                device.setId(++idCounter);
            }
            device.setUpdatedById(personId);
            device.setDateTimeUpdated(new Date());
            mockDatabase.put(device.getId(), device);
        }

        @Override
        public void deleteDevice(Device device) {
            mockDatabase.remove(device.getId());
        }
    }

}