Java tutorial
/* * 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()); } } }