golos-lib-js
Version:
Golos-js the JavaScript library with API for GOLOS blockchain
753 lines (638 loc) • 29 kB
JavaScript
import { assert } from 'chai';
import cloneDeep from 'lodash/cloneDeep';
import { encode, encodeMsg, decode, decodeMsgs, newTextMsg, newImageMsgAsync, makeQuoteMsg,
DEFAULT_APP, DEFAULT_VERSION, MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT,
MAX_TEXT_QUOTE_LENGTH, MAX_IMAGE_QUOTE_LENGTH } from '../src/auth/messages';
import th from './test_helper';
import { correctImageURL } from './mock_image';
import { importNativeLib } from '../src/';
var sandbox = global.sandbox;
const alice = {
memo: '5JpqCdoBbBDu3dH5iAPR1bpMpP726LALzzJ2Gp4krUwHPQJ7FHA',
memo_pub: 'GLS7R6TH9DSKrvhryK9j6DV97ekNEKyT1QopHtxh8CZo2QVF5uo54',
};
const bob = {
memo: '5KD3SYGUafZjixCq18THjH9uTq6EvBq9uuXHevZSrPoMgki2mDL',
memo_pub: 'GLS67bFM2GtnEcrayTquHXdA8QdgRUgmGtUTQK24ez3uz4XLDShzc',
};
describe('golos.messages: encodeMsg()', function() {
beforeEach(async function() {
await importNativeLib();
});
it('input arguments', async function() {
await assert.isRejected(encodeMsg({}), 'msg is required');
await assert.isRejected(encodeMsg({ msg: 1 }), 'private_memo is required in private chats');
await assert.isRejected(encodeMsg({ msg: 1, private_memo: alice.memo }),
'to_public_memo is required in private chats');
await assert.isRejected(encodeMsg({ msg: 1, private_memo: 1, to_public_memo: alice.memo }))
})
it('normal case', async function() {
var msg = newTextMsg('Привет');
var res = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
assert.isString(res.nonce);
assert.isNotEmpty(res.nonce);
assert.isTrue(Number.isInteger(res.checksum));
assert.isString(res.encrypted_message);
assert.isNotEmpty(res.encrypted_message);
})
it('cyrillic, emoji, etc', async function() {
var veryLong = 'Очень';
for (let i = 0; i < 100; ++i) {
veryLong += ' длинный текст. Длинный текст.\nОчень';
}
for (let str of [
'Привет',
'как дела',
'Hi',
')))',
'',
' ',
'\t',
'\n',
'\r\n',
'Привет, это тебе: ' + String.fromCodePoint(0x1F354), // emoji
veryLong,
]) {
var msg = newTextMsg(str);
var enc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
msg.type = 'text';
var res = await decodeMsgs({ private_memo: bob.memo, msgs: [enc] })
assert.lengthOf(res, 1);
assert.deepStrictEqual(res[0].message, msg);
}
})
it('alice -> alice, bob', async function() {
var msg = newTextMsg('Привет');
var enc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
msg.type = 'text';
var res = await decodeMsgs({ private_memo: alice.memo,
msgs: [enc] });
assert.lengthOf(res, 1);
console.error(res[0].raw_message)
console.error(res[0].message)
assert.deepStrictEqual(res[0].message, msg);
var res = await decodeMsgs({ private_memo: bob.memo, msgs: [enc] })
assert.lengthOf(res, 1);
assert.deepStrictEqual(res[0].message, msg);
})
it('alice -> alice', async function() {
var msg = newTextMsg('Привет');
var enc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: alice.memo_pub, msg })
msg.type = 'text';
var res = await decodeMsgs({ private_memo: alice.memo, msgs: [enc] })
assert.lengthOf(res, 1);
assert.deepStrictEqual(res[0].message, msg);
var res = await decodeMsgs({ private_memo: bob.memo, msgs: [enc] })
assert.lengthOf(res, 1);
assert.isNull(res[0].message);
})
it('edit case', async function() {
var msg = newTextMsg('Привет');
var enc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
msg.type = 'text';
var res = await decodeMsgs({ private_memo: bob.memo, msgs: [enc] })
assert.lengthOf(res, 1);
assert.deepStrictEqual(res[0].message, msg);
var msg = newTextMsg('Приветик');
var enc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg, nonce: enc.nonce })
msg.type = 'text';
var res2 = await decodeMsgs({ private_memo: bob.memo, msgs: [enc] })
assert.lengthOf(res2, 1);
assert.deepStrictEqual(res2[0].message, msg);
assert.strictEqual(res2[0].nonce, res[0].nonce);
assert.strictEqual(res2[0].checksum, res[0].checksum);
})
it('normal + edit case, with legacy encode() and decode()', async function() {
var msg = newTextMsg('Привет')
var enc = encode(alice.memo, bob.memo_pub, msg)
msg.type = 'text'
assert.isString(enc.nonce)
assert.isNotEmpty(enc.nonce)
assert.isTrue(Number.isInteger(enc.checksum))
assert.isString(enc.encrypted_message)
assert.isNotEmpty(enc.encrypted_message)
// these are need for compatibility with decodeMsgs()
enc.from_memo_key = alice.memo_pub
enc.to_memo_key = bob.memo_pub
var res = await decodeMsgs({ private_memo: bob.memo, msgs: [enc] })
assert.lengthOf(res, 1)
assert.deepStrictEqual(res[0].message, msg)
var msg = newTextMsg('Приветик')
var enc = encode(alice.memo, bob.memo_pub, msg, enc.nonce)
msg.type = 'text'
var res2 = decode(bob.memo, alice.memo_pub, [enc])
assert.lengthOf(res2, 1)
assert.deepStrictEqual(res2[0].message, msg)
assert.strictEqual(res2[0].nonce, res[0].nonce)
assert.strictEqual(res2[0].checksum, res[0].checksum)
})
})
describe('golos.messages: decodeMsgs()', function() {
before(async function () {
var msg = newTextMsg('Привет');
var msgEnc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
msg.type = 'text'; // for comparison
var msg2 = await newImageMsgAsync(correctImageURL);
var msgEnc2 = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: msg2 })
this._msgs = [
msg,
msg2,
{},
{},
];
this._msgObjs = [
msgEnc,
msgEnc2,
await encodeMsg({ private_memo: alice.memo,
to_public_memo: alice.memo_pub, msg: {} }),
await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: {} }),
];
this._decoded = await decodeMsgs({ private_memo: bob.memo, msgs: this._msgObjs })
})
beforeEach(function() {
// encode/decode are slow, so we just cloning instead of recreating
this.msgs = cloneDeep(this._msgs);
this.msgObjs = cloneDeep(this._msgObjs);
this.decoded = cloneDeep(this._decoded);
})
it('input arguments', async function() {
await assert.isRejected(decodeMsgs(), 'argument should be an object with argument-field. See golos-lib-js documentation.');
await assert.isRejected(decodeMsgs({}), 'msgs is required')
await assert.isRejected(decodeMsgs({ msgs: [], private_memo: 'wrong key' }), 'Non-base58 character')
})
it('validation', async function() {
var normalText = this.msgs[0];
var normalTextEnc = this.msgObjs[0];
var normalImage = this.msgs[1];
var normalImageEnc = this.msgObjs[1];
// 100 messages are recommended limit for get_thread
var messages = [];
// non-decodable
{
let msg = await encodeMsg({ private_memo: alice.memo,
to_public_memo: alice.memo_pub, msg: normalText })
messages.push({
nonce: msg.nonce,
from_memo_key: msg.from_memo_key,
to_memo_key: msg.to_memo_key,
checksum: 1,
encrypted_message: 'not encrypted',
});
}
// non-JSON
{
sandbox.stub(JSON, 'stringify', (data) => {
return data; // as it is
});
messages.push(await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: 'не json' }));
JSON.stringify.restore();
}
// JSON, but not object
messages.push(await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: 'Привет' }))
// no body
messages.push(await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: {} }));
// no app, version
messages.push(await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: {body: 'Привет'} }));
// normal text msgs
for (let i = 0; i < 50 - 5; ++i) {
messages.push(normalTextEnc);
}
// normal image msgs
for (let i = 0; i < 50; ++i) {
messages.push(normalImageEnc);
}
var res = await decodeMsgs({ private_memo: bob.memo, msgs: messages })
assert.lengthOf(res, 100);
// non-decodable
assert.isNull(res[0].raw_message);
assert.isNull(res[0].message);
// non-JSON
assert.equal(res[1].raw_message, 'не json');
assert.isNull(res[1].message);
// JSON, but not object
assert.equal(res[2].raw_message, '"Привет"');
assert.isNull(res[2].message);
// no body
assert.equal(res[3].raw_message, '{}');
assert.isNull(res[3].message);
// no app, version
assert.equal(res[4].raw_message, '{"body":"Привет"}');
assert.isNull(res[4].message);
// normal msgs
normalText.type = 'text';
for (let i = 5; i < 50; ++i) {
assert.deepStrictEqual(res[i].message, normalText);
}
for (let i = 50; i < res.length; ++i) {
assert.deepStrictEqual(res[i].message, normalImage);
}
// With on_error
var on_error = sandbox.spy();
var res2 = await decodeMsgs({ private_memo: bob.memo, msgs: cloneDeep(messages),
on_error: (msg, idx, err) => {
on_error(msg, idx, err.message);
}
})
on_error = on_error.getCalls();
assert.lengthOf(on_error, 5);
// non decodable
assert.calledWith(on_error[0], messages[0], 0, 'Invalid key');
// not JSON
assert.calledWith(on_error[1], messages[1], 1);
// JSON, but not object
assert.calledWith(on_error[2], messages[2], 2);
// no body
assert.calledWith(on_error[3], messages[3], 3, 'message.body should be a string');
// no app, version
assert.calledWith(on_error[4], messages[4], 4, 'message.app should be a string, >= 1, <= 16');
assert.deepStrictEqual(res2, res);
// With raw_messages
var on_error_raw = sandbox.spy();
var res3 = await decodeMsgs({ private_memo: bob.memo, msgs: cloneDeep(messages),
on_error: (msg, idx, err) => {
on_error_raw(msg, idx, err.message)
}, raw_messages: true})
on_error_raw = on_error_raw.getCalls();
assert.lengthOf(on_error_raw, 1);
// non decodable
assert.calledWith(on_error[0], messages[0], 0, 'Invalid key')
assert.lengthOf(res3, res2.length);
assert.isNull(res3[0].raw_message);
assert.isNull(res3[0].message);
assert.equal(res3[1].raw_message, res[1].raw_message);
assert.isNull(res3[1].message);
assert.equal(res3[2].raw_message, res[2].raw_message);
assert.isNull(res3[2].message);
assert.equal(res3[3].raw_message, res[3].raw_message);
assert.isNull(res3[3].message);
assert.equal(res3[4].raw_message, res[4].raw_message);
assert.isNull(res3[4].message);
// and normal
for (let i = 5; i < 50; ++i) {
assert.equal(res3[i].raw_message, res[i].raw_message);
assert.isNull(res3[i].message);
}
for (let i = 50; i < res.length; ++i) {
assert.equal(res3[i].raw_message, res[i].raw_message);
assert.isNull(res3[i].message);
}
})
it('image validation', async function() {
var normalImage = this.msgs[1];
var normalImageEnc = this.msgObjs[1];
var messages = [];
// normal
messages.push(normalImageEnc);
var addMsg = async (breaker) => {
var msg = Object.assign({}, normalImage);
breaker(msg);
msg = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
messages.push(msg);
};
// no body
await addMsg(msg => delete msg.body);
// no app
await addMsg(msg => delete msg.app);
// previewWidth, previewHeight problems
await addMsg(msg => delete msg.previewWidth);
await addMsg(msg => msg.previewWidth = '12px');
await addMsg(msg => msg.previewWidth = 0);
await addMsg(msg => msg.previewWidth = MAX_PREVIEW_WIDTH + 1);
await addMsg(msg => delete msg.previewHeight);
await addMsg(msg => msg.previewHeight = '12px');
await addMsg(msg => msg.previewHeight = 0);
await addMsg(msg => msg.previewHeight = MAX_PREVIEW_HEIGHT + 1);
var on_error = sandbox.spy();
var res = await decodeMsgs({ private_memo: bob.memo, msgs: messages,
on_error: (msg, idx, err) => {
on_error(msg, idx, err.message);
}
})
on_error = on_error.getCalls();
assert.lengthOf(on_error, 10);
// no body
assert.calledWith(on_error[0], messages[1], 1, 'message.body should be a string');
// no app
assert.calledWith(on_error[1], messages[2], 2, 'message.app should be a string, >= 1, <= 16');
// previewWidth, previewHeight problems
assert.calledWith(on_error[2], messages[3], 3, 'message.previewWidth (for image) should be an integer, >= 1, <= 600');
assert.calledWith(on_error[3], messages[4], 4, 'message.previewWidth (for image) should be an integer, >= 1, <= 600');
assert.calledWith(on_error[4], messages[5], 5, 'message.previewWidth (for image) should be an integer, >= 1, <= 600');
assert.calledWith(on_error[5], messages[6], 6, 'message.previewWidth (for image) should be an integer, >= 1, <= 600')
assert.calledWith(on_error[6], messages[7], 7, 'message.previewHeight (for image) should be an integer, >= 1, <= 300');
assert.calledWith(on_error[7], messages[8], 8, 'message.previewHeight (for image) should be an integer, >= 1, <= 300');
assert.calledWith(on_error[8], messages[9], 9, 'message.previewHeight (for image) should be an integer, >= 1, <= 300');
assert.calledWith(on_error[9], messages[10], 10, 'message.previewHeight (for image) should be an integer, >= 1, <= 300');
assert.lengthOf(res, messages.length);
})
it('on_error without return', async function() {
var on_error = sandbox.spy();
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
on_error: (msg, i, ex) => {
on_error(msg, i, ex.message);
}
})
assert.deepStrictEqual(res, this.decoded);
on_error = on_error.getCalls();
assert.lengthOf(on_error, 2);
assert.calledWith(on_error[0], this.msgObjs[2], 2, 'Invalid key')
assert.calledWith(on_error[1], this.msgObjs[3], 3, 'message.body should be a string')
})
it('on_error with return false', async function() {
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
on_error: (msg, i, ex) => {
return false;
}
})
assert.deepStrictEqual(res, this.decoded);
})
it('on_error with return true', async function() {
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
on_error: (msg, i, ex) => {
return true;
}
})
assert.lengthOf(res, 2);
assert.deepStrictEqual(res[0].message, this.msgs[0]);
assert.deepStrictEqual(res[1].message, this.msgs[1]);
})
it('for_each without return', async function() {
var for_each = sandbox.spy();
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
for_each: (msg, i) => {
for_each(msg, i);
}
})
assert.deepStrictEqual(res, this.decoded);
for_each = for_each.getCalls();
assert.equal(for_each.length, res.length);
for (let i = 0; i < this.decoded.length; ++i) {
assert.calledWith(for_each[i], this.decoded[i], i);
}
})
it('for_each with return false', async function() {
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
for_each: (msg, i) => {
return false;
}
})
assert.deepStrictEqual(res, this.decoded);
})
it('for_each with return true', async function() {
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
for_each: (msg, i) => {
if (i % 2 != 0) return true;
}
})
assert.deepStrictEqual(res[0], this.decoded[0]);
assert.deepStrictEqual(res[1], this.decoded[2]);
})
it('for_each with on_error shouldn\'t be called if error occured', async function() {
var for_each = sandbox.spy();
var on_error = sandbox.spy();
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
for_each: (msg, i) => {
for_each(msg, i);
},
on_error: (msg, i, exception) => {
on_error(msg, i, exception.message);
}
})
assert.lengthOf(res, this.msgObjs.length);
for_each = for_each.getCalls();
assert.lengthOf(for_each, 2);
assert.calledWith(for_each[0], res[0], 0);
assert.calledWith(for_each[1], res[1], 1);
on_error = on_error.getCalls();
assert.lengthOf(on_error, 2);
assert.calledWith(on_error[0], res[2], 2);
assert.calledWith(on_error[1], res[3], 3);
})
it('for_each throws, on_error decides push result or not', async function() {
var on_error = sandbox.spy();
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
for_each: (msg, i) => {
throw new Error('for_each fail');
},
on_error: (msg, i, exception) => {
on_error(msg, i, exception.message);
if (i === 2) return true; // do not push
}
})
assert.lengthOf(res, 3);
on_error = on_error.getCalls();
assert.lengthOf(on_error, 4);
assert.calledWith(on_error[0], res[0], 0, 'for_each fail');
assert.calledWith(on_error[1], res[1], 1, 'for_each fail');
assert.calledWith(on_error[2], this.msgObjs[2], 2, 'Invalid key');
assert.calledWith(on_error[3], res[2], 3, 'message.body should be a string');
})
it('before_decode with no return', async function() {
// for comparison
for (let obj of this.decoded) obj.field = 'test';
var before_decode = sandbox.spy();
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
before_decode: (msg, i, results) => {
msg.field = 'test';
before_decode(msg, i, results);
}
})
assert.deepStrictEqual(res, this.decoded);
// check before_decode calls
before_decode = before_decode.getCalls();
assert.lengthOf(before_decode, this.msgObjs.length);
for (let i = 0; i < before_decode.length; ++i) {
assert.calledWith(before_decode[i], this.msgObjs[i], i, res);
}
})
it('before_decode with return false', async function() {
// for comparison
for (let obj of this.decoded) obj.field = 'test';
// before_decode with return false
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
before_decode: (msg, i, results) => {
msg.field = 'test';
return false;
}
})
assert.deepStrictEqual(res, this.decoded);
})
it('before_decode with return true (canceling mode)', async function() {
// for comparison
for (let obj of this.decoded) obj.field = 'test';
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
before_decode: (msg, i, results) => {
msg.field = 'test';
return i % 2 != 0;
}
})
assert.lengthOf(res, 2);
assert.deepStrictEqual(res[0], this.decoded[0]);
assert.deepStrictEqual(res[1], this.decoded[2]);
})
it('before_decode throws without on_error', async function() {
var before_decode = sandbox.spy();
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
before_decode: (msg, i, results) => {
before_decode(msg, i, results);
throw new Error('before_decode fail');
}
})
before_decode = before_decode.getCalls();
assert.lengthOf(before_decode, res.length);
assert.lengthOf(res, this.msgObjs.length);
for (let i = 0; i < res.length; ++i) {
assert.calledWith(before_decode[i], res[i], i, res);
assert.isNull(res[i].raw_message);
assert.isNull(res[i].message);
}
})
it('before_decode throws with on_error', async function() {
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
before_decode: (msg, i, results) => {
throw new Error('before_decode fail');
},
on_error: (msg, i, err) => {
assert.equal(err.message, 'before_decode fail');
msg.message = 'alt msg';
}
})
assert.lengthOf(res, this.msgObjs.length);
for (let i = 0; i < res.length; ++i) {
assert.isNull(res[i].raw_message);
assert.equal(res[i].message, 'alt msg');
}
})
it('ordering + slicing', async function() {
// default case
var res = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs })
// reversed order case
var resRev = await decodeMsgs({ private_memo: bob.memo, msgs: this.msgObjs,
begin_idx: this.msgObjs.length - 1, end_idx: -1 })
assert.deepStrictEqual([...resRev].reverse(), res);
// reversed + slicing
var resSl = await decodeMsgs({ private_memo: bob.memo, msgs: cloneDeep(this.msgObjs),
begin_idx: this.msgObjs.length - 2, end_idx: 0 })
assert.lengthOf(resSl, 2);
assert.deepStrictEqual(resSl[0], resRev[1]);
assert.deepStrictEqual(resSl[1], resRev[2]);
// default + slicing by begin_idx only
var resSl = await decodeMsgs({ private_memo: bob.memo, msgs: cloneDeep(this.msgObjs),
begin_idx: 2 })
assert.lengthOf(resSl, 2);
assert.deepStrictEqual(resSl[0], res[2]);
assert.deepStrictEqual(resSl[1], res[3]);
})
})
describe('golos.messages: decode() replies', function() {
it('message', async function() {
var msg = newTextMsg('Привет');
var enc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
const orig = Object.assign({
from: 'alice',
}, enc);
var origDecoded = await decodeMsgs({ private_memo: alice.memo, msgs: [orig] })
var msg2 = newTextMsg('Hi');
msg2 = makeQuoteMsg(msg2, origDecoded[0]);
var enc2 = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: msg2 })
const reply = Object.assign({
from: 'bob',
}, enc2);
var bothDecoded = await decodeMsgs({ private_memo: alice.memo, msgs: [orig, enc2] })
assert.lengthOf(bothDecoded, 2);
assert.strictEqual(bothDecoded[1].message.quote.from, bothDecoded[0].from);
assert.strictEqual(bothDecoded[1].message.quote.nonce, bothDecoded[0].nonce);
assert.strictEqual(bothDecoded[1].message.quote.body, bothDecoded[0].message.body);
assert.strictEqual(bothDecoded[1].message.quote.type, bothDecoded[0].message.type);
})
it('too long message', async function() {
var msg = newTextMsg('a'.repeat(MAX_TEXT_QUOTE_LENGTH + 1));
var enc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
const orig = Object.assign({
from: 'alice',
}, enc);
var origDecoded = await decodeMsgs({ private_memo: alice.memo, msgs: [orig] })
var msg2 = newTextMsg('Hi');
msg2 = makeQuoteMsg(msg2, origDecoded[0]);
// keep its original length to make message invalid
msg2.quote.body = 'a'.repeat(MAX_TEXT_QUOTE_LENGTH + 1);
var enc2 = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: msg2 })
const reply = Object.assign({
from: 'bob',
}, enc2);
var bothDecoded = await decodeMsgs({ private_memo: alice.memo, msgs: [orig, enc2] })
assert.lengthOf(bothDecoded, 2);
assert.isNotNull(bothDecoded[1].raw_message);
assert.isNull(bothDecoded[1].message);
})
it('image message (its body can be long)', async function() {
assert.isTrue(correctImageURL.length > MAX_TEXT_QUOTE_LENGTH, 'too short correctImageURL for this test');
var msg = await newImageMsgAsync(correctImageURL);
var enc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
const orig = Object.assign({
from: 'alice',
}, enc);
var origDecoded = await decodeMsgs({ private_memo: alice.memo, msgs: [orig] })
var msg2 = newTextMsg('Hi');
msg2 = makeQuoteMsg(msg2, origDecoded[0]);
var enc2 = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: msg2 })
const reply = Object.assign({
from: 'bob',
}, enc2);
var bothDecoded = await decodeMsgs({ private_memo: alice.memo, msgs: [orig, enc2] })
assert.lengthOf(bothDecoded, 2);
assert.strictEqual(bothDecoded[1].message.quote.from, bothDecoded[0].from);
assert.strictEqual(bothDecoded[1].message.quote.nonce, bothDecoded[0].nonce);
assert.strictEqual(bothDecoded[1].message.quote.body, bothDecoded[0].message.body);
assert.strictEqual(bothDecoded[1].message.quote.type, bothDecoded[0].message.type);
})
it('image message (too long)', async function() {
var msg = {
body: 'a'.repeat(MAX_IMAGE_QUOTE_LENGTH + 1),
type: 'image',
app: DEFAULT_APP,
version: DEFAULT_VERSION,
previewWidth: MAX_PREVIEW_WIDTH,
previewHeight: MAX_PREVIEW_HEIGHT,
};
var enc = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg })
const orig = Object.assign({
from: 'alice',
}, enc);
var origDecoded = await decodeMsgs({ private_memo: alice.memo, msgs: [orig] })
var msg2 = newTextMsg('Hi');
msg2 = makeQuoteMsg(msg2, origDecoded[0]);
var enc2 = await encodeMsg({ private_memo: alice.memo,
to_public_memo: bob.memo_pub, msg: msg2 })
const reply = Object.assign({
from: 'bob',
}, enc2);
var bothDecoded = await decodeMsgs({ private_memo: alice.memo, msgs: [orig, enc2] })
assert.lengthOf(bothDecoded, 2);
assert.strictEqual(bothDecoded[1].message.quote.from, bothDecoded[0].from);
assert.strictEqual(bothDecoded[1].message.quote.nonce, bothDecoded[0].nonce);
assert.strictEqual(bothDecoded[1].message.quote.body, bothDecoded[0].message.body.substring(0, MAX_TEXT_QUOTE_LENGTH - 3) + '...');
assert.strictEqual(bothDecoded[1].message.quote.type, undefined);
})
})