From ef54890d5445d26cbee319c797416f0a1c1589e1 Mon Sep 17 00:00:00 2001 From: Andrew Bulat Date: Mon, 21 Oct 2024 15:50:28 +0100 Subject: [PATCH] Preparation for LiveObjects tests for applying incoming operations - LiveObjectsHelper refactoring - timeserials format fix in existing LiveObjects tests (add seriesId part) --- test/common/modules/live_objects_helper.js | 92 ++++++++++++++-------- test/realtime/live_objects.test.js | 16 ++-- 2 files changed, 71 insertions(+), 37 deletions(-) diff --git a/test/common/modules/live_objects_helper.js b/test/common/modules/live_objects_helper.js index 2f6ffc384..b2793804e 100644 --- a/test/common/modules/live_objects_helper.js +++ b/test/common/modules/live_objects_helper.js @@ -17,6 +17,10 @@ define(['shared_helper'], function (Helper) { } class LiveObjectsHelper { + constructor(helper) { + this._rest = helper.AblyRest({ useBinaryProtocol: false }); + } + /** * Creates next LiveObjects state tree on a provided channel name: * @@ -27,39 +31,37 @@ define(['shared_helper'], function (Helper) { * root "initialValueCounter" -> Counter#2 count=10 * root "referencedCounter" -> Counter#3 count=20 */ - async initForChannel(helper, channelName) { - const rest = helper.AblyRest({ useBinaryProtocol: false }); - - const emptyCounter = await this._createAndSetOnMap(rest, channelName, { + async initForChannel(channelName) { + const emptyCounter = await this.createAndSetOnMap(channelName, { mapObjectId: 'root', key: 'emptyCounter', - createOp: this._counterCreateOp(), + createOp: this.counterCreateOp(), }); - const initialValueCounter = await this._createAndSetOnMap(rest, channelName, { + const initialValueCounter = await this.createAndSetOnMap(channelName, { mapObjectId: 'root', key: 'initialValueCounter', - createOp: this._counterCreateOp({ count: 10 }), + createOp: this.counterCreateOp({ count: 10 }), }); - const referencedCounter = await this._createAndSetOnMap(rest, channelName, { + const referencedCounter = await this.createAndSetOnMap(channelName, { mapObjectId: 'root', key: 'referencedCounter', - createOp: this._counterCreateOp({ count: 20 }), + createOp: this.counterCreateOp({ count: 20 }), }); - const emptyMap = await this._createAndSetOnMap(rest, channelName, { + const emptyMap = await this.createAndSetOnMap(channelName, { mapObjectId: 'root', key: 'emptyMap', - createOp: this._mapCreateOp(), + createOp: this.mapCreateOp(), }); - const referencedMap = await this._createAndSetOnMap(rest, channelName, { + const referencedMap = await this.createAndSetOnMap(channelName, { mapObjectId: 'root', key: 'referencedMap', - createOp: this._mapCreateOp({ entries: { counterKey: { data: { objectId: referencedCounter.objectId } } } }), + createOp: this.mapCreateOp({ entries: { counterKey: { data: { objectId: referencedCounter.objectId } } } }), }); - const valuesMap = await this._createAndSetOnMap(rest, channelName, { + const valuesMap = await this.createAndSetOnMap(channelName, { mapObjectId: 'root', key: 'valuesMap', - createOp: this._mapCreateOp({ + createOp: this.mapCreateOp({ entries: { stringKey: { data: { value: 'stringValue' } }, emptyStringKey: { data: { value: '' } }, @@ -77,20 +79,19 @@ define(['shared_helper'], function (Helper) { }); } - async _createAndSetOnMap(rest, channelName, opts) { + async createAndSetOnMap(channelName, opts) { const { mapObjectId, key, createOp } = opts; - const createResult = await this._stateRequest(rest, channelName, createOp); - await this._stateRequest( - rest, + const createResult = await this.stateRequest(channelName, createOp); + await this.stateRequest( channelName, - this._mapSetOp({ objectId: mapObjectId, key, data: { objectId: createResult.objectId } }), + this.mapSetOp({ objectId: mapObjectId, key, data: { objectId: createResult.objectId } }), ); return createResult; } - _mapCreateOp(opts) { + mapCreateOp(opts) { const { objectId, entries } = opts ?? {}; const op = { operation: { @@ -107,26 +108,38 @@ define(['shared_helper'], function (Helper) { return op; } - _mapSetOp(opts) { + mapSetOp(opts) { const { objectId, key, data } = opts ?? {}; const op = { operation: { action: ACTIONS.MAP_SET, objectId, + mapOp: { + key, + data, + }, }, }; - if (key && data) { - op.operation.mapOp = { - key, - data, - }; - } + return op; + } + + mapRemoveOp(opts) { + const { objectId, key } = opts ?? {}; + const op = { + operation: { + action: ACTIONS.MAP_REMOVE, + objectId, + mapOp: { + key, + }, + }, + }; return op; } - _counterCreateOp(opts) { + counterCreateOp(opts) { const { objectId, count } = opts ?? {}; const op = { operation: { @@ -143,7 +156,22 @@ define(['shared_helper'], function (Helper) { return op; } - async _stateRequest(rest, channelName, opBody) { + counterIncOp(opts) { + const { objectId, amount } = opts ?? {}; + const op = { + operation: { + action: ACTIONS.COUNTER_INC, + objectId, + counterOp: { + amount, + }, + }, + }; + + return op; + } + + async stateRequest(channelName, opBody) { if (Array.isArray(opBody)) { throw new Error(`Only single object state requests are supported`); } @@ -151,7 +179,7 @@ define(['shared_helper'], function (Helper) { const method = 'post'; const path = `/channels/${channelName}/state`; - const response = await rest.request(method, path, 3, null, opBody, null); + const response = await this._rest.request(method, path, 3, null, opBody, null); if (response.success) { // only one operation in request, so need only first item. @@ -167,5 +195,5 @@ define(['shared_helper'], function (Helper) { } } - return (module.exports = new LiveObjectsHelper()); + return (module.exports = LiveObjectsHelper); }); diff --git a/test/realtime/live_objects.test.js b/test/realtime/live_objects.test.js index e3c0d078e..ae2515738 100644 --- a/test/realtime/live_objects.test.js +++ b/test/realtime/live_objects.test.js @@ -36,7 +36,8 @@ define(['ably', 'shared_helper', 'chai', 'live_objects', 'live_objects_helper'], return; } - LiveObjectsHelper.initForChannel(helper, liveObjectsFixturesChannel) + new LiveObjectsHelper(helper) + .initForChannel(liveObjectsFixturesChannel) .then(done) .catch((err) => done(err)); }); @@ -77,7 +78,7 @@ define(['ably', 'shared_helper', 'chai', 'live_objects', 'live_objects_helper'], { object: { objectId: 'root', - regionalTimeserial: '@0-0', + regionalTimeserial: 'a@0-0', map: {}, }, }, @@ -220,7 +221,7 @@ define(['ably', 'shared_helper', 'chai', 'live_objects', 'live_objects_helper'], // wait for initial STATE_SYNC sequence to complete await liveObjects.getRoot(); - // inject STATE_SYNC message to emulate start of new sequence + // inject STATE_SYNC message to emulate start of a new sequence helper.recordPrivateApi('call.channel.processMessage'); helper.recordPrivateApi('call.makeProtocolMessageFromDeserialized'); await channel.processMessage( @@ -259,11 +260,11 @@ define(['ably', 'shared_helper', 'chai', 'live_objects', 'live_objects_helper'], { object: { objectId: 'root', - regionalTimeserial: '@0-0', + regionalTimeserial: 'a@0-0', map: { entries: { key: { - timeserial: '@0-0', + timeserial: 'a@0-0', data: { value: 1, }, @@ -285,6 +286,7 @@ define(['ably', 'shared_helper', 'chai', 'live_objects', 'live_objects_helper'], }, client); }); + /** @nospec */ it('builds state object tree from STATE_SYNC sequence on channel attachment', async function () { const helper = this.test.helper; const client = RealtimeWithLiveObjects(helper); @@ -338,6 +340,7 @@ define(['ably', 'shared_helper', 'chai', 'live_objects', 'live_objects_helper'], }, client); }); + /** @nospec */ it('LiveCounter is initialized with initial value from STATE_SYNC sequence', async function () { const helper = this.test.helper; const client = RealtimeWithLiveObjects(helper); @@ -362,6 +365,7 @@ define(['ably', 'shared_helper', 'chai', 'live_objects', 'live_objects_helper'], }, client); }); + /** @nospec */ it('LiveMap is initialized with initial value from STATE_SYNC sequence', async function () { const helper = this.test.helper; const client = RealtimeWithLiveObjects(helper); @@ -408,6 +412,7 @@ define(['ably', 'shared_helper', 'chai', 'live_objects', 'live_objects_helper'], }, client); }); + /** @nospec */ it('LiveMaps can reference the same object in their keys', async function () { const helper = this.test.helper; const client = RealtimeWithLiveObjects(helper); @@ -447,6 +452,7 @@ define(['ably', 'shared_helper', 'chai', 'live_objects', 'live_objects_helper'], }); }); + /** @nospec */ it('can attach to channel with LiveObjects state modes', async function () { const helper = this.test.helper; const client = helper.AblyRealtime();