b2145645a51c5f804936e5e6fc3f1b67496dc9a6
[iotivity.git] / cloud / account / src / test / java / org / iotivity / cloud / accountserver / resources / acl / invite / InviteResourceTest.java
1 /*
2  * //******************************************************************
3  * //
4  * // Copyright 2016 Samsung Electronics All Rights Reserved.
5  * //
6  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  * //
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
11  * //
12  * //      http://www.apache.org/licenses/LICENSE-2.0
13  * //
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.
19  * //
20  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22 package org.iotivity.cloud.accountserver.resources.acl.invite;
23
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;
28
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.HashMap;
32 import java.util.concurrent.CountDownLatch;
33
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;
53
54 public class InviteResourceTest {
55     private static final String           INVITE_URI        = "/.well-known/ocf/acl/invite";
56
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";
60
61     private InviteResource                mInviteResource   = null;
62
63     private CountDownLatch                mLatch            = null;
64
65     private CoapDevice                    mMockDevice       = null;
66     private IResponse                     mResponse         = null;
67
68     private Cbor<HashMap<String, Object>> mCbor             = new Cbor<>();
69
70     @Before
71     public void setUp() throws Exception {
72
73         mInviteResource = new InviteResource();
74
75         mLatch = new CountDownLatch(1);
76
77         mMockDevice = Mockito.mock(CoapDevice.class);
78
79         mResponse = null;
80
81         // reset data base
82         MongoDB mongoDB = new MongoDB(Constants.DB_NAME);
83         mongoDB.deleteTable(Constants.INVITE_TABLE);
84         mongoDB.createTable(Constants.INVITE_TABLE);
85
86         Mockito.doAnswer(new Answer<Object>() {
87             @Override
88             public CoapResponse answer(InvocationOnMock invocation)
89                     throws Throwable {
90                 Object[] args = invocation.getArguments();
91                 CoapResponse resp = (CoapResponse) args[0];
92                 mResponse = resp;
93
94                 mLatch.countDown();
95
96                 return resp;
97             }
98         }).when(mMockDevice).sendResponse(Mockito.anyObject());
99
100     }
101
102     @Test
103     public void testSendInvitation() throws Exception {
104
105         sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
106
107         assertTrue(mLatch.await(1L, SECONDS));
108         assertEquals(mResponse.getStatus(), ResponseStatus.CHANGED);
109     }
110
111     @Test(expected = PreconditionFailedException.class)
112     public void testSendInvitationWithoutGid() throws Exception {
113
114         sendInvitation(null, TEST_INVITED_USER);
115     }
116
117     @Test(expected = PreconditionFailedException.class)
118     public void testSendInvitationWithoutMid() throws Exception {
119
120         sendInvitation(TEST_GROUP_ID, null);
121     }
122
123     @Test
124     public void testInviteUserObserveInvition() throws Exception {
125
126         CountDownLatch latchInviteUser = new CountDownLatch(2);
127
128         CoapDevice mockInviteUser = mock(CoapDevice.class);
129
130         // invite user callback
131         Mockito.doAnswer(new Answer<Object>() {
132             @Override
133             public CoapResponse answer(InvocationOnMock invocation)
134                     throws Throwable {
135                 Object[] args = invocation.getArguments();
136                 CoapResponse resp = (CoapResponse) args[0];
137
138                 latchInviteUser.countDown();
139
140                 // check observe notification response
141                 if (latchInviteUser.getCount() == 0) {
142
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,
147                             TEST_INVITED_USER));
148                 }
149
150                 return resp;
151             }
152         }).when(mockInviteUser).sendResponse(Mockito.anyObject());
153
154         getInvitation(TEST_INVITE_USER, mockInviteUser, Observe.SUBSCRIBE);
155         sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
156
157         assertTrue(latchInviteUser.await(2L, SECONDS));
158     }
159
160     @Test
161     public void testInvitedUserObserveInvitation() throws Exception {
162
163         CountDownLatch latchInvitedUser = new CountDownLatch(2);
164
165         CoapDevice mockInvitedUser = mock(CoapDevice.class);
166
167         // invited user callback
168         Mockito.doAnswer(new Answer<Object>() {
169             @Override
170             public CoapResponse answer(InvocationOnMock invocation)
171                     throws Throwable {
172                 Object[] args = invocation.getArguments();
173                 CoapResponse resp = (CoapResponse) args[0];
174
175                 latchInvitedUser.countDown();
176
177                 // check observe notification response
178                 if (latchInvitedUser.getCount() == 0) {
179
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,
185                             TEST_INVITE_USER));
186                 }
187
188                 return resp;
189             }
190         }).when(mockInvitedUser).sendResponse(Mockito.anyObject());
191
192         getInvitation(TEST_INVITED_USER, mockInvitedUser, Observe.SUBSCRIBE);
193         sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
194
195         assertTrue(latchInvitedUser.await(2L, SECONDS));
196     }
197
198     @Test
199     public void testInviteUserCancelObserveInvitation() throws Exception {
200
201         getInvitation(TEST_INVITE_USER, mMockDevice, Observe.SUBSCRIBE);
202         sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
203
204         getInvitation(TEST_INVITE_USER, mMockDevice, Observe.UNSUBSCRIBE);
205
206         assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT);
207         assertTrue(checkInviteInfo(mResponse.getPayload(),
208                 Constants.RESP_INVITE, TEST_GROUP_ID, TEST_INVITED_USER));
209     }
210
211     @Test
212     public void testInvitedUserCancelObserveInvitation() throws Exception {
213
214         getInvitation(TEST_INVITED_USER, mMockDevice, Observe.SUBSCRIBE);
215         sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
216
217         getInvitation(TEST_INVITED_USER, mMockDevice, Observe.UNSUBSCRIBE);
218
219         assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT);
220         assertTrue(checkInviteInfo(mResponse.getPayload(),
221                 Constants.RESP_INVITED, TEST_GROUP_ID, TEST_INVITE_USER));
222     }
223
224     @Test
225     public void testInviteUserGetInvitation() throws Exception {
226
227         sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
228
229         getInvitation(TEST_INVITE_USER, mMockDevice, Observe.NOTHING);
230
231         assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT);
232         assertTrue(checkInviteInfo(mResponse.getPayload(),
233                 Constants.RESP_INVITE, TEST_GROUP_ID, TEST_INVITED_USER));
234     }
235
236     @Test
237     public void testInvitedUserGetInvitation() throws Exception {
238
239         sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
240
241         getInvitation(TEST_INVITED_USER, mMockDevice, Observe.NOTHING);
242
243         assertEquals(mResponse.getStatus(), ResponseStatus.CONTENT);
244         assertTrue(checkInviteInfo(mResponse.getPayload(),
245                 Constants.RESP_INVITED, TEST_GROUP_ID, TEST_INVITE_USER));
246     }
247
248     @Test
249     public void testDeleteInvitation() throws Exception {
250
251         sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
252
253         deleteInvitation(TEST_GROUP_ID, TEST_INVITED_USER, "");
254
255         assertTrue(mLatch.await(1L, SECONDS));
256         assertEquals(mResponse.getStatus(), ResponseStatus.DELETED);
257     }
258
259     @Test
260     public void testCancelInvitation() throws Exception {
261
262         sendInvitation(TEST_GROUP_ID, TEST_INVITED_USER);
263
264         deleteInvitation(TEST_GROUP_ID, TEST_INVITE_USER, TEST_INVITED_USER);
265
266         assertTrue(mLatch.await(1L, SECONDS));
267         assertEquals(mResponse.getStatus(), ResponseStatus.DELETED);
268     }
269
270     private void sendInvitation(String gid, String mid) {
271
272         IRequest request = makeSendInvitationRequest(gid, mid);
273
274         mInviteResource.onDefaultRequestReceived(mMockDevice, request);
275     }
276
277     private void deleteInvitation(String gid, String uid, String mid) {
278
279         String uriQuery = Constants.REQ_GROUP_ID + "=" + gid + ";"
280                 + Constants.REQ_UUID_ID + "=" + uid + ";"
281                 + Constants.REQ_MEMBER + "=" + mid;
282
283         IRequest request = MessageBuilder.createRequest(RequestMethod.DELETE,
284                 INVITE_URI, uriQuery);
285
286         mInviteResource.onDefaultRequestReceived(mMockDevice, request);
287     }
288
289     private void getInvitation(String uid, CoapDevice device, Observe observeOpt) {
290
291         String uriQuery = Constants.REQ_UUID_ID + "=" + uid;
292         IRequest request = MessageBuilder.createRequest(RequestMethod.GET,
293                 INVITE_URI, uriQuery);
294
295         if (observeOpt.equals(Observe.NOTHING) == false) {
296             ((CoapRequest) request).setObserve(observeOpt);
297         }
298
299         mInviteResource.onDefaultRequestReceived(device, request);
300     }
301
302     private IRequest makeSendInvitationRequest(String gid, String mid) {
303
304         HashMap<String, Object> invitation = new HashMap<>();
305         invitation.put(Constants.REQ_GROUP_ID, gid);
306         invitation.put(Constants.REQ_MEMBER, mid);
307
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));
311
312         return MessageBuilder.createRequest(RequestMethod.POST, INVITE_URI,
313                 null, ContentFormat.APPLICATION_CBOR,
314                 mCbor.encodingPayloadToCbor(payload));
315     }
316
317     private boolean checkResponsePayload(IResponse response, String propertyName) {
318
319         HashMap<String, Object> payloadData = mCbor.parsePayloadFromCbor(
320                 response.getPayload(), HashMap.class);
321
322         return payloadData.get(propertyName) != null ? true : false;
323     }
324
325     private boolean checkInviteInfo(byte[] payload, String propertyKey,
326             String gid, String mid) {
327
328         HashMap<String, Object> paredPayload = mCbor.parsePayloadFromCbor(
329                 payload, HashMap.class);
330
331         @SuppressWarnings("unchecked")
332         ArrayList<HashMap<String, Object>> invitationList = (ArrayList<HashMap<String, Object>>) paredPayload
333                 .get(propertyKey);
334
335         for (HashMap<String, Object> invitation : invitationList) {
336
337             if (invitation.get(Constants.REQ_GROUP_ID).equals(gid)
338                     && invitation.get(Constants.REQ_MEMBER).equals(mid)) {
339
340                 return true;
341             }
342         }
343
344         return false;
345     }
346
347 }