2 * //******************************************************************
4 * // Copyright 2016 Samsung Electronics All Rights Reserved.
6 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
8 * // Licensed under the Apache License, Version 2.0 (the "License");
9 * // you may not use this file except in compliance with the License.
10 * // You may obtain a copy of the License at
12 * // http://www.apache.org/licenses/LICENSE-2.0
14 * // Unless required by applicable law or agreed to in writing, software
15 * // distributed under the License is distributed on an "AS IS" BASIS,
16 * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * // See the License for the specific language governing permissions and
18 * // limitations under the License.
20 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 package org.iotivity.cloud.accountserver.resources.acl.invite;
24 import static java.util.concurrent.TimeUnit.SECONDS;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertTrue;
27 import static org.mockito.Mockito.mock;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.HashMap;
32 import java.util.concurrent.CountDownLatch;
34 import org.iotivity.cloud.accountserver.Constants;
35 import org.iotivity.cloud.accountserver.db.MongoDB;
36 import org.iotivity.cloud.base.device.CoapDevice;
37 import org.iotivity.cloud.base.exception.ServerException.PreconditionFailedException;
38 import org.iotivity.cloud.base.protocols.IRequest;
39 import org.iotivity.cloud.base.protocols.IResponse;
40 import org.iotivity.cloud.base.protocols.MessageBuilder;
41 import org.iotivity.cloud.base.protocols.coap.CoapRequest;
42 import org.iotivity.cloud.base.protocols.coap.CoapResponse;
43 import org.iotivity.cloud.base.protocols.enums.ContentFormat;
44 import org.iotivity.cloud.base.protocols.enums.Observe;
45 import org.iotivity.cloud.base.protocols.enums.RequestMethod;
46 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
47 import org.iotivity.cloud.util.Cbor;
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.mockito.Mockito;
51 import org.mockito.invocation.InvocationOnMock;
52 import org.mockito.stubbing.Answer;
54 public class InviteResourceTest {
55 private static final String INVITE_URI = "/.well-known/ocf/acl/invite";
57 private static final String TEST_INVITE_USER = "u0001";
58 private static final String TEST_INVITED_USER = "u0002";
59 private static final String TEST_GROUP_ID = "g0001";
61 private InviteResource mInviteResource = null;
63 private CountDownLatch mLatch = null;
65 private CoapDevice mMockDevice = null;
66 private IResponse mResponse = null;
68 private Cbor<HashMap<String, Object>> mCbor = new Cbor<>();
71 public void setUp() throws Exception {
73 mInviteResource = new InviteResource();
75 mLatch = new CountDownLatch(1);
77 mMockDevice = Mockito.mock(CoapDevice.class);
82 MongoDB mongoDB = new MongoDB(Constants.DB_NAME);
83 mongoDB.deleteTable(Constants.INVITE_TABLE);
84 mongoDB.createTable(Constants.INVITE_TABLE);
86 Mockito.doAnswer(new Answer<Object>() {
88 public CoapResponse answer(InvocationOnMock invocation)
90 Object[] args = invocation.getArguments();
91 CoapResponse resp = (CoapResponse) args[0];
98 }).when(mMockDevice).sendResponse(Mockito.anyObject());
103 public void testSendInvitation() throws Exception {
105 sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
107 assertTrue(mLatch.await(1L, SECONDS));
108 assertEquals(mResponse.getStatus(), ResponseStatus.CHANGED);
111 @Test(expected = PreconditionFailedException.class)
112 public void testSendInvitationWithoutGid() throws Exception {
114 sendInvitation(null, TEST_INVITED_USER);
117 @Test(expected = PreconditionFailedException.class)
118 public void testSendInvitationWithoutMid() throws Exception {
120 sendInvitation(TEST_GROUP_ID, null);
124 public void testInviteUserObserveInvition() throws Exception {
126 CountDownLatch latchInviteUser = new CountDownLatch(2);
128 CoapDevice mockInviteUser = mock(CoapDevice.class);
130 // invite user callback
131 Mockito.doAnswer(new Answer<Object>() {
133 public CoapResponse answer(InvocationOnMock invocation)
135 Object[] args = invocation.getArguments();
136 CoapResponse resp = (CoapResponse) args[0];
138 latchInviteUser.countDown();
140 // check observe notification response
141 if (latchInviteUser.getCount() == 0) {
143 assertEquals(resp.getStatus(), ResponseStatus.CONTENT);
144 assertTrue(checkResponsePayload(resp, Constants.RESP_INVITE));
145 assertTrue(checkInviteInfo(resp.getPayload(),
146 Constants.RESP_INVITE, TEST_GROUP_ID,
152 }).when(mockInviteUser).sendResponse(Mockito.anyObject());
154 getInvitation(TEST_INVITE_USER, mockInviteUser, Observe.SUBSCRIBE);
155 sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
157 assertTrue(latchInviteUser.await(2L, SECONDS));
161 public void testInvitedUserObserveInvitation() throws Exception {
163 CountDownLatch latchInvitedUser = new CountDownLatch(2);
165 CoapDevice mockInvitedUser = mock(CoapDevice.class);
167 // invited user callback
168 Mockito.doAnswer(new Answer<Object>() {
170 public CoapResponse answer(InvocationOnMock invocation)
172 Object[] args = invocation.getArguments();
173 CoapResponse resp = (CoapResponse) args[0];
175 latchInvitedUser.countDown();
177 // check observe notification response
178 if (latchInvitedUser.getCount() == 0) {
180 assertEquals(resp.getStatus(), ResponseStatus.CONTENT);
181 assertTrue(checkResponsePayload(resp,
182 Constants.RESP_INVITED));
183 assertTrue(checkInviteInfo(resp.getPayload(),
184 Constants.RESP_INVITED, TEST_GROUP_ID,
190 }).when(mockInvitedUser).sendResponse(Mockito.anyObject());
192 getInvitation(TEST_INVITED_USER, mockInvitedUser, Observe.SUBSCRIBE);
193 sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
195 assertTrue(latchInvitedUser.await(2L, SECONDS));
199 public void testInviteUserCancelObserveInvitation() throws Exception {
201 getInvitation(TEST_INVITE_USER, mMockDevice, Observe.SUBSCRIBE);
202 sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
204 getInvitation(TEST_INVITE_USER, mMockDevice, Observe.UNSUBSCRIBE);
206 assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT);
207 assertTrue(checkInviteInfo(mResponse.getPayload(),
208 Constants.RESP_INVITE, TEST_GROUP_ID, TEST_INVITED_USER));
212 public void testInvitedUserCancelObserveInvitation() throws Exception {
214 getInvitation(TEST_INVITED_USER, mMockDevice, Observe.SUBSCRIBE);
215 sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
217 getInvitation(TEST_INVITED_USER, mMockDevice, Observe.UNSUBSCRIBE);
219 assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT);
220 assertTrue(checkInviteInfo(mResponse.getPayload(),
221 Constants.RESP_INVITED, TEST_GROUP_ID, TEST_INVITE_USER));
225 public void testInviteUserGetInvitation() throws Exception {
227 sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
229 getInvitation(TEST_INVITE_USER, mMockDevice, Observe.NOTHING);
231 assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT);
232 assertTrue(checkInviteInfo(mResponse.getPayload(),
233 Constants.RESP_INVITE, TEST_GROUP_ID, TEST_INVITED_USER));
237 public void testInvitedUserGetInvitation() throws Exception {
239 sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
241 getInvitation(TEST_INVITED_USER, mMockDevice, Observe.NOTHING);
243 assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT);
244 assertTrue(checkInviteInfo(mResponse.getPayload(),
245 Constants.RESP_INVITED, TEST_GROUP_ID, TEST_INVITE_USER));
249 public void testDeleteInvitation() throws Exception {
251 sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
253 deleteInvitation(TEST_GROUP_ID, TEST_INVITED_USER, "");
255 assertTrue(mLatch.await(1L, SECONDS));
256 assertEquals(mResponse.getStatus(), ResponseStatus.DELETED);
260 public void testCancelInvitation() throws Exception {
262 sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
264 deleteInvitation(TEST_GROUP_ID, TEST_INVITE_USER, TEST_INVITED_USER);
266 assertTrue(mLatch.await(1L, SECONDS));
267 assertEquals(mResponse.getStatus(), ResponseStatus.DELETED);
270 private void sendInvitation(String gid, String mid) {
272 IRequest request = makeSendInvitationRequest(gid, mid);
274 mInviteResource.onDefaultRequestReceived(mMockDevice, request);
277 private void deleteInvitation(String gid, String uid, String mid) {
279 String uriQuery = Constants.REQ_GROUP_ID + "=" + gid + ";"
280 + Constants.REQ_UUID_ID + "=" + uid + ";"
281 + Constants.REQ_MEMBER + "=" + mid;
283 IRequest request = MessageBuilder.createRequest(RequestMethod.DELETE,
284 INVITE_URI, uriQuery);
286 mInviteResource.onDefaultRequestReceived(mMockDevice, request);
289 private void getInvitation(String uid, CoapDevice device, Observe observeOpt) {
291 String uriQuery = Constants.REQ_UUID_ID + "=" + uid;
292 IRequest request = MessageBuilder.createRequest(RequestMethod.GET,
293 INVITE_URI, uriQuery);
295 if (observeOpt.equals(Observe.NOTHING) == false) {
296 ((CoapRequest) request).setObserve(observeOpt);
299 mInviteResource.onDefaultRequestReceived(device, request);
302 private IRequest makeSendInvitationRequest(String gid, String mid) {
304 HashMap<String, Object> invitation = new HashMap<>();
305 invitation.put(Constants.REQ_GROUP_ID, gid);
306 invitation.put(Constants.REQ_MEMBER, mid);
308 HashMap<String, Object> payload = new HashMap<>();
309 payload.put(Constants.REQ_UUID_ID, TEST_INVITE_USER);
310 payload.put(Constants.REQ_INVITE, Arrays.asList(invitation));
312 return MessageBuilder.createRequest(RequestMethod.POST, INVITE_URI,
313 null, ContentFormat.APPLICATION_CBOR,
314 mCbor.encodingPayloadToCbor(payload));
317 private boolean checkResponsePayload(IResponse response, String propertyName) {
319 HashMap<String, Object> payloadData = mCbor.parsePayloadFromCbor(
320 response.getPayload(), HashMap.class);
322 return payloadData.get(propertyName) != null ? true : false;
325 private boolean checkInviteInfo(byte[] payload, String propertyKey,
326 String gid, String mid) {
328 HashMap<String, Object> paredPayload = mCbor.parsePayloadFromCbor(
329 payload, HashMap.class);
331 @SuppressWarnings("unchecked")
332 ArrayList<HashMap<String, Object>> invitationList = (ArrayList<HashMap<String, Object>>) paredPayload
335 for (HashMap<String, Object> invitation : invitationList) {
337 if (invitation.get(Constants.REQ_GROUP_ID).equals(gid)
338 && invitation.get(Constants.REQ_MEMBER).equals(mid)) {