tests: Factor out USER_CHANGES/ACCEPT_COMMIT helpers

This will make it possible for other tests to reuse the code.
pull/5331/head
Richard Hansen 2021-12-19 16:47:45 -05:00
parent 674a0ccedc
commit 02d1b90d30
2 changed files with 90 additions and 36 deletions

View File

@ -1,6 +1,8 @@
'use strict';
const AttributePool = require('../../static/js/AttributePool');
const apiHandler = require('../../node/handler/APIHandler');
const assert = require('assert').strict;
const io = require('socket.io-client');
const log4js = require('log4js');
const process = require('process');
@ -185,6 +187,58 @@ exports.handshake = async (socket, padId) => {
return msg;
};
/**
* Convenience wrapper around `socket.send()` that waits for acknowledgement.
*/
exports.sendMessage = async (socket, message) => await new Promise((resolve, reject) => {
socket.send(message, (errInfo) => {
if (errInfo != null) {
const {name, message} = errInfo;
const err = new Error(message);
err.name = name;
reject(err);
return;
}
resolve();
});
});
/**
* Convenience function to send a USER_CHANGES message. Waits for acknowledgement.
*/
exports.sendUserChanges = async (socket, data) => await exports.sendMessage(socket, {
type: 'COLLABROOM',
component: 'pad',
data: {
type: 'USER_CHANGES',
apool: new AttributePool(),
...data,
},
});
/**
* Convenience function that waits for an ACCEPT_COMMIT message. Asserts that the new revision
* matches the expected revision.
*
* Note: To avoid a race condition, this should be called before the USER_CHANGES message is sent.
* For example:
*
* await Promise.all([
* common.waitForAcceptCommit(socket, rev + 1),
* common.sendUserChanges(socket, {baseRev: rev, changeset}),
* ]);
*/
exports.waitForAcceptCommit = async (socket, wantRev) => {
const msg = await exports.waitForSocketEvent(socket, 'message');
assert.deepEqual(msg, {
type: 'COLLABROOM',
data: {
type: 'ACCEPT_COMMIT',
newRev: wantRev,
},
});
};
const alphabet = 'abcdefghijklmnopqrstuvwxyz';
/**

View File

@ -36,27 +36,10 @@ describe(__filename, function () {
});
describe('USER_CHANGES', function () {
const sendUserChanges = (changeset, apool = new AttributePool()) => {
socket.json.send({
type: 'COLLABROOM',
component: 'pad',
data: {
type: 'USER_CHANGES',
baseRev: rev,
changeset,
apool: new AttributePool(),
},
});
};
const sendUserChanges =
async (changeset) => await common.sendUserChanges(socket, {baseRev: rev, changeset});
const assertAccepted = async (wantRev) => {
const msg = await common.waitForSocketEvent(socket, 'message');
assert.deepEqual(msg, {
type: 'COLLABROOM',
data: {
type: 'ACCEPT_COMMIT',
newRev: wantRev,
},
});
await common.waitForAcceptCommit(socket, wantRev);
rev = wantRev;
};
const assertRejected = async () => {
@ -65,38 +48,55 @@ describe(__filename, function () {
};
it('changes are applied', async function () {
sendUserChanges('Z:1>5+5$hello');
await assertAccepted(rev + 1);
await Promise.all([
assertAccepted(rev + 1),
sendUserChanges('Z:1>5+5$hello'),
]);
assert.equal(pad.text(), 'hello\n');
});
it('bad changeset is rejected', async function () {
sendUserChanges('this is not a valid changeset');
await assertRejected();
await Promise.all([
assertRejected(),
sendUserChanges('this is not a valid changeset'),
]);
});
it('retransmission is accepted, has no effect', async function () {
sendUserChanges('Z:1>5+5$hello');
await assertAccepted(rev + 1);
const cs = 'Z:1>5+5$hello';
await Promise.all([
assertAccepted(rev + 1),
sendUserChanges(cs),
]);
--rev;
sendUserChanges('Z:1>5+5$hello');
await assertAccepted(rev + 1);
await Promise.all([
assertAccepted(rev + 1),
sendUserChanges(cs),
]);
assert.equal(pad.text(), 'hello\n');
});
it('identity changeset is accepted, has no effect', async function () {
sendUserChanges('Z:1>5+5$hello');
await assertAccepted(rev + 1);
sendUserChanges('Z:6>0$');
await assertAccepted(rev);
await Promise.all([
assertAccepted(rev + 1),
sendUserChanges('Z:1>5+5$hello'),
]);
await Promise.all([
assertAccepted(rev),
sendUserChanges('Z:6>0$'),
]);
assert.equal(pad.text(), 'hello\n');
});
it('non-identity changeset with no net change is accepted, has no effect', async function () {
sendUserChanges('Z:1>5+5$hello');
await assertAccepted(rev + 1);
sendUserChanges('Z:6>0-5+5$hello');
await assertAccepted(rev);
await Promise.all([
assertAccepted(rev + 1),
sendUserChanges('Z:1>5+5$hello'),
]);
await Promise.all([
assertAccepted(rev),
sendUserChanges('Z:6>0-5+5$hello'),
]);
assert.equal(pad.text(), 'hello\n');
});
});