Skip to content

Commit

Permalink
Preparation for LiveObjects tests for applying incoming operations
Browse files Browse the repository at this point in the history
- LiveObjectsHelper refactoring
- timeserials format fix in existing LiveObjects tests (add seriesId part)
  • Loading branch information
VeskeR committed Oct 25, 2024
1 parent 0b646e2 commit ef54890
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 37 deletions.
92 changes: 60 additions & 32 deletions test/common/modules/live_objects_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -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:
*
Expand All @@ -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: '' } },
Expand All @@ -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: {
Expand All @@ -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: {
Expand All @@ -143,15 +156,30 @@ 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`);
}

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.
Expand All @@ -167,5 +195,5 @@ define(['shared_helper'], function (Helper) {
}
}

return (module.exports = new LiveObjectsHelper());
return (module.exports = LiveObjectsHelper);
});
16 changes: 11 additions & 5 deletions test/realtime/live_objects.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
});
Expand Down Expand Up @@ -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: {},
},
},
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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,
},
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit ef54890

Please sign in to comment.