@webex/internal-plugin-conversation 2.59.2 → 2.59.3-next.1
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/.eslintrc.js +6 -6
- package/README.md +47 -47
- package/babel.config.js +3 -3
- package/dist/activities.js +4 -4
- package/dist/activities.js.map +1 -1
- package/dist/activity-thread-ordering.js +34 -34
- package/dist/activity-thread-ordering.js.map +1 -1
- package/dist/config.js +12 -12
- package/dist/config.js.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/conversation.js +474 -474
- package/dist/conversation.js.map +1 -1
- package/dist/convo-error.js +4 -4
- package/dist/convo-error.js.map +1 -1
- package/dist/decryption-transforms.js +155 -155
- package/dist/decryption-transforms.js.map +1 -1
- package/dist/encryption-transforms.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/share-activity.js +57 -57
- package/dist/share-activity.js.map +1 -1
- package/dist/to-array.js +7 -7
- package/dist/to-array.js.map +1 -1
- package/jest.config.js +3 -3
- package/package.json +21 -20
- package/process +1 -1
- package/src/activities.js +157 -157
- package/src/activity-thread-ordering.js +283 -283
- package/src/activity-threading.md +282 -282
- package/src/config.js +37 -37
- package/src/constants.js +3 -3
- package/src/conversation.js +2535 -2535
- package/src/convo-error.js +15 -15
- package/src/decryption-transforms.js +541 -541
- package/src/encryption-transforms.js +345 -345
- package/src/index.js +327 -327
- package/src/share-activity.js +436 -436
- package/src/to-array.js +29 -29
- package/test/integration/spec/create.js +290 -290
- package/test/integration/spec/encryption.js +333 -333
- package/test/integration/spec/get.js +1255 -1255
- package/test/integration/spec/mercury.js +94 -94
- package/test/integration/spec/share.js +537 -537
- package/test/integration/spec/verbs.js +1041 -1041
- package/test/unit/spec/conversation.js +823 -823
- package/test/unit/spec/decrypt-transforms.js +460 -460
- package/test/unit/spec/encryption-transforms.js +93 -93
- package/test/unit/spec/share-activity.js +178 -178
package/src/to-array.js
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {isFunction} from 'lodash';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Helper to convert objects into arrays of transforms. probably belongs in
|
|
9
|
-
* webex-core
|
|
10
|
-
* @param {string} direction "inbound"|"outbound"
|
|
11
|
-
* @param {Object} obj
|
|
12
|
-
* @private
|
|
13
|
-
* @returns {Array}
|
|
14
|
-
*/
|
|
15
|
-
export default function toArray(direction, obj) {
|
|
16
|
-
return Object.keys(obj).map((name) => {
|
|
17
|
-
const entry = obj[name];
|
|
18
|
-
|
|
19
|
-
if (isFunction(entry)) {
|
|
20
|
-
return {
|
|
21
|
-
name,
|
|
22
|
-
direction,
|
|
23
|
-
fn: entry,
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return {name, ...entry};
|
|
28
|
-
});
|
|
29
|
-
}
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {isFunction} from 'lodash';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Helper to convert objects into arrays of transforms. probably belongs in
|
|
9
|
+
* webex-core
|
|
10
|
+
* @param {string} direction "inbound"|"outbound"
|
|
11
|
+
* @param {Object} obj
|
|
12
|
+
* @private
|
|
13
|
+
* @returns {Array}
|
|
14
|
+
*/
|
|
15
|
+
export default function toArray(direction, obj) {
|
|
16
|
+
return Object.keys(obj).map((name) => {
|
|
17
|
+
const entry = obj[name];
|
|
18
|
+
|
|
19
|
+
if (isFunction(entry)) {
|
|
20
|
+
return {
|
|
21
|
+
name,
|
|
22
|
+
direction,
|
|
23
|
+
fn: entry,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return {name, ...entry};
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -1,290 +1,290 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {InvalidUserCreation} from '@webex/internal-plugin-conversation';
|
|
6
|
-
import {patterns} from '@webex/common';
|
|
7
|
-
import WebexCore, {WebexHttpError} from '@webex/webex-core';
|
|
8
|
-
import {assert} from '@webex/test-helper-chai';
|
|
9
|
-
import testUsers from '@webex/test-helper-test-users';
|
|
10
|
-
import {find, last, map} from 'lodash';
|
|
11
|
-
import uuid from 'uuid';
|
|
12
|
-
import fh from '@webex/test-helper-file';
|
|
13
|
-
|
|
14
|
-
describe('plugin-conversation', function () {
|
|
15
|
-
this.timeout(60000);
|
|
16
|
-
describe('#create()', () => {
|
|
17
|
-
let checkov, kirk, mccoy, participants, webex, spock;
|
|
18
|
-
let sampleTextOne = 'sample-text-one.txt';
|
|
19
|
-
|
|
20
|
-
before(async () => {
|
|
21
|
-
[spock, mccoy, checkov, kirk] = await testUsers.create({count: 4});
|
|
22
|
-
participants = [spock, mccoy, checkov];
|
|
23
|
-
|
|
24
|
-
// Pause for 5 seconds for CI
|
|
25
|
-
await new Promise((done) => setTimeout(done, 5000));
|
|
26
|
-
|
|
27
|
-
webex = new WebexCore({
|
|
28
|
-
credentials: {
|
|
29
|
-
authorization: spock.token,
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
webex.config.conversation.allowedOutboundTags = {
|
|
34
|
-
strong: [],
|
|
35
|
-
};
|
|
36
|
-
webex.config.conversation.allowedInboundTags = {
|
|
37
|
-
strong: [],
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
mccoy.webex = new WebexCore({
|
|
41
|
-
credentials: {
|
|
42
|
-
authorization: mccoy.token,
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// eslint-disable-next-line no-unused-expressions
|
|
47
|
-
await webex.internal.mercury.connect();
|
|
48
|
-
await mccoy.webex.internal.mercury.connect();
|
|
49
|
-
|
|
50
|
-
sampleTextOne = await fh.fetch(sampleTextOne);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
after(async () => {
|
|
54
|
-
// eslint-disable-next-line no-unused-expressions
|
|
55
|
-
webex && (await webex.internal.mercury.disconnect());
|
|
56
|
-
// eslint-disable-next-line no-unused-expressions
|
|
57
|
-
mccoy && (await mccoy.webex.internal.mercury.disconnect());
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
function makeEmailAddress() {
|
|
61
|
-
return `webex-js-sdk--test-${uuid.v4()}@example.com`;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
describe('when there is only one other participant', () => {
|
|
65
|
-
it('creates a 1:1 conversation', () =>
|
|
66
|
-
webex.internal.conversation.create({participants: [mccoy]}).then((conversation) => {
|
|
67
|
-
assert.isConversation(conversation);
|
|
68
|
-
assert.isOneOnOneConversation(conversation);
|
|
69
|
-
assert.isNewEncryptedConversation(conversation);
|
|
70
|
-
|
|
71
|
-
assert.lengthOf(conversation.participants.items, 2);
|
|
72
|
-
assert.lengthOf(conversation.activities.items, 1);
|
|
73
|
-
}));
|
|
74
|
-
|
|
75
|
-
// TODO: Issues with side boarding users too soon. Skipping until it's fixed
|
|
76
|
-
describe.skip("when the other user doesn't exist", () => {
|
|
77
|
-
let email;
|
|
78
|
-
|
|
79
|
-
beforeEach(() => {
|
|
80
|
-
email = makeEmailAddress();
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('invites the other user', () =>
|
|
84
|
-
webex.internal.conversation.create({participants: [email]}).then((conversation) => {
|
|
85
|
-
assert.isConversation(conversation);
|
|
86
|
-
assert.isOneOnOneConversation(conversation);
|
|
87
|
-
assert.isNewEncryptedConversation(conversation);
|
|
88
|
-
|
|
89
|
-
const participant = find(conversation.participants.items, {emailAddress: email});
|
|
90
|
-
|
|
91
|
-
assert.include(participant.tags, 'SIDE_BOARDED');
|
|
92
|
-
assert.match(participant.id, patterns.uuid);
|
|
93
|
-
}));
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
describe('when the conversation already exists', () => {
|
|
97
|
-
describe('with skipOneOnOneFetch=true', () => {
|
|
98
|
-
it('fails to create a 1:1 conversation that already exists', () =>
|
|
99
|
-
assert
|
|
100
|
-
.isRejected(
|
|
101
|
-
webex.internal.conversation.create(
|
|
102
|
-
{participants: [mccoy]},
|
|
103
|
-
{skipOneOnOneFetch: true}
|
|
104
|
-
)
|
|
105
|
-
)
|
|
106
|
-
.then((reason) => assert.instanceOf(reason, WebexHttpError.Conflict)));
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('returns the preexisting conversation', () =>
|
|
110
|
-
webex.internal.conversation.create({participants: [checkov]}).then((conversation) =>
|
|
111
|
-
webex.internal.conversation.create({participants: [checkov]}).then((conversation2) => {
|
|
112
|
-
assert.equal(conversation2.url, conversation.url);
|
|
113
|
-
assert.lengthOf(conversation.activities.items, 1);
|
|
114
|
-
assert.equal(conversation.activities.items[0].verb, 'create');
|
|
115
|
-
})
|
|
116
|
-
));
|
|
117
|
-
|
|
118
|
-
it('returns the preexisting conversation and posts a comment', () =>
|
|
119
|
-
webex.internal.conversation
|
|
120
|
-
.create({participants: [checkov], comment: 'hi'})
|
|
121
|
-
.then((conversation) =>
|
|
122
|
-
webex.internal.conversation
|
|
123
|
-
.create({participants: [checkov]})
|
|
124
|
-
.then((conversation2) => {
|
|
125
|
-
assert.equal(conversation2.id, conversation.id);
|
|
126
|
-
// the first activity is "create"; get the "post"
|
|
127
|
-
const activity = conversation.activities.items.pop();
|
|
128
|
-
|
|
129
|
-
assert.equal(activity.verb, 'post');
|
|
130
|
-
assert.equal(activity.object.displayName, 'hi');
|
|
131
|
-
})
|
|
132
|
-
));
|
|
133
|
-
|
|
134
|
-
it('returns the preexisting conversation and posts a comment with html', () =>
|
|
135
|
-
webex.internal.conversation
|
|
136
|
-
.create({participants: [checkov], comment: '**hi**', html: '<strong>hi</strong>'})
|
|
137
|
-
.then((conversation) =>
|
|
138
|
-
webex.internal.conversation
|
|
139
|
-
.create({participants: [checkov]})
|
|
140
|
-
.then((conversation2) => {
|
|
141
|
-
assert.equal(conversation2.id, conversation.id);
|
|
142
|
-
// the first activity is "create"; get the "post"
|
|
143
|
-
const activity = conversation.activities.items.pop();
|
|
144
|
-
|
|
145
|
-
assert.equal(activity.verb, 'post');
|
|
146
|
-
assert.equal(activity.object.displayName, '**hi**');
|
|
147
|
-
assert.equal(activity.object.content, '<strong>hi</strong>');
|
|
148
|
-
})
|
|
149
|
-
));
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
describe('when {forceGrouped: true} is specified', () => {
|
|
153
|
-
it('creates a grouped conversation @canary', () =>
|
|
154
|
-
webex.internal.conversation
|
|
155
|
-
.create({participants: [mccoy]}, {forceGrouped: true})
|
|
156
|
-
.then((conversation) => {
|
|
157
|
-
assert.isConversation(conversation);
|
|
158
|
-
assert.isGroupConversation(conversation);
|
|
159
|
-
assert.isNewEncryptedConversation(conversation);
|
|
160
|
-
|
|
161
|
-
assert.lengthOf(conversation.participants.items, 2);
|
|
162
|
-
assert.lengthOf(conversation.activities.items, 1);
|
|
163
|
-
}));
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
describe('when there is an invalid user in the participants list', () => {
|
|
168
|
-
describe('with allowPartialCreation', () => {
|
|
169
|
-
it('creates a group conversation', () =>
|
|
170
|
-
webex.internal.conversation
|
|
171
|
-
.create({participants: [mccoy, 'invalidUser']}, {allowPartialCreation: true})
|
|
172
|
-
.then((conversation) => {
|
|
173
|
-
assert.isConversation(conversation);
|
|
174
|
-
assert.isGroupConversation(conversation);
|
|
175
|
-
assert.isNewEncryptedConversation(conversation);
|
|
176
|
-
|
|
177
|
-
assert.lengthOf(conversation.participants.items, 2);
|
|
178
|
-
assert.lengthOf(conversation.activities.items, 1);
|
|
179
|
-
}));
|
|
180
|
-
|
|
181
|
-
it('creates a group conversation with invalid uuid', () =>
|
|
182
|
-
testUsers
|
|
183
|
-
.remove([kirk])
|
|
184
|
-
.then(() =>
|
|
185
|
-
webex.internal.conversation.create(
|
|
186
|
-
{participants: [mccoy.id, kirk.id]},
|
|
187
|
-
{allowPartialCreation: true}
|
|
188
|
-
)
|
|
189
|
-
)
|
|
190
|
-
.then((conversation) => {
|
|
191
|
-
assert.isConversation(conversation);
|
|
192
|
-
assert.isGroupConversation(conversation);
|
|
193
|
-
assert.isNewEncryptedConversation(conversation);
|
|
194
|
-
|
|
195
|
-
assert.lengthOf(conversation.participants.items, 2);
|
|
196
|
-
assert.lengthOf(conversation.activities.items, 1);
|
|
197
|
-
}));
|
|
198
|
-
|
|
199
|
-
it('fails to create a 1:1 conversation', () =>
|
|
200
|
-
assert
|
|
201
|
-
.isRejected(
|
|
202
|
-
webex.internal.conversation.create(
|
|
203
|
-
{participants: ['invalidUser']},
|
|
204
|
-
{allowPartialCreation: true}
|
|
205
|
-
)
|
|
206
|
-
)
|
|
207
|
-
.then((reason) => assert.instanceOf(reason, InvalidUserCreation)));
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
describe('without allowPartialCreation', () => {
|
|
211
|
-
it('fails to create a group conversation without allowPartialCreation param', () =>
|
|
212
|
-
assert.isRejected(
|
|
213
|
-
webex.internal.conversation.create({participants: [mccoy, 'invalidUser']})
|
|
214
|
-
));
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
describe('when {compact: ?} is not specified', () => {
|
|
219
|
-
it('creates a compact conversation', () =>
|
|
220
|
-
webex.internal.conversation
|
|
221
|
-
.create({participants})
|
|
222
|
-
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 5}))
|
|
223
|
-
.then((c) => assert.lengthOf(c.activities.items, 1)));
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it('creates a conversation with a name', () =>
|
|
227
|
-
webex.internal.conversation
|
|
228
|
-
.create({displayName: 'displayName', participants})
|
|
229
|
-
.then((c) => webex.internal.conversation.get(c))
|
|
230
|
-
.then((c) => assert.equal(c.displayName, 'displayName')));
|
|
231
|
-
|
|
232
|
-
it('creates a conversation with a comment', () =>
|
|
233
|
-
webex.internal.conversation
|
|
234
|
-
.create({comment: 'comment', participants})
|
|
235
|
-
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 2}))
|
|
236
|
-
.then((c) => assert.equal(c.activities.items[1].object.displayName, 'comment')));
|
|
237
|
-
|
|
238
|
-
it('creates a conversation with a tag', () =>
|
|
239
|
-
webex.internal.conversation
|
|
240
|
-
.create({tags: ['WELCOME'], participants})
|
|
241
|
-
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 1}))
|
|
242
|
-
.then((c) => assert.equal(c.tags[0], 'WELCOME')));
|
|
243
|
-
|
|
244
|
-
it('creates a favorite conversation', () =>
|
|
245
|
-
webex.internal.conversation
|
|
246
|
-
.create({favorite: true, participants})
|
|
247
|
-
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 1}))
|
|
248
|
-
.then((c) => assert.equal(c.tags[0], 'FAVORITE')));
|
|
249
|
-
|
|
250
|
-
it('creates a conversation with a comment with html', () =>
|
|
251
|
-
webex.internal.conversation
|
|
252
|
-
.create({comment: '**comment**', html: '<strong>comment</strong>', participants})
|
|
253
|
-
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 2}))
|
|
254
|
-
.then((c) => {
|
|
255
|
-
assert.equal(c.activities.items[1].object.displayName, '**comment**');
|
|
256
|
-
assert.equal(c.activities.items[1].object.content, '<strong>comment</strong>');
|
|
257
|
-
}));
|
|
258
|
-
|
|
259
|
-
it('creates a conversation with a share', () =>
|
|
260
|
-
webex.internal.conversation
|
|
261
|
-
.create({participants, files: [sampleTextOne]})
|
|
262
|
-
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 10}))
|
|
263
|
-
.then((c) => {
|
|
264
|
-
assert.equal(last(c.activities.items).verb, 'share');
|
|
265
|
-
|
|
266
|
-
return webex.internal.conversation.download(
|
|
267
|
-
last(c.activities.items).object.files.items[0]
|
|
268
|
-
);
|
|
269
|
-
})
|
|
270
|
-
.then((file) => fh.isMatchingFile(file, sampleTextOne)));
|
|
271
|
-
|
|
272
|
-
it('ensures the current user is in the participants list', () =>
|
|
273
|
-
webex.internal.conversation
|
|
274
|
-
.create({comment: 'comment', participants: [mccoy, checkov]})
|
|
275
|
-
.then((c) => webex.internal.conversation.get(c, {includeParticipants: true}))
|
|
276
|
-
.then((c) => assert.include(map(c.participants.items, 'id'), spock.id)));
|
|
277
|
-
|
|
278
|
-
it('does not allow me to create a conversation with zero participants', () =>
|
|
279
|
-
assert.isRejected(
|
|
280
|
-
webex.internal.conversation.create({participants: []}, /`params.participants` is required/)
|
|
281
|
-
));
|
|
282
|
-
|
|
283
|
-
it('does not allow me to create a classified space when feature toggle is disabled for the org', () =>
|
|
284
|
-
webex.internal.conversation
|
|
285
|
-
.create({participants: [mccoy, checkov], classificationId: 'abcde-12345-Some-UUID'})
|
|
286
|
-
.catch((err) =>
|
|
287
|
-
assert.match(err.toString(), /Org not entitled for space classifications/)
|
|
288
|
-
));
|
|
289
|
-
});
|
|
290
|
-
});
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {InvalidUserCreation} from '@webex/internal-plugin-conversation';
|
|
6
|
+
import {patterns} from '@webex/common';
|
|
7
|
+
import WebexCore, {WebexHttpError} from '@webex/webex-core';
|
|
8
|
+
import {assert} from '@webex/test-helper-chai';
|
|
9
|
+
import testUsers from '@webex/test-helper-test-users';
|
|
10
|
+
import {find, last, map} from 'lodash';
|
|
11
|
+
import uuid from 'uuid';
|
|
12
|
+
import fh from '@webex/test-helper-file';
|
|
13
|
+
|
|
14
|
+
describe('plugin-conversation', function () {
|
|
15
|
+
this.timeout(60000);
|
|
16
|
+
describe('#create()', () => {
|
|
17
|
+
let checkov, kirk, mccoy, participants, webex, spock;
|
|
18
|
+
let sampleTextOne = 'sample-text-one.txt';
|
|
19
|
+
|
|
20
|
+
before(async () => {
|
|
21
|
+
[spock, mccoy, checkov, kirk] = await testUsers.create({count: 4});
|
|
22
|
+
participants = [spock, mccoy, checkov];
|
|
23
|
+
|
|
24
|
+
// Pause for 5 seconds for CI
|
|
25
|
+
await new Promise((done) => setTimeout(done, 5000));
|
|
26
|
+
|
|
27
|
+
webex = new WebexCore({
|
|
28
|
+
credentials: {
|
|
29
|
+
authorization: spock.token,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
webex.config.conversation.allowedOutboundTags = {
|
|
34
|
+
strong: [],
|
|
35
|
+
};
|
|
36
|
+
webex.config.conversation.allowedInboundTags = {
|
|
37
|
+
strong: [],
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
mccoy.webex = new WebexCore({
|
|
41
|
+
credentials: {
|
|
42
|
+
authorization: mccoy.token,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// eslint-disable-next-line no-unused-expressions
|
|
47
|
+
await webex.internal.mercury.connect();
|
|
48
|
+
await mccoy.webex.internal.mercury.connect();
|
|
49
|
+
|
|
50
|
+
sampleTextOne = await fh.fetch(sampleTextOne);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
after(async () => {
|
|
54
|
+
// eslint-disable-next-line no-unused-expressions
|
|
55
|
+
webex && (await webex.internal.mercury.disconnect());
|
|
56
|
+
// eslint-disable-next-line no-unused-expressions
|
|
57
|
+
mccoy && (await mccoy.webex.internal.mercury.disconnect());
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
function makeEmailAddress() {
|
|
61
|
+
return `webex-js-sdk--test-${uuid.v4()}@example.com`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
describe('when there is only one other participant', () => {
|
|
65
|
+
it('creates a 1:1 conversation', () =>
|
|
66
|
+
webex.internal.conversation.create({participants: [mccoy]}).then((conversation) => {
|
|
67
|
+
assert.isConversation(conversation);
|
|
68
|
+
assert.isOneOnOneConversation(conversation);
|
|
69
|
+
assert.isNewEncryptedConversation(conversation);
|
|
70
|
+
|
|
71
|
+
assert.lengthOf(conversation.participants.items, 2);
|
|
72
|
+
assert.lengthOf(conversation.activities.items, 1);
|
|
73
|
+
}));
|
|
74
|
+
|
|
75
|
+
// TODO: Issues with side boarding users too soon. Skipping until it's fixed
|
|
76
|
+
describe.skip("when the other user doesn't exist", () => {
|
|
77
|
+
let email;
|
|
78
|
+
|
|
79
|
+
beforeEach(() => {
|
|
80
|
+
email = makeEmailAddress();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('invites the other user', () =>
|
|
84
|
+
webex.internal.conversation.create({participants: [email]}).then((conversation) => {
|
|
85
|
+
assert.isConversation(conversation);
|
|
86
|
+
assert.isOneOnOneConversation(conversation);
|
|
87
|
+
assert.isNewEncryptedConversation(conversation);
|
|
88
|
+
|
|
89
|
+
const participant = find(conversation.participants.items, {emailAddress: email});
|
|
90
|
+
|
|
91
|
+
assert.include(participant.tags, 'SIDE_BOARDED');
|
|
92
|
+
assert.match(participant.id, patterns.uuid);
|
|
93
|
+
}));
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('when the conversation already exists', () => {
|
|
97
|
+
describe('with skipOneOnOneFetch=true', () => {
|
|
98
|
+
it('fails to create a 1:1 conversation that already exists', () =>
|
|
99
|
+
assert
|
|
100
|
+
.isRejected(
|
|
101
|
+
webex.internal.conversation.create(
|
|
102
|
+
{participants: [mccoy]},
|
|
103
|
+
{skipOneOnOneFetch: true}
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
.then((reason) => assert.instanceOf(reason, WebexHttpError.Conflict)));
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('returns the preexisting conversation', () =>
|
|
110
|
+
webex.internal.conversation.create({participants: [checkov]}).then((conversation) =>
|
|
111
|
+
webex.internal.conversation.create({participants: [checkov]}).then((conversation2) => {
|
|
112
|
+
assert.equal(conversation2.url, conversation.url);
|
|
113
|
+
assert.lengthOf(conversation.activities.items, 1);
|
|
114
|
+
assert.equal(conversation.activities.items[0].verb, 'create');
|
|
115
|
+
})
|
|
116
|
+
));
|
|
117
|
+
|
|
118
|
+
it('returns the preexisting conversation and posts a comment', () =>
|
|
119
|
+
webex.internal.conversation
|
|
120
|
+
.create({participants: [checkov], comment: 'hi'})
|
|
121
|
+
.then((conversation) =>
|
|
122
|
+
webex.internal.conversation
|
|
123
|
+
.create({participants: [checkov]})
|
|
124
|
+
.then((conversation2) => {
|
|
125
|
+
assert.equal(conversation2.id, conversation.id);
|
|
126
|
+
// the first activity is "create"; get the "post"
|
|
127
|
+
const activity = conversation.activities.items.pop();
|
|
128
|
+
|
|
129
|
+
assert.equal(activity.verb, 'post');
|
|
130
|
+
assert.equal(activity.object.displayName, 'hi');
|
|
131
|
+
})
|
|
132
|
+
));
|
|
133
|
+
|
|
134
|
+
it('returns the preexisting conversation and posts a comment with html', () =>
|
|
135
|
+
webex.internal.conversation
|
|
136
|
+
.create({participants: [checkov], comment: '**hi**', html: '<strong>hi</strong>'})
|
|
137
|
+
.then((conversation) =>
|
|
138
|
+
webex.internal.conversation
|
|
139
|
+
.create({participants: [checkov]})
|
|
140
|
+
.then((conversation2) => {
|
|
141
|
+
assert.equal(conversation2.id, conversation.id);
|
|
142
|
+
// the first activity is "create"; get the "post"
|
|
143
|
+
const activity = conversation.activities.items.pop();
|
|
144
|
+
|
|
145
|
+
assert.equal(activity.verb, 'post');
|
|
146
|
+
assert.equal(activity.object.displayName, '**hi**');
|
|
147
|
+
assert.equal(activity.object.content, '<strong>hi</strong>');
|
|
148
|
+
})
|
|
149
|
+
));
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe('when {forceGrouped: true} is specified', () => {
|
|
153
|
+
it('creates a grouped conversation @canary', () =>
|
|
154
|
+
webex.internal.conversation
|
|
155
|
+
.create({participants: [mccoy]}, {forceGrouped: true})
|
|
156
|
+
.then((conversation) => {
|
|
157
|
+
assert.isConversation(conversation);
|
|
158
|
+
assert.isGroupConversation(conversation);
|
|
159
|
+
assert.isNewEncryptedConversation(conversation);
|
|
160
|
+
|
|
161
|
+
assert.lengthOf(conversation.participants.items, 2);
|
|
162
|
+
assert.lengthOf(conversation.activities.items, 1);
|
|
163
|
+
}));
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
describe('when there is an invalid user in the participants list', () => {
|
|
168
|
+
describe('with allowPartialCreation', () => {
|
|
169
|
+
it('creates a group conversation', () =>
|
|
170
|
+
webex.internal.conversation
|
|
171
|
+
.create({participants: [mccoy, 'invalidUser']}, {allowPartialCreation: true})
|
|
172
|
+
.then((conversation) => {
|
|
173
|
+
assert.isConversation(conversation);
|
|
174
|
+
assert.isGroupConversation(conversation);
|
|
175
|
+
assert.isNewEncryptedConversation(conversation);
|
|
176
|
+
|
|
177
|
+
assert.lengthOf(conversation.participants.items, 2);
|
|
178
|
+
assert.lengthOf(conversation.activities.items, 1);
|
|
179
|
+
}));
|
|
180
|
+
|
|
181
|
+
it('creates a group conversation with invalid uuid', () =>
|
|
182
|
+
testUsers
|
|
183
|
+
.remove([kirk])
|
|
184
|
+
.then(() =>
|
|
185
|
+
webex.internal.conversation.create(
|
|
186
|
+
{participants: [mccoy.id, kirk.id]},
|
|
187
|
+
{allowPartialCreation: true}
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
.then((conversation) => {
|
|
191
|
+
assert.isConversation(conversation);
|
|
192
|
+
assert.isGroupConversation(conversation);
|
|
193
|
+
assert.isNewEncryptedConversation(conversation);
|
|
194
|
+
|
|
195
|
+
assert.lengthOf(conversation.participants.items, 2);
|
|
196
|
+
assert.lengthOf(conversation.activities.items, 1);
|
|
197
|
+
}));
|
|
198
|
+
|
|
199
|
+
it('fails to create a 1:1 conversation', () =>
|
|
200
|
+
assert
|
|
201
|
+
.isRejected(
|
|
202
|
+
webex.internal.conversation.create(
|
|
203
|
+
{participants: ['invalidUser']},
|
|
204
|
+
{allowPartialCreation: true}
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
.then((reason) => assert.instanceOf(reason, InvalidUserCreation)));
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
describe('without allowPartialCreation', () => {
|
|
211
|
+
it('fails to create a group conversation without allowPartialCreation param', () =>
|
|
212
|
+
assert.isRejected(
|
|
213
|
+
webex.internal.conversation.create({participants: [mccoy, 'invalidUser']})
|
|
214
|
+
));
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe('when {compact: ?} is not specified', () => {
|
|
219
|
+
it('creates a compact conversation', () =>
|
|
220
|
+
webex.internal.conversation
|
|
221
|
+
.create({participants})
|
|
222
|
+
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 5}))
|
|
223
|
+
.then((c) => assert.lengthOf(c.activities.items, 1)));
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('creates a conversation with a name', () =>
|
|
227
|
+
webex.internal.conversation
|
|
228
|
+
.create({displayName: 'displayName', participants})
|
|
229
|
+
.then((c) => webex.internal.conversation.get(c))
|
|
230
|
+
.then((c) => assert.equal(c.displayName, 'displayName')));
|
|
231
|
+
|
|
232
|
+
it('creates a conversation with a comment', () =>
|
|
233
|
+
webex.internal.conversation
|
|
234
|
+
.create({comment: 'comment', participants})
|
|
235
|
+
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 2}))
|
|
236
|
+
.then((c) => assert.equal(c.activities.items[1].object.displayName, 'comment')));
|
|
237
|
+
|
|
238
|
+
it('creates a conversation with a tag', () =>
|
|
239
|
+
webex.internal.conversation
|
|
240
|
+
.create({tags: ['WELCOME'], participants})
|
|
241
|
+
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 1}))
|
|
242
|
+
.then((c) => assert.equal(c.tags[0], 'WELCOME')));
|
|
243
|
+
|
|
244
|
+
it('creates a favorite conversation', () =>
|
|
245
|
+
webex.internal.conversation
|
|
246
|
+
.create({favorite: true, participants})
|
|
247
|
+
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 1}))
|
|
248
|
+
.then((c) => assert.equal(c.tags[0], 'FAVORITE')));
|
|
249
|
+
|
|
250
|
+
it('creates a conversation with a comment with html', () =>
|
|
251
|
+
webex.internal.conversation
|
|
252
|
+
.create({comment: '**comment**', html: '<strong>comment</strong>', participants})
|
|
253
|
+
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 2}))
|
|
254
|
+
.then((c) => {
|
|
255
|
+
assert.equal(c.activities.items[1].object.displayName, '**comment**');
|
|
256
|
+
assert.equal(c.activities.items[1].object.content, '<strong>comment</strong>');
|
|
257
|
+
}));
|
|
258
|
+
|
|
259
|
+
it('creates a conversation with a share', () =>
|
|
260
|
+
webex.internal.conversation
|
|
261
|
+
.create({participants, files: [sampleTextOne]})
|
|
262
|
+
.then((c) => webex.internal.conversation.get(c, {activitiesLimit: 10}))
|
|
263
|
+
.then((c) => {
|
|
264
|
+
assert.equal(last(c.activities.items).verb, 'share');
|
|
265
|
+
|
|
266
|
+
return webex.internal.conversation.download(
|
|
267
|
+
last(c.activities.items).object.files.items[0]
|
|
268
|
+
);
|
|
269
|
+
})
|
|
270
|
+
.then((file) => fh.isMatchingFile(file, sampleTextOne)));
|
|
271
|
+
|
|
272
|
+
it('ensures the current user is in the participants list', () =>
|
|
273
|
+
webex.internal.conversation
|
|
274
|
+
.create({comment: 'comment', participants: [mccoy, checkov]})
|
|
275
|
+
.then((c) => webex.internal.conversation.get(c, {includeParticipants: true}))
|
|
276
|
+
.then((c) => assert.include(map(c.participants.items, 'id'), spock.id)));
|
|
277
|
+
|
|
278
|
+
it('does not allow me to create a conversation with zero participants', () =>
|
|
279
|
+
assert.isRejected(
|
|
280
|
+
webex.internal.conversation.create({participants: []}, /`params.participants` is required/)
|
|
281
|
+
));
|
|
282
|
+
|
|
283
|
+
it('does not allow me to create a classified space when feature toggle is disabled for the org', () =>
|
|
284
|
+
webex.internal.conversation
|
|
285
|
+
.create({participants: [mccoy, checkov], classificationId: 'abcde-12345-Some-UUID'})
|
|
286
|
+
.catch((err) =>
|
|
287
|
+
assert.match(err.toString(), /Org not entitled for space classifications/)
|
|
288
|
+
));
|
|
289
|
+
});
|
|
290
|
+
});
|