/* * Copyright 2019 Arcus Project * * 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 com.iris.client.server.rest; import java.util.Arrays; import java.util.List; import java.util.UUID; import org.easymock.Capture; import org.easymock.CaptureType; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import com.google.common.util.concurrent.Futures; import com.google.inject.Inject; import com.iris.bridge.metrics.BridgeMetrics; import com.iris.bridge.server.client.Client; import com.iris.bridge.server.client.ClientFactory; import com.iris.bridge.server.netty.Authenticator; import com.iris.core.dao.MobileDeviceDAO; import com.iris.core.dao.PersonDAO; import com.iris.core.platform.PlatformMessageBus; import com.iris.io.json.JSON; import com.iris.messages.ClientMessage; import com.iris.messages.ErrorEvent; import com.iris.messages.MessageBody; import com.iris.messages.MessageConstants; import com.iris.messages.PlatformMessage; import com.iris.messages.address.Address; import com.iris.messages.capability.NotificationCapability; import com.iris.messages.capability.NotificationCapability.NotifyRequest; import com.iris.messages.model.Fixtures; import com.iris.messages.model.MobileDevice; import com.iris.messages.model.Person; import com.iris.messages.service.SessionService; import com.iris.messages.service.SessionService.LockDeviceRequest; import com.iris.messages.services.PlatformConstants; import com.iris.messages.type.Population; import com.iris.population.PlacePopulationCacheManager; import com.iris.test.IrisMockTestCase; import com.iris.test.Mocks; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.local.LocalChannel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.cookie.DefaultCookie; import io.netty.util.CharsetUtil; @RunWith(value = Parameterized.class) @Mocks({ PersonDAO.class, MobileDeviceDAO.class, FullHttpRequest.class, ChannelHandlerContext.class, PlatformMessageBus.class, ClientFactory.class, Client.class, Authenticator.class, BridgeMetrics.class, PlacePopulationCacheManager.class}) public class TestLockDeviceRESTHandler extends IrisMockTestCase { @Inject protected PlacePopulationCacheManager mockPopulationCacheMgr; @Inject private PersonDAO personDao; @Inject private MobileDeviceDAO mobileDeviceDao; @Inject private ClientFactory clientFactory; private Channel channel = new LocalChannel(); @Inject private Client client; @Inject private Authenticator authenticator; @Inject private LockDeviceRESTHandler handler; @Inject private FullHttpRequest request; @Inject private ChannelHandlerContext ctx; @Inject private PlatformMessageBus platformBus; private Person curLoggedPerson = null; //private UUID curLoggedInPerson = UUID.randomUUID(); @Parameters(name="deviceIdentifier[{0}],reason[{1}],success[{2}],personMatch[{3}]") public static List<Object []> files() { return Arrays.<Object[]>asList( new Object [] { "12345", LockDeviceRequest.REASON_TOUCH_FAILED, true, true}, new Object [] { "12345", LockDeviceRequest.REASON_USER_REQUESTED, true, true}, new Object [] { "12345", "BadReason", false, true}, //reason not valid new Object [] { "12345", LockDeviceRequest.REASON_TOUCH_FAILED, false, false} //person id not match ); } private final String deviceIdentifier; private final String reason; private final boolean isSuccess; private final boolean personMatch; @Before public void setupMocks() { EasyMock.expect(mockPopulationCacheMgr.getPopulationByPlaceId(EasyMock.anyObject(UUID.class))).andReturn(Population.NAME_GENERAL).anyTimes(); } public TestLockDeviceRESTHandler(String deviceIdentifier, String reason, boolean isSuccess, boolean personMatch) { this.deviceIdentifier = deviceIdentifier; this.reason = reason; this.isSuccess = isSuccess; this.personMatch = personMatch; curLoggedPerson = Fixtures.createPerson(); curLoggedPerson.setId(UUID.randomUUID()); } @Test public void testLockDeviceRequest() throws Exception { FullHttpResponse response = callLockDeviceRequest(deviceIdentifier, reason, isSuccess, personMatch); MessageBody mb = toClientRequest(response); if(isSuccess) { assertEquals(MessageConstants.MSG_EMPTY_MESSAGE, mb.getMessageType()); }else{ assertEquals(ErrorEvent.MESSAGE_TYPE, mb.getMessageType()); } } private FullHttpResponse callLockDeviceRequest(String curDeviceId, String curReason, boolean curSuccess, boolean curPersonMatch) throws Exception { EasyMock.expect(client.getPrincipalId()).andReturn(curLoggedPerson.getId()).anyTimes(); EasyMock.expect(request.content()).andReturn(Unpooled.copiedBuffer(generateClientMessage(generateRequest(curDeviceId, curReason)).getBytes())); EasyMock.expect(ctx.channel()).andReturn(channel).anyTimes(); EasyMock.expect(clientFactory.get(channel)).andReturn(client).anyTimes(); Capture<PlatformMessage> platformMsgCapture = EasyMock.newCapture(CaptureType.ALL); EasyMock.expect(platformBus.send(EasyMock.capture(platformMsgCapture))).andAnswer( () -> { return Futures.immediateFuture(null); } ).anyTimes(); MobileDevice mobileDevice = new MobileDevice(); mobileDevice.setDeviceIdentifier(curDeviceId); if(curPersonMatch) { mobileDevice.setPersonId(curLoggedPerson.getId()); mobileDeviceDao.delete(mobileDevice); EasyMock.expectLastCall(); EasyMock.expect(personDao.findById(curLoggedPerson.getId())).andReturn(curLoggedPerson); }else{ mobileDevice.setPersonId(UUID.randomUUID()); } EasyMock.expect(mobileDeviceDao.findWithToken(curDeviceId)).andReturn(mobileDevice); //logout always needs to be called client.logout(); EasyMock.expectLastCall(); EasyMock.expect(authenticator.expireCookie()).andReturn(new DefaultCookie("test", "test")); replay(); FullHttpResponse response = handler.respond(request, ctx); if(curSuccess) { //notification needs to be sent PlatformMessage msg = platformMsgCapture.getValue(); assertNotificationSent(msg); } return response; } private void assertNotificationSent(PlatformMessage msg) { assertNotNull(msg.getValue()); assertEquals(NotificationCapability.NAMESPACE, msg.getDestination().getGroup()); assertEquals(NotifyRequest.NAME, msg.getMessageType()); } private MessageBody toClientRequest(FullHttpResponse response) { String json = response.content().toString(CharsetUtil.UTF_8); ClientMessage clientMessage = JSON.fromJson(json, ClientMessage.class); return clientMessage.getPayload(); } private MessageBody generateRequest(String deviceIdentifier, String reason) { return SessionService.LockDeviceRequest.builder().withDeviceIdentifier(deviceIdentifier).withReason(reason).build(); } private String generateClientMessage(MessageBody body) { ClientMessage.Builder messageBuilder = ClientMessage.builder().withCorrelationId("").withSource(Address.platformService(PlatformConstants.SERVICE_PEOPLE).getRepresentation()).withPayload(body); return JSON.toJson(messageBuilder.create()); } }