polfan-server-js-client 0.3.3 → 0.4.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/.gitmodules +3 -3
- package/.idea/shelf/Uncommitted_changes_before_Checkout_at_05_08_2026_17_28_[Changes]/shelved.patch +447 -0
- package/.idea/shelf/Uncommitted_changes_before_Checkout_at_05_08_2026_17_28_[Changes]1/shelved.patch +0 -0
- package/.idea/shelf/Uncommitted_changes_before_Checkout_at_05_08_2026_17_28__Changes_.xml +4 -0
- package/.idea/workspace.xml +61 -52
- package/CODE_OF_CONDUCT.md +76 -76
- package/README.md +44 -44
- package/babel.config.js +5 -5
- package/build/index.cjs.js +398 -427
- package/build/index.cjs.js.map +1 -1
- package/build/index.umd.js +1 -1
- package/build/index.umd.js.map +1 -1
- package/build/types/index.d.ts +2 -1
- package/build/types/state-tracker/RoomMessagesHistory.d.ts +4 -15
- package/build/types/state-tracker/TopicHistoryWindow.d.ts +0 -48
- package/build/types/types/src/index.d.ts +11 -3
- package/build/types/types/src/schemes/Message.d.ts +5 -1
- package/build/types/types/src/schemes/MessagePoll.d.ts +10 -0
- package/build/types/types/src/schemes/Reaction.d.ts +13 -0
- package/build/types/types/src/schemes/SessionData.d.ts +6 -0
- package/build/types/types/src/schemes/User.d.ts +15 -0
- package/build/types/types/src/schemes/UserData.d.ts +5 -0
- package/build/types/types/src/schemes/commands/CreateMessage.d.ts +3 -0
- package/build/types/types/src/schemes/commands/GetMessages.d.ts +5 -0
- package/build/types/types/src/schemes/commands/GetReactionDetails.d.ts +8 -0
- package/build/types/types/src/schemes/commands/React.d.ts +6 -0
- package/build/types/types/src/schemes/commands/SetSessionData.d.ts +9 -1
- package/build/types/types/src/schemes/commands/SetUserData.d.ts +1 -0
- package/build/types/types/src/schemes/commands/Unreact.d.ts +6 -0
- package/build/types/types/src/schemes/events/Messages.d.ts +3 -0
- package/build/types/types/src/schemes/events/Reacted.d.ts +9 -0
- package/build/types/types/src/schemes/events/ReactionDetails.d.ts +11 -0
- package/build/types/types/src/schemes/events/ReactionUpdated.d.ts +8 -0
- package/jest.config.ts +199 -199
- package/package.json +1 -1
- package/scripts/getPackageJson.js +24 -24
- package/src/FilesClient.ts +42 -42
- package/src/index.ts +2 -0
- package/src/state-tracker/ChatStateTracker.ts +71 -71
- package/src/state-tracker/RoomMessagesHistory.ts +9 -27
- package/src/state-tracker/TopicHistoryWindow.ts +1 -133
- package/src/state-tracker/UsersManager.ts +1 -1
- package/src/state-tracker/functions.ts +28 -28
- package/src/types/src/index.ts +24 -2
- package/src/types/src/schemes/Message.ts +5 -1
- package/src/types/src/schemes/MessagePoll.ts +12 -0
- package/src/types/src/schemes/Reaction.ts +16 -0
- package/src/types/src/schemes/SessionData.ts +8 -1
- package/src/types/src/schemes/User.ts +17 -1
- package/src/types/src/schemes/UserData.ts +5 -0
- package/src/types/src/schemes/commands/CreateMessage.ts +3 -0
- package/src/types/src/schemes/commands/GetMessages.ts +5 -0
- package/src/types/src/schemes/commands/GetReactionDetails.ts +9 -0
- package/src/types/src/schemes/commands/React.ts +7 -0
- package/src/types/src/schemes/commands/SetSessionData.ts +11 -2
- package/src/types/src/schemes/commands/SetUserData.ts +1 -0
- package/src/types/src/schemes/commands/Unreact.ts +7 -0
- package/src/types/src/schemes/events/Messages.ts +3 -0
- package/src/types/src/schemes/events/Reacted.ts +10 -0
- package/src/types/src/schemes/events/ReactionDetails.ts +12 -0
- package/src/types/src/schemes/events/ReactionUpdated.ts +9 -0
- package/tests/async-utils.test.ts +29 -29
- package/tests/history-window.test.ts +0 -131
- package/tests/space-roles.test.ts +42 -42
- package/tests/state-reconnect.test.ts +0 -260
- package/.idea/shelf/Uncommitted_changes_before_Checkout_at_26_07_2026_21_26_[Changes]/shelved.patch +0 -174
- package/.idea/shelf/Uncommitted_changes_before_Checkout_at_26_07_2026_21_26__Changes_.xml +0 -4
- package/.idea/shelf/Uncommitted_changes_before_rebase_[Changes]/shelved.patch +0 -18
- package/.idea/shelf/Uncommitted_changes_before_rebase__Changes_.xml +0 -4
|
@@ -2,4 +2,9 @@ export type PrivateMessagePolicy = 'None' | 'Mutual' | 'All';
|
|
|
2
2
|
|
|
3
3
|
export interface UserData {
|
|
4
4
|
privateMessagePolicy: PrivateMessagePolicy;
|
|
5
|
+
/**
|
|
6
|
+
* Whether others may see that the user is reachable on a push-registered
|
|
7
|
+
* device while disconnected. When false the user simply reads as offline.
|
|
8
|
+
*/
|
|
9
|
+
showAsyncPresence: boolean;
|
|
5
10
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {ChatLocation} from "../ChatLocation";
|
|
2
|
+
import {MessagePoll} from "../MessagePoll";
|
|
2
3
|
|
|
3
4
|
export interface CreateMessage {
|
|
4
5
|
location: ChatLocation;
|
|
@@ -6,4 +7,6 @@ export interface CreateMessage {
|
|
|
6
7
|
attachments?: string[];
|
|
7
8
|
customNick?: string;
|
|
8
9
|
customColor?: string;
|
|
10
|
+
/** Turns the message into a poll; its content becomes the question. */
|
|
11
|
+
poll?: MessagePoll;
|
|
9
12
|
}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
import {SessionPlatform} from "../SessionData";
|
|
2
|
+
|
|
1
3
|
export interface SessionPush {
|
|
2
4
|
token?: string;
|
|
3
|
-
platform?: 'ios' | 'android' | 'web';
|
|
4
5
|
active?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated The platform describes the session, not its push registration.
|
|
8
|
+
* Use {@link SetSessionData.platform} (or the `platform` connection query
|
|
9
|
+
* parameter). Still accepted by the server, but the top-level field wins.
|
|
10
|
+
*/
|
|
11
|
+
platform?: SessionPlatform;
|
|
5
12
|
}
|
|
6
13
|
|
|
7
14
|
export interface SetSessionData {
|
|
8
15
|
clientFocused?: boolean;
|
|
9
16
|
push?: SessionPush;
|
|
10
|
-
|
|
17
|
+
/** Client platform of this session; null leaves the stored value unchanged. */
|
|
18
|
+
platform?: SessionPlatform;
|
|
19
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import {ChatLocation} from "../ChatLocation";
|
|
2
2
|
import {Message} from "../Message";
|
|
3
|
+
import {UserReaction} from "../Reaction";
|
|
3
4
|
|
|
4
5
|
export interface Messages {
|
|
5
6
|
location: ChatLocation;
|
|
6
7
|
messages: Message[];
|
|
8
|
+
/** Message id => reactions of the asking user; present only when requested. */
|
|
9
|
+
myReactions?: Record<string, UserReaction[]>;
|
|
7
10
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {ToggledReaction} from "../Reaction";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sent to every client of the voting user, so all of their devices know what they
|
|
5
|
+
* voted for without refetching the message history.
|
|
6
|
+
*/
|
|
7
|
+
export interface Reacted {
|
|
8
|
+
messageId: string;
|
|
9
|
+
reaction: ToggledReaction;
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {ReactionType} from "../Reaction";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Who reacted, oldest vote first. Only the ids travel - the nicks are already
|
|
5
|
+
* known from the room members collection.
|
|
6
|
+
*/
|
|
7
|
+
export interface ReactionDetails {
|
|
8
|
+
messageId: string;
|
|
9
|
+
type: ReactionType;
|
|
10
|
+
value: string;
|
|
11
|
+
userIds: string[];
|
|
12
|
+
}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import {PromiseRegistry} from "../src/state-tracker/AsyncUtils";
|
|
2
|
-
|
|
3
|
-
test('promise registry - limit the calling of async process', async () => {
|
|
4
|
-
const pr = new PromiseRegistry();
|
|
5
|
-
let generationCount = 0;
|
|
6
|
-
|
|
7
|
-
async function generateResult() {
|
|
8
|
-
return ++generationCount;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async function getResult() {
|
|
12
|
-
const resultKey = 'test';
|
|
13
|
-
|
|
14
|
-
if (pr.notExist('test')) {
|
|
15
|
-
pr.registerByFunction(generateResult, resultKey);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
await pr.get(resultKey);
|
|
19
|
-
return generationCount;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const call1 = await getResult();
|
|
23
|
-
expect(call1).toBe(1);
|
|
24
|
-
const call2 = await getResult();
|
|
25
|
-
expect(call2).toBe(1);
|
|
26
|
-
const call3 = await getResult();
|
|
27
|
-
expect(call3).toBe(1);
|
|
28
|
-
|
|
29
|
-
expect(generationCount).toBe(1);
|
|
1
|
+
import {PromiseRegistry} from "../src/state-tracker/AsyncUtils";
|
|
2
|
+
|
|
3
|
+
test('promise registry - limit the calling of async process', async () => {
|
|
4
|
+
const pr = new PromiseRegistry();
|
|
5
|
+
let generationCount = 0;
|
|
6
|
+
|
|
7
|
+
async function generateResult() {
|
|
8
|
+
return ++generationCount;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async function getResult() {
|
|
12
|
+
const resultKey = 'test';
|
|
13
|
+
|
|
14
|
+
if (pr.notExist('test')) {
|
|
15
|
+
pr.registerByFunction(generateResult, resultKey);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
await pr.get(resultKey);
|
|
19
|
+
return generationCount;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const call1 = await getResult();
|
|
23
|
+
expect(call1).toBe(1);
|
|
24
|
+
const call2 = await getResult();
|
|
25
|
+
expect(call2).toBe(1);
|
|
26
|
+
const call3 = await getResult();
|
|
27
|
+
expect(call3).toBe(1);
|
|
28
|
+
|
|
29
|
+
expect(generationCount).toBe(1);
|
|
30
30
|
});
|
|
@@ -209,137 +209,6 @@ test('history window - reset to latest', async () => {
|
|
|
209
209
|
[7,8,9].forEach(id => expect(window.items.map(item => item.id)).toContain(id));
|
|
210
210
|
});
|
|
211
211
|
|
|
212
|
-
test('history window - resync to latest merges the new page into loaded items', async () => {
|
|
213
|
-
const window = new TestableHistoryWindow();
|
|
214
|
-
window.limit = 10;
|
|
215
|
-
window.fetchLimit = 3;
|
|
216
|
-
|
|
217
|
-
await window.resetToLatest(); // [7,8,9]
|
|
218
|
-
await window.fetchPrevious(); // [4,5,6,7,8,9]
|
|
219
|
-
|
|
220
|
-
await window.resyncToLatest(); // fetched [7,8,9] overlaps -> nothing is lost
|
|
221
|
-
|
|
222
|
-
expect(window.state).toEqual(WindowState.LATEST);
|
|
223
|
-
expect(window.items.map(item => item.id)).toEqual([4, 5, 6, 7, 8, 9]);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
test('history window - resync to latest trims the merged items to the limit', async () => {
|
|
227
|
-
const window = new TestableHistoryWindow();
|
|
228
|
-
window.limit = 4;
|
|
229
|
-
window.fetchLimit = 3;
|
|
230
|
-
|
|
231
|
-
await window.resetToLatest(); // [7,8,9]
|
|
232
|
-
await window.fetchPrevious(); // [4,5,6,7] (trimmed to the limit)
|
|
233
|
-
|
|
234
|
-
// [4,5,6,7] merged with the page [7,8,9] -> [4,5,6,7,8,9], trimmed again.
|
|
235
|
-
await window.resyncToLatest();
|
|
236
|
-
|
|
237
|
-
expect(window.state).toEqual(WindowState.LATEST);
|
|
238
|
-
expect(window.items.map(item => item.id)).toEqual([6, 7, 8, 9]);
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
test('history window - resync to latest marks the gap instead of dropping items', async () => {
|
|
242
|
-
const window = new TestableHistoryWindow();
|
|
243
|
-
window.limit = 10;
|
|
244
|
-
window.fetchLimit = 3;
|
|
245
|
-
|
|
246
|
-
await window.jumpTo('1'); // [0,1,2]
|
|
247
|
-
|
|
248
|
-
expect(window.gaps).toEqual([]);
|
|
249
|
-
|
|
250
|
-
// A full page ([7,8,9]) that does not reach the newest loaded item (2):
|
|
251
|
-
// items 3..6 were never fetched, so the seam in front of 7 is marked.
|
|
252
|
-
await window.resyncToLatest();
|
|
253
|
-
|
|
254
|
-
expect(window.state).toEqual(WindowState.LATEST);
|
|
255
|
-
expect(window.items.map(item => item.id)).toEqual([0, 1, 2, 7, 8, 9]);
|
|
256
|
-
expect(window.gaps).toEqual([7]);
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
test('history window - gap marker disappears with the item it points at', async () => {
|
|
260
|
-
const window = new TestableHistoryWindow();
|
|
261
|
-
window.limit = 10;
|
|
262
|
-
window.fetchLimit = 3;
|
|
263
|
-
|
|
264
|
-
await window.jumpTo('1'); // [0,1,2]
|
|
265
|
-
await window.resyncToLatest(); // [0,1,2] | [7,8,9]
|
|
266
|
-
|
|
267
|
-
expect(window.gaps).toEqual([7]);
|
|
268
|
-
|
|
269
|
-
window.delete(7);
|
|
270
|
-
|
|
271
|
-
expect(window.gaps).toEqual([]);
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
test('history window - gap marker is closed by fetching what is before it', async () => {
|
|
275
|
-
const window = new TestableHistoryWindow();
|
|
276
|
-
window.limit = 10;
|
|
277
|
-
window.fetchLimit = 3;
|
|
278
|
-
|
|
279
|
-
await window.jumpTo('1'); // [0,1,2]
|
|
280
|
-
await window.resyncToLatest(); // [0,1,2] | [7,8,9]
|
|
281
|
-
window.delete(0, 1, 2); // the items above the gap are gone, 7 is the top one
|
|
282
|
-
|
|
283
|
-
expect(window.gaps).toEqual([7]);
|
|
284
|
-
|
|
285
|
-
// Whatever comes back was fetched as the direct predecessor of 7, so the
|
|
286
|
-
// history is continuous again.
|
|
287
|
-
await window.fetchPrevious(); // [4,5,6,7,8,9]
|
|
288
|
-
|
|
289
|
-
expect(window.items.map(item => item.id)).toEqual([4, 5, 6, 7, 8, 9]);
|
|
290
|
-
expect(window.gaps).toEqual([]);
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
test('history window - gap markers are cleared when the whole window is replaced', async () => {
|
|
294
|
-
const window = new TestableHistoryWindow();
|
|
295
|
-
window.limit = 10;
|
|
296
|
-
window.fetchLimit = 3;
|
|
297
|
-
|
|
298
|
-
await window.jumpTo('1'); // [0,1,2]
|
|
299
|
-
await window.resyncToLatest(); // [0,1,2] | [7,8,9]
|
|
300
|
-
|
|
301
|
-
expect(window.gaps).toEqual([7]);
|
|
302
|
-
|
|
303
|
-
await window.resetToLatest(true); // [7,8,9] - a continuous window again
|
|
304
|
-
|
|
305
|
-
expect(window.items.map(item => item.id)).toEqual([7, 8, 9]);
|
|
306
|
-
expect(window.gaps).toEqual([]);
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
test('history window - gap marker is forgotten when trimmed out of the window', async () => {
|
|
310
|
-
const window = new TestableHistoryWindow();
|
|
311
|
-
window.limit = 10;
|
|
312
|
-
window.fetchLimit = 3;
|
|
313
|
-
|
|
314
|
-
await window.jumpTo('1'); // [0,1,2]
|
|
315
|
-
await window.resyncToLatest(); // [0,1,2] | [7,8,9]
|
|
316
|
-
|
|
317
|
-
expect(window.gaps).toEqual([7]);
|
|
318
|
-
|
|
319
|
-
// The window shrinks and the trimming pushes item 7 (and everything above
|
|
320
|
-
// it) out, so the marker has nothing left to point at.
|
|
321
|
-
window.limit = 2;
|
|
322
|
-
await window.resyncToLatest();
|
|
323
|
-
|
|
324
|
-
expect(window.items.map(item => item.id)).toEqual([8, 9]);
|
|
325
|
-
expect(window.gaps).toEqual([]);
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
test('history window - resync to latest keeps loaded items when the page is not full', async () => {
|
|
329
|
-
const window = new TestableHistoryWindow();
|
|
330
|
-
window.limit = 10;
|
|
331
|
-
window.fetchLimit = 5; // The fetch returns 3 items only - all there is.
|
|
332
|
-
|
|
333
|
-
await window.jumpTo('1'); // [0,1,2,3]
|
|
334
|
-
|
|
335
|
-
// Nothing is missing in between: the page is everything the remote side has,
|
|
336
|
-
// so the loaded items are kept even though the page does not reach them.
|
|
337
|
-
await window.resyncToLatest();
|
|
338
|
-
|
|
339
|
-
expect(window.state).toEqual(WindowState.LATEST);
|
|
340
|
-
expect(window.items.map(item => item.id)).toEqual([0, 1, 2, 3, 7, 8, 9]);
|
|
341
|
-
});
|
|
342
|
-
|
|
343
212
|
test('history window - jump to message', async () => {
|
|
344
213
|
const window = new TestableHistoryWindow();
|
|
345
214
|
window.limit = 5;
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
import {IndexedObjectCollection} from "../src";
|
|
2
|
-
import {Role} from "pserv-ts-types";
|
|
3
|
-
import {reorderRolesOnPriorityUpdate} from "../src/state-tracker/functions";
|
|
4
|
-
|
|
5
|
-
const createCollection = () => new IndexedObjectCollection<Role>(
|
|
6
|
-
role => role.id,
|
|
7
|
-
[
|
|
8
|
-
{id: 'id1', name: 'everyone', priority: 0, color: '#ff0000'},
|
|
9
|
-
{id: 'id2', name: 'roleA', priority: 1, color: '#ff0000'},
|
|
10
|
-
{id: 'id3', name: 'roleB', priority: 2, color: '#ff0000'},
|
|
11
|
-
{id: 'id4', name: 'roleC', priority: 3, color: '#ff0000'},
|
|
12
|
-
{id: 'id5', name: 'roleD', priority: 4, color: '#ff0000'},
|
|
13
|
-
],
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
test('roles reorder - increase', () => {
|
|
17
|
-
const collection = createCollection();
|
|
18
|
-
const oldRole = collection.get('id2');
|
|
19
|
-
const newRole: Role = {...oldRole, priority: 4};
|
|
20
|
-
const result = reorderRolesOnPriorityUpdate(collection.items, oldRole, newRole);
|
|
21
|
-
collection.set(newRole, ...result);
|
|
22
|
-
|
|
23
|
-
//expect(result.length).toBe(3);
|
|
24
|
-
expect(collection.get('id1').priority).toBe(0);
|
|
25
|
-
expect(collection.get('id2').priority).toBe(4);
|
|
26
|
-
expect(collection.get('id3').priority).toBe(1);
|
|
27
|
-
expect(collection.get('id4').priority).toBe(2);
|
|
28
|
-
expect(collection.get('id5').priority).toBe(3);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('roles reorder - decrease', () => {
|
|
32
|
-
const collection = createCollection();
|
|
33
|
-
const oldRole = collection.get('id5');
|
|
34
|
-
const newRole: Role = {...oldRole, priority: 0};
|
|
35
|
-
const result = reorderRolesOnPriorityUpdate(collection.items, oldRole, newRole);
|
|
36
|
-
collection.set(newRole, ...result);
|
|
37
|
-
|
|
38
|
-
expect(collection.get('id1').priority).toBe(1);
|
|
39
|
-
expect(collection.get('id2').priority).toBe(2);
|
|
40
|
-
expect(collection.get('id3').priority).toBe(3);
|
|
41
|
-
expect(collection.get('id4').priority).toBe(4);
|
|
42
|
-
expect(collection.get('id5').priority).toBe(0);
|
|
1
|
+
import {IndexedObjectCollection} from "../src";
|
|
2
|
+
import {Role} from "pserv-ts-types";
|
|
3
|
+
import {reorderRolesOnPriorityUpdate} from "../src/state-tracker/functions";
|
|
4
|
+
|
|
5
|
+
const createCollection = () => new IndexedObjectCollection<Role>(
|
|
6
|
+
role => role.id,
|
|
7
|
+
[
|
|
8
|
+
{id: 'id1', name: 'everyone', priority: 0, color: '#ff0000'},
|
|
9
|
+
{id: 'id2', name: 'roleA', priority: 1, color: '#ff0000'},
|
|
10
|
+
{id: 'id3', name: 'roleB', priority: 2, color: '#ff0000'},
|
|
11
|
+
{id: 'id4', name: 'roleC', priority: 3, color: '#ff0000'},
|
|
12
|
+
{id: 'id5', name: 'roleD', priority: 4, color: '#ff0000'},
|
|
13
|
+
],
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
test('roles reorder - increase', () => {
|
|
17
|
+
const collection = createCollection();
|
|
18
|
+
const oldRole = collection.get('id2');
|
|
19
|
+
const newRole: Role = {...oldRole, priority: 4};
|
|
20
|
+
const result = reorderRolesOnPriorityUpdate(collection.items, oldRole, newRole);
|
|
21
|
+
collection.set(newRole, ...result);
|
|
22
|
+
|
|
23
|
+
//expect(result.length).toBe(3);
|
|
24
|
+
expect(collection.get('id1').priority).toBe(0);
|
|
25
|
+
expect(collection.get('id2').priority).toBe(4);
|
|
26
|
+
expect(collection.get('id3').priority).toBe(1);
|
|
27
|
+
expect(collection.get('id4').priority).toBe(2);
|
|
28
|
+
expect(collection.get('id5').priority).toBe(3);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('roles reorder - decrease', () => {
|
|
32
|
+
const collection = createCollection();
|
|
33
|
+
const oldRole = collection.get('id5');
|
|
34
|
+
const newRole: Role = {...oldRole, priority: 0};
|
|
35
|
+
const result = reorderRolesOnPriorityUpdate(collection.items, oldRole, newRole);
|
|
36
|
+
collection.set(newRole, ...result);
|
|
37
|
+
|
|
38
|
+
expect(collection.get('id1').priority).toBe(1);
|
|
39
|
+
expect(collection.get('id2').priority).toBe(2);
|
|
40
|
+
expect(collection.get('id3').priority).toBe(3);
|
|
41
|
+
expect(collection.get('id4').priority).toBe(4);
|
|
42
|
+
expect(collection.get('id5').priority).toBe(0);
|
|
43
43
|
});
|