@webex/internal-plugin-conversation 3.0.0-beta.9 → 3.0.0-bnr.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/dist/activities.js +8 -69
- package/dist/activities.js.map +1 -1
- package/dist/activity-thread-ordering.js +19 -79
- package/dist/activity-thread-ordering.js.map +1 -1
- package/dist/config.js +1 -7
- package/dist/config.js.map +1 -1
- package/dist/constants.js +4 -5
- package/dist/constants.js.map +1 -1
- package/dist/conversation.js +790 -1199
- package/dist/conversation.js.map +1 -1
- package/dist/convo-error.js +0 -23
- package/dist/convo-error.js.map +1 -1
- package/dist/decryption-transforms.js +35 -98
- package/dist/decryption-transforms.js.map +1 -1
- package/dist/encryption-transforms.js +11 -48
- package/dist/encryption-transforms.js.map +1 -1
- package/dist/index.js +7 -50
- package/dist/index.js.map +1 -1
- package/dist/internal-plugin-conversation.d.ts +21 -0
- package/dist/share-activity.js +40 -106
- package/dist/share-activity.js.map +1 -1
- package/dist/to-array.js +9 -11
- package/dist/to-array.js.map +1 -1
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/types/activities.d.ts +32 -0
- package/dist/types/activity-thread-ordering.d.ts +18 -0
- package/dist/types/config.d.ts +19 -0
- package/dist/types/constants.d.ts +5 -0
- package/dist/types/conversation.d.ts +2 -0
- package/dist/types/convo-error.d.ts +10 -0
- package/dist/types/decryption-transforms.d.ts +1 -0
- package/dist/types/encryption-transforms.d.ts +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/share-activity.d.ts +7 -0
- package/dist/types/to-array.d.ts +9 -0
- package/package.json +15 -15
- package/src/activities.js +10 -7
- package/src/activity-thread-ordering.js +27 -30
- package/src/activity-threading.md +68 -49
- package/src/config.js +5 -5
- package/src/conversation.js +621 -589
- package/src/decryption-transforms.js +103 -62
- package/src/encryption-transforms.js +103 -83
- package/src/index.js +82 -66
- package/src/share-activity.js +64 -55
- package/src/to-array.js +2 -2
- package/test/integration/spec/create.js +184 -118
- package/test/integration/spec/encryption.js +250 -186
- package/test/integration/spec/get.js +761 -513
- package/test/integration/spec/mercury.js +37 -27
- package/test/integration/spec/share.js +292 -229
- package/test/integration/spec/verbs.js +628 -441
- package/test/unit/spec/conversation.js +265 -163
- package/test/unit/spec/decrypt-transforms.js +112 -131
- package/test/unit/spec/encryption-transforms.js +24 -18
- package/test/unit/spec/share-activity.js +37 -40
|
@@ -13,14 +13,13 @@ import uuid from 'uuid';
|
|
|
13
13
|
import fh from '@webex/test-helper-file';
|
|
14
14
|
import {skipInNode} from '@webex/test-helper-mocha';
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
describe('plugin-conversation', function () {
|
|
18
17
|
this.timeout(30000);
|
|
19
18
|
describe('verbs', () => {
|
|
20
19
|
let checkov, mccoy, participants, webex, spock;
|
|
21
20
|
|
|
22
|
-
before(() =>
|
|
23
|
-
.then(async (users) => {
|
|
21
|
+
before(() =>
|
|
22
|
+
testUsers.create({count: 3}).then(async (users) => {
|
|
24
23
|
[spock, mccoy, checkov] = participants = users;
|
|
25
24
|
|
|
26
25
|
// Pause for 5 seconds for CI
|
|
@@ -28,26 +27,29 @@ describe('plugin-conversation', function () {
|
|
|
28
27
|
|
|
29
28
|
webex = new WebexCore({
|
|
30
29
|
credentials: {
|
|
31
|
-
authorization: spock.token
|
|
32
|
-
}
|
|
30
|
+
authorization: spock.token,
|
|
31
|
+
},
|
|
33
32
|
});
|
|
34
33
|
|
|
35
34
|
mccoy.webex = new WebexCore({
|
|
36
35
|
credentials: {
|
|
37
|
-
authorization: mccoy.token
|
|
38
|
-
}
|
|
36
|
+
authorization: mccoy.token,
|
|
37
|
+
},
|
|
39
38
|
});
|
|
40
39
|
|
|
41
40
|
return Promise.all([
|
|
42
41
|
webex.internal.mercury.connect(),
|
|
43
|
-
mccoy.webex.internal.mercury.connect()
|
|
42
|
+
mccoy.webex.internal.mercury.connect(),
|
|
44
43
|
]);
|
|
45
|
-
})
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
46
|
|
|
47
|
-
after(() =>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
after(() =>
|
|
48
|
+
Promise.all([
|
|
49
|
+
webex && webex.internal.mercury.disconnect(),
|
|
50
|
+
mccoy && mccoy.webex.internal.mercury.disconnect(),
|
|
51
|
+
])
|
|
52
|
+
);
|
|
51
53
|
|
|
52
54
|
function makeEmailAddress() {
|
|
53
55
|
return `webex-js-sdk--test-${uuid.v4()}@example.com`;
|
|
@@ -60,156 +62,196 @@ describe('plugin-conversation', function () {
|
|
|
60
62
|
return Promise.resolve();
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
return webex.internal.conversation.create({participants})
|
|
64
|
-
|
|
65
|
+
return webex.internal.conversation.create({participants}).then((c) => {
|
|
66
|
+
conversation = c;
|
|
67
|
+
});
|
|
65
68
|
});
|
|
66
69
|
|
|
67
70
|
describe('#add()', () => {
|
|
68
71
|
let email;
|
|
69
72
|
|
|
70
|
-
beforeEach(() => {
|
|
73
|
+
beforeEach(() => {
|
|
74
|
+
email = makeEmailAddress();
|
|
75
|
+
});
|
|
71
76
|
|
|
72
|
-
beforeEach(() =>
|
|
73
|
-
.
|
|
77
|
+
beforeEach(() =>
|
|
78
|
+
webex.internal.conversation
|
|
79
|
+
.create({participants: [checkov]}, {forceGrouped: true})
|
|
80
|
+
.then((c) => {
|
|
81
|
+
conversation = c;
|
|
82
|
+
})
|
|
83
|
+
);
|
|
74
84
|
|
|
75
|
-
it('adds the specified user to the specified conversation', () =>
|
|
76
|
-
.then((activity) => {
|
|
85
|
+
it('adds the specified user to the specified conversation', () =>
|
|
86
|
+
webex.internal.conversation.add(conversation, mccoy).then((activity) => {
|
|
77
87
|
assert.isActivity(activity);
|
|
78
88
|
assert.property(activity, 'kmsMessage');
|
|
79
89
|
}));
|
|
80
90
|
|
|
81
|
-
it(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
it("grants the specified user access to the conversation's key", () =>
|
|
92
|
+
webex.internal.conversation
|
|
93
|
+
.post(conversation, {displayName: 'PROOF!'})
|
|
94
|
+
.then(() => webex.internal.conversation.add(conversation, mccoy))
|
|
95
|
+
.then(() => mccoy.webex.internal.conversation.get(conversation, {activitiesLimit: 10}))
|
|
96
|
+
.then((c) => {
|
|
97
|
+
assert.isConversation(c);
|
|
98
|
+
const activity = find(c.activities.items, {verb: 'post'});
|
|
87
99
|
|
|
88
|
-
|
|
89
|
-
|
|
100
|
+
assert.equal(activity.object.displayName, 'PROOF!');
|
|
101
|
+
}));
|
|
90
102
|
|
|
91
103
|
// TODO: Issues with side boarding users too soon. Skipping until it's fixed
|
|
92
|
-
it.skip('sideboards a non-existent user', () =>
|
|
93
|
-
.
|
|
94
|
-
|
|
104
|
+
it.skip('sideboards a non-existent user', () =>
|
|
105
|
+
webex.internal.conversation
|
|
106
|
+
.add(conversation, email)
|
|
107
|
+
.then((activity) => {
|
|
108
|
+
assert.isActivity(activity);
|
|
95
109
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
110
|
+
return webex.internal.conversation.get(conversation, {includeParticipants: true});
|
|
111
|
+
})
|
|
112
|
+
.then((c) => {
|
|
113
|
+
assert.isConversation(c);
|
|
114
|
+
const participant = find(c.participants.items, {emailAddress: email});
|
|
101
115
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
116
|
+
assert.include(participant.tags, 'SIDE_BOARDED');
|
|
117
|
+
assert.match(participant.id, patterns.uuid);
|
|
118
|
+
}));
|
|
105
119
|
});
|
|
106
120
|
|
|
107
121
|
describe('#assign()', () => {
|
|
108
|
-
before(() =>
|
|
109
|
-
.then((c) => {
|
|
122
|
+
before(() =>
|
|
123
|
+
webex.internal.conversation.create({participants}).then((c) => {
|
|
110
124
|
conversation = c;
|
|
111
|
-
})
|
|
125
|
+
})
|
|
126
|
+
);
|
|
112
127
|
|
|
113
128
|
let sampleImageSmallOnePng = 'sample-image-small-one.png';
|
|
114
129
|
|
|
115
|
-
before(() =>
|
|
116
|
-
.then((res) => {
|
|
130
|
+
before(() =>
|
|
131
|
+
fh.fetch(sampleImageSmallOnePng).then((res) => {
|
|
117
132
|
sampleImageSmallOnePng = res;
|
|
118
|
-
})
|
|
133
|
+
})
|
|
134
|
+
);
|
|
119
135
|
|
|
120
|
-
it('assigns an avatar to a room', () =>
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
it('assigns an avatar to a room', () =>
|
|
137
|
+
webex.internal.conversation
|
|
138
|
+
.assign(conversation, sampleImageSmallOnePng)
|
|
139
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
140
|
+
.then((c) => {
|
|
141
|
+
assert.property(c, 'avatar');
|
|
142
|
+
|
|
143
|
+
assert.property(c.avatar, 'files');
|
|
144
|
+
assert.property(c.avatar.files, 'items');
|
|
145
|
+
assert.lengthOf(c.avatar.files.items, 1);
|
|
146
|
+
assert.property(c.avatar.files.items[0], 'fileSize');
|
|
147
|
+
assert.property(c.avatar.files.items[0], 'mimeType');
|
|
148
|
+
assert.property(c.avatar.files.items[0], 'objectType');
|
|
149
|
+
assert.property(c.avatar.files.items[0], 'scr');
|
|
150
|
+
assert.property(c.avatar.files.items[0], 'url');
|
|
151
|
+
assert.equal(c.avatar.objectType, 'content');
|
|
152
|
+
|
|
153
|
+
assert.isString(c.avatarEncryptionKeyUrl);
|
|
154
|
+
assert.isObject(c.avatar.files.items[0].scr, 'The scr was decrypted');
|
|
155
|
+
assert.equal(c.avatar.files.items[0].displayName, 'sample-image-small-one.png');
|
|
156
|
+
|
|
157
|
+
assert.property(c, 'avatarEncryptionKeyUrl');
|
|
158
|
+
}));
|
|
141
159
|
});
|
|
142
160
|
|
|
143
161
|
describe('#leave()', () => {
|
|
144
|
-
afterEach(() => {
|
|
162
|
+
afterEach(() => {
|
|
163
|
+
conversation = null;
|
|
164
|
+
});
|
|
145
165
|
|
|
146
|
-
it('removes the current user from the specified conversation', () =>
|
|
147
|
-
.
|
|
148
|
-
|
|
166
|
+
it('removes the current user from the specified conversation', () =>
|
|
167
|
+
webex.internal.conversation
|
|
168
|
+
.leave(conversation)
|
|
169
|
+
.then((activity) => {
|
|
170
|
+
assert.isActivity(activity);
|
|
149
171
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
172
|
+
return assert.isRejected(webex.internal.conversation.get(conversation));
|
|
173
|
+
})
|
|
174
|
+
.then((reason) => {
|
|
175
|
+
assert.statusCode(reason, 404);
|
|
154
176
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
177
|
+
return assert.isRejected(
|
|
178
|
+
webex.internal.encryption.kms.fetchKey({
|
|
179
|
+
uri: conversation.defaultActivityEncryptionKeyUrl,
|
|
180
|
+
})
|
|
181
|
+
);
|
|
182
|
+
})
|
|
183
|
+
.then((reason) => assert.equal(reason.status, 403)));
|
|
158
184
|
|
|
159
|
-
it('removes the specified user from the specified conversation', () =>
|
|
160
|
-
.
|
|
161
|
-
|
|
185
|
+
it('removes the specified user from the specified conversation', () =>
|
|
186
|
+
webex.internal.conversation
|
|
187
|
+
.leave(conversation, mccoy)
|
|
188
|
+
.then((activity) => {
|
|
189
|
+
assert.isActivity(activity);
|
|
162
190
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
191
|
+
return assert.isRejected(mccoy.webex.internal.conversation.get(conversation));
|
|
192
|
+
})
|
|
193
|
+
.then((reason) => {
|
|
194
|
+
assert.statusCode(reason, 404);
|
|
167
195
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
196
|
+
return assert.isRejected(
|
|
197
|
+
mccoy.webex.internal.encryption.kms.fetchKey({
|
|
198
|
+
uri: conversation.defaultActivityEncryptionKeyUrl,
|
|
199
|
+
})
|
|
200
|
+
);
|
|
201
|
+
})
|
|
202
|
+
.then((reason) => assert.equal(reason.status, 403)));
|
|
171
203
|
|
|
172
204
|
describe('with deleted users', () => {
|
|
173
205
|
let redshirt;
|
|
174
206
|
|
|
175
|
-
beforeEach(() =>
|
|
176
|
-
.then(([rs]) => {
|
|
207
|
+
beforeEach(() =>
|
|
208
|
+
testUsers.create({count: 1}).then(([rs]) => {
|
|
177
209
|
redshirt = rs;
|
|
178
210
|
|
|
179
211
|
return webex.internal.conversation.add(conversation, rs);
|
|
180
|
-
})
|
|
212
|
+
})
|
|
213
|
+
);
|
|
181
214
|
|
|
182
|
-
it('removes the specified deleted user from the specified conversation', () =>
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
215
|
+
it('removes the specified deleted user from the specified conversation', () =>
|
|
216
|
+
webex.internal.conversation
|
|
217
|
+
.leave(conversation, redshirt)
|
|
218
|
+
.then(() => webex.internal.conversation.get(conversation, {includeParticipants: true}))
|
|
219
|
+
.then((c) => {
|
|
220
|
+
assert.lengthOf(c.participants.items, 3);
|
|
221
|
+
assert.notInclude(map(c.participants.items, 'id'), redshirt.id);
|
|
222
|
+
}));
|
|
188
223
|
});
|
|
189
224
|
});
|
|
190
225
|
|
|
191
226
|
describe('#leave() with id only', () => {
|
|
192
|
-
afterEach(() => {
|
|
227
|
+
afterEach(() => {
|
|
228
|
+
conversation = null;
|
|
229
|
+
});
|
|
193
230
|
|
|
194
|
-
it('removes the current user by id only', () =>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
231
|
+
it('removes the current user by id only', () =>
|
|
232
|
+
webex.internal.conversation
|
|
233
|
+
.leave({
|
|
234
|
+
id: conversation.id,
|
|
235
|
+
defaultActivityEncryptionKeyUrl: conversation.defaultActivityEncryptionKeyUrl,
|
|
236
|
+
kmsResourceObjectUrl: conversation.kmsResourceObjectUrl,
|
|
237
|
+
})
|
|
238
|
+
.then((activity) => {
|
|
239
|
+
assert.isActivity(activity);
|
|
201
240
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
241
|
+
return assert.isRejected(webex.internal.conversation.get(conversation));
|
|
242
|
+
})
|
|
243
|
+
.then((reason) => {
|
|
244
|
+
assert.statusCode(reason, 404);
|
|
206
245
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
246
|
+
return assert.isRejected(
|
|
247
|
+
webex.internal.encryption.kms.fetchKey({
|
|
248
|
+
uri: conversation.defaultActivityEncryptionKeyUrl,
|
|
249
|
+
})
|
|
250
|
+
);
|
|
251
|
+
})
|
|
252
|
+
.then((reason) => assert.equal(reason.status, 403)));
|
|
210
253
|
});
|
|
211
254
|
|
|
212
|
-
|
|
213
255
|
describe('#post()', () => {
|
|
214
256
|
let message, richMessage;
|
|
215
257
|
|
|
@@ -223,7 +265,7 @@ describe('plugin-conversation', function () {
|
|
|
223
265
|
const allTagsUsedInThisTest = {
|
|
224
266
|
div: [],
|
|
225
267
|
b: [],
|
|
226
|
-
span: []
|
|
268
|
+
span: [],
|
|
227
269
|
};
|
|
228
270
|
|
|
229
271
|
[
|
|
@@ -233,7 +275,7 @@ describe('plugin-conversation', function () {
|
|
|
233
275
|
allowedInboundTags: {div: []},
|
|
234
276
|
outboundMessage: '<div>HELLO</div>',
|
|
235
277
|
outboundFilteredMessage: '<div>HELLO</div>',
|
|
236
|
-
inboundMessage: '<div>HELLO</div>'
|
|
278
|
+
inboundMessage: '<div>HELLO</div>',
|
|
237
279
|
},
|
|
238
280
|
{
|
|
239
281
|
it: 'filters and escapes disallowed outbound tags',
|
|
@@ -241,7 +283,7 @@ describe('plugin-conversation', function () {
|
|
|
241
283
|
allowedInboundTags: {},
|
|
242
284
|
outboundMessage: '<div><b>HELLO</b></div>',
|
|
243
285
|
outboundFilteredMessage: '<div><b>HELLO</b></div>',
|
|
244
|
-
inboundMessage: '<div><b>HELLO</b></div>'
|
|
286
|
+
inboundMessage: '<div><b>HELLO</b></div>',
|
|
245
287
|
},
|
|
246
288
|
{
|
|
247
289
|
it: 'filters disallowed inbound tags',
|
|
@@ -249,24 +291,24 @@ describe('plugin-conversation', function () {
|
|
|
249
291
|
allowedInboundTags: {b: []},
|
|
250
292
|
outboundMessage: '<div><b>HELLO</b></div>',
|
|
251
293
|
outboundFilteredMessage: '<div><b>HELLO</b></div>',
|
|
252
|
-
inboundMessage: '<b>HELLO</b>'
|
|
294
|
+
inboundMessage: '<b>HELLO</b>',
|
|
253
295
|
},
|
|
254
296
|
{
|
|
255
297
|
it: 'filters and escapes the correct outbound tags',
|
|
256
298
|
allowedOutboundTags: {div: [], span: []},
|
|
257
299
|
allowedInboundTags: {},
|
|
258
|
-
outboundMessage:
|
|
259
|
-
outboundFilteredMessage:
|
|
260
|
-
inboundMessage:
|
|
300
|
+
outboundMessage: "<div><b>HELLO</b><span> it's me</span></div>",
|
|
301
|
+
outboundFilteredMessage: "<div><b>HELLO</b><span> it's me</span></div>",
|
|
302
|
+
inboundMessage: "<b>HELLO</b> it's me",
|
|
261
303
|
},
|
|
262
304
|
{
|
|
263
305
|
it: 'filters the correct inbound tags and filters and escapes the correct outbound tags',
|
|
264
306
|
allowedOutboundTags: {div: [], span: []},
|
|
265
307
|
allowedInboundTags: {span: []},
|
|
266
|
-
outboundMessage:
|
|
267
|
-
outboundFilteredMessage:
|
|
268
|
-
inboundMessage:
|
|
269
|
-
}
|
|
308
|
+
outboundMessage: "<div><b>HELLO</b><span> it's me</span></div>",
|
|
309
|
+
outboundFilteredMessage: "<div><b>HELLO</b><span> it's me</span></div>",
|
|
310
|
+
inboundMessage: "<b>HELLO</b><span> it's me</span>",
|
|
311
|
+
},
|
|
270
312
|
].forEach((def) => {
|
|
271
313
|
it(def.it, () => {
|
|
272
314
|
webex.config.conversation.allowedOutboundTags = def.allowedOutboundTags;
|
|
@@ -275,10 +317,11 @@ describe('plugin-conversation', function () {
|
|
|
275
317
|
// the message is filtered by only the outbound rules
|
|
276
318
|
webex.config.conversation.allowedInboundTags = allTagsUsedInThisTest;
|
|
277
319
|
|
|
278
|
-
return webex.internal.conversation
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
320
|
+
return webex.internal.conversation
|
|
321
|
+
.post(conversation, {
|
|
322
|
+
displayName: message,
|
|
323
|
+
content: def.outboundMessage,
|
|
324
|
+
})
|
|
282
325
|
.then((activity) => {
|
|
283
326
|
assert.equal(activity.object.content, def.outboundFilteredMessage);
|
|
284
327
|
mccoy.webex.config.conversation.allowedInboundTags = def.allowedInboundTags;
|
|
@@ -299,29 +342,37 @@ describe('plugin-conversation', function () {
|
|
|
299
342
|
it('can post a plain text successfully', () => {
|
|
300
343
|
const {defaultActivityEncryptionKeyUrl} = conversation;
|
|
301
344
|
|
|
302
|
-
Promise.all([
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
345
|
+
Promise.all([
|
|
346
|
+
webex
|
|
347
|
+
.request({
|
|
348
|
+
method: 'GET',
|
|
349
|
+
api: 'conversation',
|
|
350
|
+
resource: `/conversations/${conversation.id}/healed?resetKey=true`,
|
|
351
|
+
})
|
|
352
|
+
.then(() =>
|
|
353
|
+
webex.request({
|
|
354
|
+
method: 'GET',
|
|
355
|
+
api: 'conversation',
|
|
356
|
+
resource: `conversations/${conversation.id}`,
|
|
357
|
+
})
|
|
358
|
+
),
|
|
359
|
+
])
|
|
312
360
|
.then((res) => {
|
|
313
361
|
res.body.defaultActivityEncryptionKeyUrl = defaultActivityEncryptionKeyUrl;
|
|
314
362
|
|
|
315
363
|
return webex.internal.conversation.post(res.body, message);
|
|
316
364
|
})
|
|
317
365
|
.then((res) => {
|
|
318
|
-
assert.notEqual(
|
|
366
|
+
assert.notEqual(
|
|
367
|
+
res.body.defaultActivityEncryptionKeyUrl,
|
|
368
|
+
defaultActivityEncryptionKeyUrl
|
|
369
|
+
);
|
|
319
370
|
});
|
|
320
371
|
});
|
|
321
372
|
});
|
|
322
373
|
|
|
323
|
-
it('posts a comment to the specified conversation', () =>
|
|
324
|
-
.then((activity) => {
|
|
374
|
+
it('posts a comment to the specified conversation', () =>
|
|
375
|
+
webex.internal.conversation.post(conversation, message).then((activity) => {
|
|
325
376
|
assert.isActivity(activity);
|
|
326
377
|
|
|
327
378
|
assert.isEncryptedActivity(activity);
|
|
@@ -330,159 +381,201 @@ describe('plugin-conversation', function () {
|
|
|
330
381
|
assert.equal(activity.object.displayName, message);
|
|
331
382
|
}));
|
|
332
383
|
|
|
333
|
-
it(
|
|
334
|
-
.then((c) => {
|
|
335
|
-
const {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
384
|
+
it("updates the specified conversation's unread status", () =>
|
|
385
|
+
mccoy.webex.internal.conversation.get(conversation).then((c) => {
|
|
386
|
+
const {lastSeenActivityDate, lastReadableActivityDate} = c;
|
|
387
|
+
|
|
388
|
+
return webex.internal.conversation.post(conversation, message).then(() =>
|
|
389
|
+
mccoy.webex.internal.conversation.get(conversation).then((c2) => {
|
|
390
|
+
assert.equal(c2.lastSeenActivityDate, lastSeenActivityDate);
|
|
391
|
+
assert.isAbove(
|
|
392
|
+
Date.parse(c2.lastReadableActivityDate),
|
|
393
|
+
Date.parse(lastReadableActivityDate)
|
|
394
|
+
);
|
|
395
|
+
})
|
|
396
|
+
);
|
|
346
397
|
}));
|
|
347
398
|
|
|
348
|
-
it('posts rich content to the specified conversation', () =>
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
399
|
+
it('posts rich content to the specified conversation', () =>
|
|
400
|
+
webex.internal.conversation
|
|
401
|
+
.post(conversation, {
|
|
402
|
+
displayName: message,
|
|
403
|
+
content: richMessage,
|
|
404
|
+
})
|
|
405
|
+
.then((activity) => {
|
|
406
|
+
assert.isActivity(activity);
|
|
354
407
|
|
|
355
|
-
|
|
356
|
-
|
|
408
|
+
assert.isEncryptedActivity(activity);
|
|
409
|
+
assert.equal(activity.encryptionKeyUrl, conversation.defaultActivityEncryptionKeyUrl);
|
|
357
410
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
411
|
+
assert.equal(activity.object.displayName, message);
|
|
412
|
+
assert.equal(activity.object.content, richMessage);
|
|
413
|
+
}));
|
|
361
414
|
|
|
362
|
-
it('submits mentions to the specified conversation', () =>
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
415
|
+
it('submits mentions to the specified conversation', () =>
|
|
416
|
+
webex.internal.conversation
|
|
417
|
+
.post(conversation, {
|
|
418
|
+
displayName: message,
|
|
419
|
+
content: richMessage,
|
|
420
|
+
mentions: {
|
|
421
|
+
items: [
|
|
422
|
+
{
|
|
423
|
+
id: mccoy.id,
|
|
424
|
+
objectType: 'person',
|
|
425
|
+
},
|
|
426
|
+
],
|
|
427
|
+
},
|
|
428
|
+
})
|
|
429
|
+
.then((activity) => {
|
|
430
|
+
assert.isActivity(activity);
|
|
374
431
|
|
|
375
|
-
|
|
376
|
-
|
|
432
|
+
assert.isEncryptedActivity(activity);
|
|
433
|
+
assert.equal(activity.encryptionKeyUrl, conversation.defaultActivityEncryptionKeyUrl);
|
|
377
434
|
|
|
378
|
-
|
|
379
|
-
|
|
435
|
+
assert.equal(activity.object.displayName, message);
|
|
436
|
+
assert.equal(activity.object.content, richMessage);
|
|
380
437
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
438
|
+
assert.isDefined(activity.object.mentions);
|
|
439
|
+
assert.isDefined(activity.object.mentions.items);
|
|
440
|
+
assert.lengthOf(activity.object.mentions.items, 1);
|
|
441
|
+
assert.equal(activity.object.mentions.items[0].id, mccoy.id);
|
|
442
|
+
}));
|
|
386
443
|
});
|
|
387
444
|
|
|
388
445
|
describe('#update()', () => {
|
|
389
|
-
it('renames the specified conversation', () =>
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
446
|
+
it('renames the specified conversation', () =>
|
|
447
|
+
webex.internal.conversation
|
|
448
|
+
.update(conversation, {
|
|
449
|
+
displayName: 'displayName2',
|
|
450
|
+
objectType: 'conversation',
|
|
451
|
+
})
|
|
452
|
+
.then((c) => webex.internal.conversation.get({url: c.target.url}))
|
|
453
|
+
.then((c) => assert.equal(c.displayName, 'displayName2')));
|
|
395
454
|
});
|
|
396
455
|
|
|
397
456
|
describe('#unassign()', () => {
|
|
398
|
-
before(() =>
|
|
399
|
-
.then((c) => {
|
|
457
|
+
before(() =>
|
|
458
|
+
webex.internal.conversation.create({participants}).then((c) => {
|
|
400
459
|
conversation = c;
|
|
401
|
-
})
|
|
460
|
+
})
|
|
461
|
+
);
|
|
402
462
|
|
|
403
463
|
let sampleImageSmallOnePng = 'sample-image-small-one.png';
|
|
404
464
|
|
|
405
|
-
before(() =>
|
|
406
|
-
.then((res) => {
|
|
465
|
+
before(() =>
|
|
466
|
+
fh.fetch(sampleImageSmallOnePng).then((res) => {
|
|
407
467
|
sampleImageSmallOnePng = res;
|
|
408
|
-
})
|
|
468
|
+
})
|
|
469
|
+
);
|
|
409
470
|
|
|
410
471
|
beforeEach(() => webex.internal.conversation.assign(conversation, sampleImageSmallOnePng));
|
|
411
472
|
|
|
412
|
-
it('unassigns an avatar from a room', () =>
|
|
413
|
-
|
|
414
|
-
.then((c) => {
|
|
473
|
+
it('unassigns an avatar from a room', () =>
|
|
474
|
+
webex.internal.conversation.unassign(conversation).then(() =>
|
|
475
|
+
webex.internal.conversation.get(conversation).then((c) => {
|
|
415
476
|
assert.notProperty(c, 'avatar');
|
|
416
477
|
assert.notProperty(c, 'avatarEncryptionKeyUrl');
|
|
417
|
-
})
|
|
478
|
+
})
|
|
479
|
+
));
|
|
418
480
|
});
|
|
419
481
|
|
|
420
482
|
describe('#updateKey()', () => {
|
|
421
|
-
beforeEach(() =>
|
|
422
|
-
.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
return webex.internal.conversation.get(conversation);
|
|
429
|
-
})
|
|
430
|
-
.then((c) => {
|
|
431
|
-
assert.isDefined(c.defaultActivityEncryptionKeyUrl);
|
|
432
|
-
assert.notEqual(c.defaultActivityEncryptionKeyUrl, conversation.defaultActivityEncryptionKeyUrl);
|
|
433
|
-
}));
|
|
483
|
+
beforeEach(() =>
|
|
484
|
+
webex.internal.conversation
|
|
485
|
+
.create({participants, comment: 'THIS IS A COMMENT'})
|
|
486
|
+
.then((c) => {
|
|
487
|
+
conversation = c;
|
|
488
|
+
})
|
|
489
|
+
);
|
|
434
490
|
|
|
435
|
-
it('assigns
|
|
436
|
-
|
|
491
|
+
it('assigns an unused key to the specified conversation', () =>
|
|
492
|
+
webex.internal.conversation
|
|
493
|
+
.updateKey(conversation)
|
|
437
494
|
.then((activity) => {
|
|
438
495
|
assert.isActivity(activity);
|
|
439
|
-
assert.equal(activity.object.defaultActivityEncryptionKeyUrl, key.uri);
|
|
440
496
|
|
|
441
497
|
return webex.internal.conversation.get(conversation);
|
|
442
498
|
})
|
|
443
499
|
.then((c) => {
|
|
444
500
|
assert.isDefined(c.defaultActivityEncryptionKeyUrl);
|
|
445
|
-
assert.notEqual(
|
|
446
|
-
|
|
501
|
+
assert.notEqual(
|
|
502
|
+
c.defaultActivityEncryptionKeyUrl,
|
|
503
|
+
conversation.defaultActivityEncryptionKeyUrl
|
|
504
|
+
);
|
|
505
|
+
}));
|
|
447
506
|
|
|
448
|
-
it('
|
|
449
|
-
.then((
|
|
450
|
-
|
|
507
|
+
it('assigns the specified key to the specified conversation', () =>
|
|
508
|
+
webex.internal.encryption.kms.createUnboundKeys({count: 1}).then(([key]) =>
|
|
509
|
+
webex.internal.conversation
|
|
510
|
+
.updateKey(conversation, key)
|
|
511
|
+
.then((activity) => {
|
|
512
|
+
assert.isActivity(activity);
|
|
513
|
+
assert.equal(activity.object.defaultActivityEncryptionKeyUrl, key.uri);
|
|
451
514
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
515
|
+
return webex.internal.conversation.get(conversation);
|
|
516
|
+
})
|
|
517
|
+
.then((c) => {
|
|
518
|
+
assert.isDefined(c.defaultActivityEncryptionKeyUrl);
|
|
519
|
+
assert.notEqual(
|
|
520
|
+
c.defaultActivityEncryptionKeyUrl,
|
|
521
|
+
conversation.defaultActivityEncryptionKeyUrl
|
|
522
|
+
);
|
|
523
|
+
})
|
|
524
|
+
));
|
|
461
525
|
|
|
462
|
-
|
|
463
|
-
|
|
526
|
+
it('grants access to the key for all users in the conversation', () =>
|
|
527
|
+
webex.internal.conversation
|
|
528
|
+
.updateKey(conversation)
|
|
529
|
+
.then((activity) => {
|
|
530
|
+
assert.isActivity(activity);
|
|
531
|
+
|
|
532
|
+
return mccoy.webex.internal.conversation.get({
|
|
533
|
+
url: conversation.url,
|
|
534
|
+
participantsLimit: 0,
|
|
535
|
+
activitiesLimit: 0,
|
|
536
|
+
});
|
|
537
|
+
})
|
|
538
|
+
.then((c) => {
|
|
539
|
+
assert.isDefined(c.defaultActivityEncryptionKeyUrl);
|
|
540
|
+
assert.notEqual(
|
|
541
|
+
c.defaultActivityEncryptionKeyUrl,
|
|
542
|
+
conversation.defaultActivityEncryptionKeyUrl
|
|
543
|
+
);
|
|
544
|
+
|
|
545
|
+
return mccoy.webex.internal.encryption.kms.fetchKey({
|
|
546
|
+
uri: c.defaultActivityEncryptionKeyUrl,
|
|
547
|
+
});
|
|
548
|
+
}));
|
|
464
549
|
});
|
|
465
550
|
|
|
466
551
|
describe('#updateTypingStatus()', () => {
|
|
467
|
-
beforeEach(() =>
|
|
468
|
-
.
|
|
469
|
-
|
|
470
|
-
|
|
552
|
+
beforeEach(() =>
|
|
553
|
+
webex.internal.conversation
|
|
554
|
+
.create({participants, comment: 'THIS IS A COMMENT'})
|
|
555
|
+
.then((c) => {
|
|
556
|
+
conversation = c;
|
|
557
|
+
})
|
|
558
|
+
);
|
|
471
559
|
|
|
472
|
-
it('sets the typing indicator for the specified conversation', () =>
|
|
473
|
-
.
|
|
474
|
-
|
|
475
|
-
|
|
560
|
+
it('sets the typing indicator for the specified conversation', () =>
|
|
561
|
+
webex.internal.conversation
|
|
562
|
+
.updateTypingStatus(conversation, {typing: true})
|
|
563
|
+
.then(({statusCode}) => {
|
|
564
|
+
assert.equal(statusCode, 204);
|
|
565
|
+
}));
|
|
476
566
|
|
|
477
|
-
it('clears the typing indicator for the specified conversation', () =>
|
|
478
|
-
.
|
|
479
|
-
|
|
480
|
-
|
|
567
|
+
it('clears the typing indicator for the specified conversation', () =>
|
|
568
|
+
webex.internal.conversation
|
|
569
|
+
.updateTypingStatus(conversation, {typing: false})
|
|
570
|
+
.then(({statusCode}) => {
|
|
571
|
+
assert.equal(statusCode, 204);
|
|
572
|
+
}));
|
|
481
573
|
|
|
482
574
|
it('fails if called with a bad conversation object', () => {
|
|
483
575
|
let error;
|
|
484
576
|
|
|
485
|
-
return webex.internal.conversation
|
|
577
|
+
return webex.internal.conversation
|
|
578
|
+
.updateTypingStatus({}, {typing: false})
|
|
486
579
|
.catch((reason) => {
|
|
487
580
|
error = reason;
|
|
488
581
|
})
|
|
@@ -494,7 +587,8 @@ describe('plugin-conversation', function () {
|
|
|
494
587
|
it('infers id from conversation url if missing', () => {
|
|
495
588
|
Reflect.deleteProperty(conversation, 'id');
|
|
496
589
|
|
|
497
|
-
return webex.internal.conversation
|
|
590
|
+
return webex.internal.conversation
|
|
591
|
+
.updateTypingStatus(conversation, {typing: true})
|
|
498
592
|
.then(({statusCode}) => {
|
|
499
593
|
assert.equal(statusCode, 204);
|
|
500
594
|
});
|
|
@@ -506,31 +600,33 @@ describe('plugin-conversation', function () {
|
|
|
506
600
|
{
|
|
507
601
|
itString: 'favorites the specified conversation',
|
|
508
602
|
tag: 'FAVORITE',
|
|
509
|
-
verb: 'favorite'
|
|
603
|
+
verb: 'favorite',
|
|
510
604
|
},
|
|
511
605
|
{
|
|
512
606
|
itString: 'hides the specified conversation',
|
|
513
607
|
tag: 'HIDDEN',
|
|
514
|
-
verb: 'hide'
|
|
608
|
+
verb: 'hide',
|
|
515
609
|
},
|
|
516
610
|
{
|
|
517
611
|
itString: 'locks the specified conversation',
|
|
518
612
|
tag: 'LOCKED',
|
|
519
|
-
verb: 'lock'
|
|
613
|
+
verb: 'lock',
|
|
520
614
|
},
|
|
521
615
|
{
|
|
522
616
|
itString: 'mutes the specified conversation',
|
|
523
617
|
tag: 'MUTED',
|
|
524
|
-
verb: 'mute'
|
|
525
|
-
}
|
|
618
|
+
verb: 'mute',
|
|
619
|
+
},
|
|
526
620
|
].forEach(({tag, verb, itString}) => {
|
|
527
621
|
describe(`#${verb}()`, () => {
|
|
528
|
-
it(itString, () =>
|
|
529
|
-
.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
622
|
+
it(itString, () =>
|
|
623
|
+
webex.internal.conversation[verb](conversation)
|
|
624
|
+
.then((activity) => {
|
|
625
|
+
assert.isActivity(activity);
|
|
626
|
+
})
|
|
627
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
628
|
+
.then((c) => assert.include(c.tags, tag))
|
|
629
|
+
);
|
|
534
630
|
});
|
|
535
631
|
});
|
|
536
632
|
|
|
@@ -539,181 +635,226 @@ describe('plugin-conversation', function () {
|
|
|
539
635
|
itString: 'unfavorites the specified conversation',
|
|
540
636
|
setupVerb: 'favorite',
|
|
541
637
|
tag: 'FAVORITE',
|
|
542
|
-
verb: 'unfavorite'
|
|
638
|
+
verb: 'unfavorite',
|
|
543
639
|
},
|
|
544
640
|
{
|
|
545
641
|
itString: 'unhides the specified conversation',
|
|
546
642
|
setupVerb: 'hide',
|
|
547
643
|
tag: 'HIDDEN',
|
|
548
|
-
verb: 'unhide'
|
|
644
|
+
verb: 'unhide',
|
|
549
645
|
},
|
|
550
646
|
{
|
|
551
647
|
itString: 'unlocks the specified conversation',
|
|
552
648
|
setupVerb: 'lock',
|
|
553
649
|
tag: 'LOCKED',
|
|
554
|
-
verb: 'unlock'
|
|
650
|
+
verb: 'unlock',
|
|
555
651
|
},
|
|
556
652
|
{
|
|
557
653
|
itString: 'unmutes the specified conversation',
|
|
558
654
|
setupVerb: 'mute',
|
|
559
655
|
tag: 'MUTED',
|
|
560
|
-
verb: 'unmute'
|
|
561
|
-
}
|
|
562
|
-
].forEach(({
|
|
563
|
-
tag, verb, itString, setupVerb
|
|
564
|
-
}) => {
|
|
656
|
+
verb: 'unmute',
|
|
657
|
+
},
|
|
658
|
+
].forEach(({tag, verb, itString, setupVerb}) => {
|
|
565
659
|
describe(`#${verb}()`, () => {
|
|
566
|
-
beforeEach(() =>
|
|
567
|
-
.catch((reason) => {
|
|
660
|
+
beforeEach(() =>
|
|
661
|
+
webex.internal.conversation[setupVerb](conversation).catch((reason) => {
|
|
568
662
|
if (reason.statusCode !== 403) {
|
|
569
663
|
throw reason;
|
|
570
664
|
}
|
|
571
|
-
}));
|
|
572
|
-
|
|
573
|
-
it(itString, () => webex.internal.conversation[verb](conversation)
|
|
574
|
-
.then((activity) => {
|
|
575
|
-
assert.isActivity(activity);
|
|
576
665
|
})
|
|
577
|
-
|
|
578
|
-
|
|
666
|
+
);
|
|
667
|
+
|
|
668
|
+
it(itString, () =>
|
|
669
|
+
webex.internal.conversation[verb](conversation)
|
|
670
|
+
.then((activity) => {
|
|
671
|
+
assert.isActivity(activity);
|
|
672
|
+
})
|
|
673
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
674
|
+
.then((c) => assert.notInclude(c.tags, tag))
|
|
675
|
+
);
|
|
579
676
|
});
|
|
580
677
|
});
|
|
581
678
|
|
|
582
679
|
describe('#setSpaceProperty()', () => {
|
|
583
|
-
afterEach(() => {
|
|
680
|
+
afterEach(() => {
|
|
681
|
+
conversation = null;
|
|
682
|
+
});
|
|
584
683
|
describe('when the current user is a moderator', () => {
|
|
585
|
-
it('sets announcement mode for the specified conversation', () =>
|
|
586
|
-
.
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
684
|
+
it('sets announcement mode for the specified conversation', () =>
|
|
685
|
+
webex.internal.conversation
|
|
686
|
+
.assignModerator(conversation)
|
|
687
|
+
.catch(allowConflicts)
|
|
688
|
+
.then(() => webex.internal.conversation.lock(conversation))
|
|
689
|
+
.catch(allowConflicts)
|
|
690
|
+
.then(() =>
|
|
691
|
+
webex.internal.conversation.setSpaceProperty(conversation, 'ANNOUNCEMENT')
|
|
692
|
+
)
|
|
693
|
+
.then((activity) => {
|
|
694
|
+
assert.isActivity(activity);
|
|
695
|
+
})
|
|
696
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
697
|
+
.then((c) => assert.include(c.tags, 'ANNOUNCEMENT')));
|
|
595
698
|
});
|
|
596
699
|
|
|
597
700
|
describe('when the current user is not a moderator', () => {
|
|
598
|
-
it('fails to set announcement mode for the specified conversation', () =>
|
|
599
|
-
.
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
701
|
+
it('fails to set announcement mode for the specified conversation', () =>
|
|
702
|
+
webex.internal.conversation
|
|
703
|
+
.assignModerator(conversation)
|
|
704
|
+
.catch(allowConflicts)
|
|
705
|
+
.then(() => webex.internal.conversation.lock(conversation))
|
|
706
|
+
.catch(allowConflicts)
|
|
707
|
+
.then(() =>
|
|
708
|
+
assert.isRejected(
|
|
709
|
+
mccoy.webex.internal.conversation.setSpaceProperty(conversation, 'ANNOUNCEMENT')
|
|
710
|
+
)
|
|
711
|
+
)
|
|
712
|
+
.then((reason) => assert.instanceOf(reason, WebexHttpError.Forbidden)));
|
|
604
713
|
});
|
|
605
714
|
});
|
|
606
715
|
|
|
607
716
|
describe('#unsetSpaceProperty()', () => {
|
|
608
|
-
afterEach(() => {
|
|
717
|
+
afterEach(() => {
|
|
718
|
+
conversation = null;
|
|
719
|
+
});
|
|
609
720
|
describe('when the current user is a moderator', () => {
|
|
610
|
-
it('unsets announcement mode for the specified conversation', () =>
|
|
611
|
-
.
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
721
|
+
it('unsets announcement mode for the specified conversation', () =>
|
|
722
|
+
webex.internal.conversation
|
|
723
|
+
.assignModerator(conversation)
|
|
724
|
+
.catch(allowConflicts)
|
|
725
|
+
.then(() => webex.internal.conversation.lock(conversation))
|
|
726
|
+
.catch(allowConflicts)
|
|
727
|
+
.then(() =>
|
|
728
|
+
webex.internal.conversation.setSpaceProperty(conversation, 'ANNOUNCEMENT')
|
|
729
|
+
)
|
|
730
|
+
.then((activity) => {
|
|
731
|
+
assert.isActivity(activity);
|
|
732
|
+
})
|
|
733
|
+
.then(() =>
|
|
734
|
+
webex.internal.conversation.unsetSpaceProperty(conversation, 'ANNOUNCEMENT')
|
|
735
|
+
)
|
|
736
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
737
|
+
.then((c) => assert.notInclude(c.tags, 'ANNOUNCEMENT')));
|
|
621
738
|
});
|
|
622
739
|
|
|
623
740
|
describe('when the current user is not a moderator', () => {
|
|
624
|
-
it('fails to unset announcement mode for the specified conversation', () =>
|
|
625
|
-
.
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
741
|
+
it('fails to unset announcement mode for the specified conversation', () =>
|
|
742
|
+
webex.internal.conversation
|
|
743
|
+
.assignModerator(conversation)
|
|
744
|
+
.catch(allowConflicts)
|
|
745
|
+
.then(() => webex.internal.conversation.lock(conversation))
|
|
746
|
+
.catch(allowConflicts)
|
|
747
|
+
.then(() =>
|
|
748
|
+
webex.internal.conversation.setSpaceProperty(conversation, 'ANNOUNCEMENT')
|
|
749
|
+
)
|
|
750
|
+
.then((activity) => {
|
|
751
|
+
assert.isActivity(activity);
|
|
752
|
+
})
|
|
753
|
+
.then(() =>
|
|
754
|
+
assert.isRejected(
|
|
755
|
+
mccoy.webex.internal.conversation.unsetSpaceProperty(conversation, 'ANNOUNCEMENT')
|
|
756
|
+
)
|
|
757
|
+
)
|
|
758
|
+
.then((reason) => assert.instanceOf(reason, WebexHttpError.Forbidden)));
|
|
634
759
|
});
|
|
635
760
|
});
|
|
636
761
|
|
|
637
762
|
describe('#removeAllMuteTags()', () => {
|
|
638
|
-
it('removes all mute tags on the convo', () =>
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
763
|
+
it('removes all mute tags on the convo', () =>
|
|
764
|
+
webex.internal.conversation
|
|
765
|
+
.muteMessages(conversation)
|
|
766
|
+
.then(() => webex.internal.conversation.muteMentions(conversation))
|
|
767
|
+
.then(() => webex.internal.conversation.removeAllMuteTags(conversation))
|
|
768
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
769
|
+
.then((c) => {
|
|
770
|
+
assert.notInclude(c.tags, 'MESSAGE_NOTIFICATIONS_ON');
|
|
771
|
+
assert.notInclude(c.tags, 'MESSAGE_NOTIFICATIONS_OFF');
|
|
772
|
+
assert.notInclude(c.tags, 'MENTION_NOTIFICATIONS_ON');
|
|
773
|
+
assert.notInclude(c.tags, 'MESSAGE_NOTIFICATIONS_OFF');
|
|
774
|
+
}));
|
|
648
775
|
|
|
649
|
-
it('removes all unmute tags on the convo', () =>
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
776
|
+
it('removes all unmute tags on the convo', () =>
|
|
777
|
+
webex.internal.conversation
|
|
778
|
+
.unmuteMentions(conversation)
|
|
779
|
+
.then(() => webex.internal.conversation.unmuteMessages(conversation))
|
|
780
|
+
.then(() => webex.internal.conversation.removeAllMuteTags(conversation))
|
|
781
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
782
|
+
.then((c) => {
|
|
783
|
+
assert.notInclude(c.tags, 'MESSAGE_NOTIFICATIONS_ON');
|
|
784
|
+
assert.notInclude(c.tags, 'MESSAGE_NOTIFICATIONS_OFF');
|
|
785
|
+
assert.notInclude(c.tags, 'MENTION_NOTIFICATIONS_ON');
|
|
786
|
+
assert.notInclude(c.tags, 'MESSAGE_NOTIFICATIONS_OFF');
|
|
787
|
+
}));
|
|
659
788
|
});
|
|
660
789
|
|
|
661
790
|
describe('#muteMentions()', () => {
|
|
662
|
-
it('mutes the specified conversation of Mentions only', () =>
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
791
|
+
it('mutes the specified conversation of Mentions only', () =>
|
|
792
|
+
webex.internal.conversation
|
|
793
|
+
.muteMentions(conversation)
|
|
794
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
795
|
+
.then((c) => {
|
|
796
|
+
assert.include(c.tags, 'MENTION_NOTIFICATIONS_OFF');
|
|
797
|
+
assert.notInclude(c.tags, 'MENTION_NOTIFICATIONS_ON');
|
|
798
|
+
}));
|
|
668
799
|
});
|
|
669
800
|
|
|
670
801
|
describe('#unmuteMentions()', () => {
|
|
671
802
|
before(() => webex.internal.conversation.muteMentions(conversation));
|
|
672
803
|
|
|
673
|
-
it('unmutes the specified conversation of Mentions', () =>
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
804
|
+
it('unmutes the specified conversation of Mentions', () =>
|
|
805
|
+
webex.internal.conversation
|
|
806
|
+
.unmuteMentions(conversation)
|
|
807
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
808
|
+
.then((c) => {
|
|
809
|
+
assert.include(c.tags, 'MENTION_NOTIFICATIONS_ON');
|
|
810
|
+
assert.notInclude(c.tags, 'MENTION_NOTIFICATIONS_OFF');
|
|
811
|
+
}));
|
|
679
812
|
});
|
|
680
813
|
|
|
681
814
|
describe('#muteMessages()', () => {
|
|
682
|
-
it('mutes the specified conversation of Messages only', () =>
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
815
|
+
it('mutes the specified conversation of Messages only', () =>
|
|
816
|
+
webex.internal.conversation
|
|
817
|
+
.muteMessages(conversation)
|
|
818
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
819
|
+
.then((c) => {
|
|
820
|
+
assert.include(c.tags, 'MESSAGE_NOTIFICATIONS_OFF');
|
|
821
|
+
assert.notInclude(c.tags, 'MESSAGE_NOTIFICATIONS_ON');
|
|
822
|
+
}));
|
|
688
823
|
});
|
|
689
824
|
|
|
690
825
|
describe('#unmuteMessages()', () => {
|
|
691
826
|
before(() => webex.internal.conversation.muteMessages(conversation));
|
|
692
827
|
|
|
693
|
-
it('unmutes the specified conversation of Messages only', () =>
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
828
|
+
it('unmutes the specified conversation of Messages only', () =>
|
|
829
|
+
webex.internal.conversation
|
|
830
|
+
.unmuteMessages(conversation)
|
|
831
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
832
|
+
.then((c) => {
|
|
833
|
+
assert.include(c.tags, 'MESSAGE_NOTIFICATIONS_ON');
|
|
834
|
+
assert.notInclude(c.tags, 'MESSAGE_NOTIFICATIONS_OFF');
|
|
835
|
+
}));
|
|
699
836
|
});
|
|
700
837
|
|
|
701
838
|
describe('#ignore()', () => {
|
|
702
|
-
it('ignores the specified conversation', () =>
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
839
|
+
it('ignores the specified conversation', () =>
|
|
840
|
+
webex.internal.conversation
|
|
841
|
+
.ignore(conversation)
|
|
842
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
843
|
+
.then((c) => {
|
|
844
|
+
assert.include(c.tags, 'IGNORED');
|
|
845
|
+
}));
|
|
707
846
|
});
|
|
708
847
|
|
|
709
848
|
describe('#unignore()', () => {
|
|
710
849
|
before(() => webex.internal.conversation.ignore(conversation));
|
|
711
850
|
|
|
712
|
-
it('ignores the specified conversation', () =>
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
851
|
+
it('ignores the specified conversation', () =>
|
|
852
|
+
webex.internal.conversation
|
|
853
|
+
.unignore(conversation)
|
|
854
|
+
.then(() => webex.internal.conversation.get(conversation))
|
|
855
|
+
.then((c) => {
|
|
856
|
+
assert.notInclude(c.tags, 'IGNORED');
|
|
857
|
+
}));
|
|
717
858
|
});
|
|
718
859
|
});
|
|
719
860
|
|
|
@@ -722,7 +863,8 @@ describe('plugin-conversation', function () {
|
|
|
722
863
|
|
|
723
864
|
before(() => {
|
|
724
865
|
if (!conversation) {
|
|
725
|
-
return webex.internal.conversation
|
|
866
|
+
return webex.internal.conversation
|
|
867
|
+
.create({displayName: 'displayName', participants})
|
|
726
868
|
.then((c) => {
|
|
727
869
|
conversation = c;
|
|
728
870
|
});
|
|
@@ -732,45 +874,62 @@ describe('plugin-conversation', function () {
|
|
|
732
874
|
});
|
|
733
875
|
|
|
734
876
|
describe('#acknowledge()', () => {
|
|
735
|
-
it('acknowledges the specified activity', () =>
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
.then((
|
|
877
|
+
it('acknowledges the specified activity', () =>
|
|
878
|
+
webex.internal.conversation
|
|
879
|
+
.post(conversation, {displayName: 'A comment to acknowledge'})
|
|
880
|
+
.then((activity) =>
|
|
881
|
+
mccoy.webex.internal.conversation.acknowledge(conversation, activity)
|
|
882
|
+
)
|
|
883
|
+
.then((ack) =>
|
|
884
|
+
webex.internal.conversation
|
|
885
|
+
.get(conversation, {activitiesLimit: 1})
|
|
886
|
+
.then((c) => assert.equal(c.activities.items[0].url, ack.object.url))
|
|
887
|
+
));
|
|
739
888
|
});
|
|
740
889
|
|
|
741
890
|
describe('#assignModerator()', () => {
|
|
742
|
-
it('assigns a moderator to a conversation', () =>
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
891
|
+
it('assigns a moderator to a conversation', () =>
|
|
892
|
+
webex.internal.conversation
|
|
893
|
+
.assignModerator(conversation, spock)
|
|
894
|
+
.then(() =>
|
|
895
|
+
webex.internal.conversation.get(conversation, {
|
|
896
|
+
activitiesLimit: 5,
|
|
897
|
+
includeParticipants: true,
|
|
898
|
+
})
|
|
899
|
+
)
|
|
900
|
+
.then((c) => {
|
|
901
|
+
const moderators = c.participants.items.filter(
|
|
902
|
+
(p) => p.roomProperties && p.roomProperties.isModerator
|
|
903
|
+
);
|
|
749
904
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
905
|
+
assert.lengthOf(moderators, 1);
|
|
906
|
+
assert.equal(moderators[0].id, spock.id);
|
|
907
|
+
}));
|
|
753
908
|
});
|
|
754
909
|
|
|
755
910
|
describe('#delete()', () => {
|
|
756
911
|
let sampleImageSmallOnePng = 'sample-image-small-one.png';
|
|
757
912
|
|
|
758
|
-
before(() =>
|
|
759
|
-
.then((res) => {
|
|
913
|
+
before(() =>
|
|
914
|
+
fh.fetch(sampleImageSmallOnePng).then((res) => {
|
|
760
915
|
sampleImageSmallOnePng = res;
|
|
761
|
-
})
|
|
916
|
+
})
|
|
917
|
+
);
|
|
762
918
|
|
|
763
|
-
it(
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
919
|
+
it("deletes the current user's post", () =>
|
|
920
|
+
webex.internal.conversation
|
|
921
|
+
.post(conversation, {displayName: 'Delete Me 1'})
|
|
922
|
+
.then((a) => webex.internal.conversation.delete(conversation, a))
|
|
923
|
+
.then(() => new Promise((resolve) => setTimeout(resolve, 2000)))
|
|
924
|
+
.then(() => webex.internal.conversation.get(conversation, {activitiesLimit: 2}))
|
|
925
|
+
.then((c) => {
|
|
926
|
+
assert.equal(c.activities.items[0].verb, 'tombstone');
|
|
927
|
+
assert.equal(c.activities.items[1].verb, 'delete');
|
|
928
|
+
}));
|
|
771
929
|
|
|
772
|
-
it(
|
|
773
|
-
webex.internal.conversation
|
|
930
|
+
it("deletes the current user's share", () =>
|
|
931
|
+
webex.internal.conversation
|
|
932
|
+
.share(conversation, [sampleImageSmallOnePng])
|
|
774
933
|
.then((a) => webex.internal.conversation.delete(conversation, a))
|
|
775
934
|
.then(() => new Promise((resolve) => setTimeout(resolve, 2000)))
|
|
776
935
|
.then(() => webex.internal.conversation.get(conversation, {activitiesLimit: 2}))
|
|
@@ -780,68 +939,96 @@ describe('plugin-conversation', function () {
|
|
|
780
939
|
}));
|
|
781
940
|
|
|
782
941
|
describe('when the current user is a moderator', () => {
|
|
783
|
-
it(
|
|
784
|
-
.
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
942
|
+
it("deletes any user's content", () =>
|
|
943
|
+
webex.internal.conversation
|
|
944
|
+
.assignModerator(conversation)
|
|
945
|
+
.catch(allowConflicts)
|
|
946
|
+
.then(() => webex.internal.conversation.lock(conversation))
|
|
947
|
+
.catch(allowConflicts)
|
|
948
|
+
.then(() =>
|
|
949
|
+
mccoy.webex.internal.conversation.post(conversation, {displayName: 'Delete Me 2'})
|
|
950
|
+
)
|
|
951
|
+
.then((a) => webex.internal.conversation.delete(conversation, a)));
|
|
789
952
|
});
|
|
790
953
|
|
|
791
954
|
describe('when the current user is not a moderator', () => {
|
|
792
|
-
it(
|
|
793
|
-
.
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
955
|
+
it("fails to delete other users' content", () =>
|
|
956
|
+
webex.internal.conversation
|
|
957
|
+
.assignModerator(conversation)
|
|
958
|
+
.catch(allowConflicts)
|
|
959
|
+
.then(() => webex.internal.conversation.lock(conversation))
|
|
960
|
+
.catch(allowConflicts)
|
|
961
|
+
.then(() =>
|
|
962
|
+
webex.internal.conversation.post(conversation, {displayName: 'Delete Me 3'})
|
|
963
|
+
)
|
|
964
|
+
.then((a) =>
|
|
965
|
+
assert.isRejected(mccoy.webex.internal.conversation.delete(conversation, a))
|
|
966
|
+
)
|
|
967
|
+
.then((reason) => assert.instanceOf(reason, WebexHttpError.Forbidden)));
|
|
799
968
|
});
|
|
800
969
|
});
|
|
801
970
|
|
|
802
971
|
describe('#addReaction', () => {
|
|
803
|
-
it('adds a reaction', () =>
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
972
|
+
it('adds a reaction', () =>
|
|
973
|
+
webex.internal.conversation
|
|
974
|
+
.post(conversation, {displayName: 'React Me 1'})
|
|
975
|
+
.then((activity) =>
|
|
976
|
+
webex.internal.conversation.addReaction(conversation, 'smiley', activity)
|
|
977
|
+
)
|
|
978
|
+
.then((reaction) => {
|
|
979
|
+
assert.equal(reaction.verb, 'add');
|
|
980
|
+
assert.equal(reaction.object.objectType, 'reaction2');
|
|
981
|
+
assert.equal(reaction.object.displayName, 'smiley');
|
|
982
|
+
}));
|
|
810
983
|
});
|
|
811
984
|
|
|
812
985
|
describe('#deleteReaction', () => {
|
|
813
|
-
it('deletes a reaction', () =>
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
986
|
+
it('deletes a reaction', () =>
|
|
987
|
+
webex.internal.conversation
|
|
988
|
+
.post(conversation, {displayName: 'React Me 1'})
|
|
989
|
+
.then((activity) =>
|
|
990
|
+
webex.internal.conversation.addReaction(conversation, 'smiley', activity)
|
|
991
|
+
)
|
|
992
|
+
.then((reaction) =>
|
|
993
|
+
webex.internal.conversation.deleteReaction(conversation, reaction.id)
|
|
994
|
+
)
|
|
995
|
+
.then((deleteReaction) => {
|
|
996
|
+
assert.equal(deleteReaction.verb, 'delete');
|
|
997
|
+
assert.equal(deleteReaction.object.verb, 'tombstone');
|
|
998
|
+
assert.equal(deleteReaction.object.parent.type, 'reaction');
|
|
999
|
+
}));
|
|
821
1000
|
});
|
|
822
1001
|
|
|
823
1002
|
describe('#unassignModerator()', () => {
|
|
824
|
-
it('removes a moderator from a conversation', () =>
|
|
825
|
-
.
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
1003
|
+
it('removes a moderator from a conversation', () =>
|
|
1004
|
+
webex.internal.conversation
|
|
1005
|
+
.assignModerator(conversation, spock)
|
|
1006
|
+
.catch(allowConflicts)
|
|
1007
|
+
.then(() => webex.internal.conversation.unassignModerator(conversation, spock))
|
|
1008
|
+
.then(() =>
|
|
1009
|
+
webex.internal.conversation.get(conversation, {
|
|
1010
|
+
activitiesLimit: 5,
|
|
1011
|
+
includeParticipants: true,
|
|
1012
|
+
})
|
|
1013
|
+
)
|
|
1014
|
+
.then((c) => {
|
|
1015
|
+
const moderators = c.participants.items.filter(
|
|
1016
|
+
(p) => p.roomProperties && p.roomProperties.isModerator
|
|
1017
|
+
);
|
|
833
1018
|
|
|
834
|
-
|
|
835
|
-
|
|
1019
|
+
assert.lengthOf(moderators, 0);
|
|
1020
|
+
}));
|
|
836
1021
|
});
|
|
837
1022
|
|
|
838
1023
|
describe('#update()', () => {
|
|
839
|
-
it('renames the specified conversation', () =>
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1024
|
+
it('renames the specified conversation', () =>
|
|
1025
|
+
webex.internal.conversation
|
|
1026
|
+
.update(conversation, {
|
|
1027
|
+
displayName: 'displayName2',
|
|
1028
|
+
objectType: 'conversation',
|
|
1029
|
+
})
|
|
1030
|
+
.then((c) => webex.internal.conversation.get({url: c.target.url}))
|
|
1031
|
+
.then((c) => assert.equal(c.displayName, 'displayName2')));
|
|
845
1032
|
});
|
|
846
1033
|
});
|
|
847
1034
|
});
|