From f778702dcd5d4406aa17fad0ea48702df18a0e3c Mon Sep 17 00:00:00 2001 From: Minji Park Date: Tue, 16 Aug 2016 18:08:34 +0900 Subject: [PATCH] add unit tests for invite resource in accout server - test cases for invite resource - add request query check in invite resource Change-Id: I24de60fd3884c64437e35a5c0b1ed29cd5685378 Signed-off-by: Minji Park Reviewed-on: https://gerrit.iotivity.org/gerrit/10499 Reviewed-by: Yeonghun Nam Tested-by: jenkins-iotivity Reviewed-by: jung seungho Reviewed-by: Glen Youngjin Kim Reviewed-by: Jee Hyeok Kim --- .../resources/acl/invite/InviteResource.java | 4 +- .../resources/acl/invite/InviteResourceTest.java | 347 +++++++++++++++++++++ 2 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResourceTest.java diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResource.java index 080eafe..c5bc4b5 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResource.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResource.java @@ -139,7 +139,9 @@ public class InviteResource extends Resource { HashMap> queryParams = request.getUriQueryMap(); - checkQueryException(Constants.REQ_GROUP_ID, queryParams); + checkQueryException( + Arrays.asList(Constants.REQ_UUID_ID, Constants.REQ_GROUP_ID), + queryParams); String gid = queryParams.get(Constants.REQ_GROUP_ID).get(0); String uid = queryParams.get(Constants.REQ_UUID_ID).get(0); diff --git a/cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResourceTest.java b/cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResourceTest.java new file mode 100644 index 0000000..b214564 --- /dev/null +++ b/cloud/account/src/test/java/org/iotivity/cloud/accountserver/resources/acl/invite/InviteResourceTest.java @@ -0,0 +1,347 @@ +/* + * //****************************************************************** + * // + * // Copyright 2016 Samsung Electronics All Rights Reserved. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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 org.iotivity.cloud.accountserver.resources.acl.invite; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.concurrent.CountDownLatch; + +import org.iotivity.cloud.accountserver.Constants; +import org.iotivity.cloud.accountserver.db.MongoDB; +import org.iotivity.cloud.base.device.CoapDevice; +import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException; +import org.iotivity.cloud.base.protocols.IRequest; +import org.iotivity.cloud.base.protocols.IResponse; +import org.iotivity.cloud.base.protocols.MessageBuilder; +import org.iotivity.cloud.base.protocols.coap.CoapRequest; +import org.iotivity.cloud.base.protocols.coap.CoapResponse; +import org.iotivity.cloud.base.protocols.enums.ContentFormat; +import org.iotivity.cloud.base.protocols.enums.Observe; +import org.iotivity.cloud.base.protocols.enums.RequestMethod; +import org.iotivity.cloud.base.protocols.enums.ResponseStatus; +import org.iotivity.cloud.util.Cbor; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +public class InviteResourceTest { + private static final String INVITE_URI = "/.well-known/ocf/acl/invite"; + + private static final String TEST_INVITE_USER = "u0001"; + private static final String TEST_INVITED_USER = "u0002"; + private static final String TEST_GROUP_ID = "g0001"; + + private InviteResource mInviteResource = null; + + private CountDownLatch mLatch = null; + + private CoapDevice mMockDevice = null; + private IResponse mResponse = null; + + private Cbor> mCbor = new Cbor<>(); + + @Before + public void setUp() throws Exception { + + mInviteResource = new InviteResource(); + + mLatch = new CountDownLatch(1); + + mMockDevice = Mockito.mock(CoapDevice.class); + + mResponse = null; + + // reset data base + MongoDB mongoDB = new MongoDB(Constants.DB_NAME); + mongoDB.deleteTable(Constants.INVITE_TABLE); + mongoDB.createTable(Constants.INVITE_TABLE); + + Mockito.doAnswer(new Answer() { + @Override + public CoapResponse answer(InvocationOnMock invocation) + throws Throwable { + Object[] args = invocation.getArguments(); + CoapResponse resp = (CoapResponse) args[0]; + mResponse = resp; + + mLatch.countDown(); + + return resp; + } + }).when(mMockDevice).sendResponse(Mockito.anyObject()); + + } + + @Test + public void testSendInvitation() throws Exception { + + sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER); + + assertTrue(mLatch.await(1L, SECONDS)); + assertEquals(mResponse.getStatus(), ResponseStatus.CHANGED); + } + + @Test(expected = PreconditionFailedException.class) + public void testSendInvitationWithoutGid() throws Exception { + + sendInvitation(null, TEST_INVITED_USER); + } + + @Test(expected = PreconditionFailedException.class) + public void testSendInvitationWithoutMid() throws Exception { + + sendInvitation(TEST_GROUP_ID, null); + } + + @Test + public void testInviteUserObserveInvition() throws Exception { + + CountDownLatch latchInviteUser = new CountDownLatch(2); + + CoapDevice mockInviteUser = mock(CoapDevice.class); + + // invite user callback + Mockito.doAnswer(new Answer() { + @Override + public CoapResponse answer(InvocationOnMock invocation) + throws Throwable { + Object[] args = invocation.getArguments(); + CoapResponse resp = (CoapResponse) args[0]; + + latchInviteUser.countDown(); + + // check observe notification response + if (latchInviteUser.getCount() == 0) { + + assertEquals(resp.getStatus(), ResponseStatus.CONTENT); + assertTrue(checkResponsePayload(resp, Constants.RESP_INVITE)); + assertTrue(checkInviteInfo(resp.getPayload(), + Constants.RESP_INVITE, TEST_GROUP_ID, + TEST_INVITED_USER)); + } + + return resp; + } + }).when(mockInviteUser).sendResponse(Mockito.anyObject()); + + getInvitation(TEST_INVITE_USER, mockInviteUser, Observe.SUBSCRIBE); + sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER); + + assertTrue(latchInviteUser.await(2L, SECONDS)); + } + + @Test + public void testInvitedUserObserveInvitation() throws Exception { + + CountDownLatch latchInvitedUser = new CountDownLatch(2); + + CoapDevice mockInvitedUser = mock(CoapDevice.class); + + // invited user callback + Mockito.doAnswer(new Answer() { + @Override + public CoapResponse answer(InvocationOnMock invocation) + throws Throwable { + Object[] args = invocation.getArguments(); + CoapResponse resp = (CoapResponse) args[0]; + + latchInvitedUser.countDown(); + + // check observe notification response + if (latchInvitedUser.getCount() == 0) { + + assertEquals(resp.getStatus(), ResponseStatus.CONTENT); + assertTrue(checkResponsePayload(resp, + Constants.RESP_INVITED)); + assertTrue(checkInviteInfo(resp.getPayload(), + Constants.RESP_INVITED, TEST_GROUP_ID, + TEST_INVITE_USER)); + } + + return resp; + } + }).when(mockInvitedUser).sendResponse(Mockito.anyObject()); + + getInvitation(TEST_INVITED_USER, mockInvitedUser, Observe.SUBSCRIBE); + sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER); + + assertTrue(latchInvitedUser.await(2L, SECONDS)); + } + + @Test + public void testInviteUserCancelObserveInvitation() throws Exception { + + getInvitation(TEST_INVITE_USER, mMockDevice, Observe.SUBSCRIBE); + sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER); + + getInvitation(TEST_INVITE_USER, mMockDevice, Observe.UNSUBSCRIBE); + + assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT); + assertTrue(checkInviteInfo(mResponse.getPayload(), + Constants.RESP_INVITE, TEST_GROUP_ID, TEST_INVITED_USER)); + } + + @Test + public void testInvitedUserCancelObserveInvitation() throws Exception { + + getInvitation(TEST_INVITED_USER, mMockDevice, Observe.SUBSCRIBE); + sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER); + + getInvitation(TEST_INVITED_USER, mMockDevice, Observe.UNSUBSCRIBE); + + assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT); + assertTrue(checkInviteInfo(mResponse.getPayload(), + Constants.RESP_INVITED, TEST_GROUP_ID, TEST_INVITE_USER)); + } + + @Test + public void testInviteUserGetInvitation() throws Exception { + + sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER); + + getInvitation(TEST_INVITE_USER, mMockDevice, Observe.NOTHING); + + assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT); + assertTrue(checkInviteInfo(mResponse.getPayload(), + Constants.RESP_INVITE, TEST_GROUP_ID, TEST_INVITED_USER)); + } + + @Test + public void testInvitedUserGetInvitation() throws Exception { + + sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER); + + getInvitation(TEST_INVITED_USER, mMockDevice, Observe.NOTHING); + + assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT); + assertTrue(checkInviteInfo(mResponse.getPayload(), + Constants.RESP_INVITED, TEST_GROUP_ID, TEST_INVITE_USER)); + } + + @Test + public void testDeleteInvitation() throws Exception { + + sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER); + + deleteInvitation(TEST_GROUP_ID, TEST_INVITED_USER, ""); + + assertTrue(mLatch.await(1L, SECONDS)); + assertEquals(mResponse.getStatus(), ResponseStatus.DELETED); + } + + @Test + public void testCancelInvitation() throws Exception { + + sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER); + + deleteInvitation(TEST_GROUP_ID, TEST_INVITE_USER, TEST_INVITED_USER); + + assertTrue(mLatch.await(1L, SECONDS)); + assertEquals(mResponse.getStatus(), ResponseStatus.DELETED); + } + + private void sendInvitation(String gid, String mid) { + + IRequest request = makeSendInvitationRequest(gid, mid); + + mInviteResource.onDefaultRequestReceived(mMockDevice, request); + } + + private void deleteInvitation(String gid, String uid, String mid) { + + String uriQuery = Constants.REQ_GROUP_ID + "=" + gid + ";" + + Constants.REQ_UUID_ID + "=" + uid + ";" + + Constants.REQ_MEMBER + "=" + mid; + + IRequest request = MessageBuilder.createRequest(RequestMethod.DELETE, + INVITE_URI, uriQuery); + + mInviteResource.onDefaultRequestReceived(mMockDevice, request); + } + + private void getInvitation(String uid, CoapDevice device, Observe observeOpt) { + + String uriQuery = Constants.REQ_UUID_ID + "=" + uid; + IRequest request = MessageBuilder.createRequest(RequestMethod.GET, + INVITE_URI, uriQuery); + + if (observeOpt.equals(Observe.NOTHING) == false) { + ((CoapRequest) request).setObserve(observeOpt); + } + + mInviteResource.onDefaultRequestReceived(device, request); + } + + private IRequest makeSendInvitationRequest(String gid, String mid) { + + HashMap invitation = new HashMap<>(); + invitation.put(Constants.REQ_GROUP_ID, gid); + invitation.put(Constants.REQ_MEMBER, mid); + + HashMap payload = new HashMap<>(); + payload.put(Constants.REQ_UUID_ID, TEST_INVITE_USER); + payload.put(Constants.REQ_INVITE, Arrays.asList(invitation)); + + return MessageBuilder.createRequest(RequestMethod.POST, INVITE_URI, + null, ContentFormat.APPLICATION_CBOR, + mCbor.encodingPayloadToCbor(payload)); + } + + private boolean checkResponsePayload(IResponse response, String propertyName) { + + HashMap payloadData = mCbor.parsePayloadFromCbor( + response.getPayload(), HashMap.class); + + return payloadData.get(propertyName) != null ? true : false; + } + + private boolean checkInviteInfo(byte[] payload, String propertyKey, + String gid, String mid) { + + HashMap paredPayload = mCbor.parsePayloadFromCbor( + payload, HashMap.class); + + @SuppressWarnings("unchecked") + ArrayList> invitationList = (ArrayList>) paredPayload + .get(propertyKey); + + for (HashMap invitation : invitationList) { + + if (invitation.get(Constants.REQ_GROUP_ID).equals(gid) + && invitation.get(Constants.REQ_MEMBER).equals(mid)) { + + return true; + } + } + + return false; + } + +} \ No newline at end of file -- 2.7.4