Fix "did reaction fully send?" logic
This commit is contained in:
parent
2dded88081
commit
0c12607e79
7 changed files with 352 additions and 77 deletions
150
ts/test-node/jobs/helpers/handleMultipleSendErrors_test.ts
Normal file
150
ts/test-node/jobs/helpers/handleMultipleSendErrors_test.ts
Normal file
|
@ -0,0 +1,150 @@
|
|||
// Copyright 2022 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import * as sinon from 'sinon';
|
||||
import { noop } from 'lodash';
|
||||
import { HTTPError } from '../../../textsecure/Errors';
|
||||
import { SECOND } from '../../../util/durations';
|
||||
|
||||
import { handleMultipleSendErrors } from '../../../jobs/helpers/handleMultipleSendErrors';
|
||||
|
||||
describe('handleMultipleSendErrors', () => {
|
||||
const make413 = (retryAfter: number): HTTPError =>
|
||||
new HTTPError('Slow down', {
|
||||
code: 413,
|
||||
headers: { 'retry-after': retryAfter.toString() },
|
||||
response: {},
|
||||
});
|
||||
|
||||
const defaultOptions = {
|
||||
isFinalAttempt: false,
|
||||
log: { info: noop },
|
||||
markFailed: () => {
|
||||
throw new Error('This should not be called');
|
||||
},
|
||||
timeRemaining: 1234,
|
||||
};
|
||||
|
||||
let sandbox: sinon.SinonSandbox;
|
||||
let clock: sinon.SinonFakeTimers;
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = sinon.createSandbox();
|
||||
clock = sandbox.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('throws the first provided error', async () => {
|
||||
await assert.isRejected(
|
||||
handleMultipleSendErrors({
|
||||
...defaultOptions,
|
||||
errors: [new Error('first'), new Error('second')],
|
||||
}),
|
||||
'first'
|
||||
);
|
||||
});
|
||||
|
||||
it("marks the send failed if it's the final attempt", async () => {
|
||||
const markFailed = sinon.stub();
|
||||
|
||||
await assert.isRejected(
|
||||
handleMultipleSendErrors({
|
||||
...defaultOptions,
|
||||
errors: [new Error('uh oh')],
|
||||
markFailed,
|
||||
isFinalAttempt: true,
|
||||
})
|
||||
);
|
||||
|
||||
sinon.assert.calledOnceWithExactly(markFailed);
|
||||
});
|
||||
|
||||
describe('413 handling', () => {
|
||||
it('sleeps for the longest 413 Retry-After time', async () => {
|
||||
let done = false;
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await handleMultipleSendErrors({
|
||||
...defaultOptions,
|
||||
errors: [
|
||||
new Error('Other'),
|
||||
make413(10),
|
||||
make413(999),
|
||||
make413(20),
|
||||
],
|
||||
timeRemaining: 99999999,
|
||||
});
|
||||
} catch (err) {
|
||||
// No-op
|
||||
} finally {
|
||||
done = true;
|
||||
}
|
||||
})();
|
||||
|
||||
await clock.tickAsync(900 * SECOND);
|
||||
assert.isFalse(done, "Didn't sleep for long enough");
|
||||
await clock.tickAsync(100 * SECOND);
|
||||
assert.isTrue(done, 'Slept for too long');
|
||||
});
|
||||
|
||||
it("doesn't sleep longer than the remaining time", async () => {
|
||||
let done = false;
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await handleMultipleSendErrors({
|
||||
...defaultOptions,
|
||||
errors: [make413(9999)],
|
||||
timeRemaining: 99,
|
||||
});
|
||||
} catch (err) {
|
||||
// No-op
|
||||
} finally {
|
||||
done = true;
|
||||
}
|
||||
})();
|
||||
|
||||
await clock.tickAsync(100);
|
||||
assert.isTrue(done);
|
||||
});
|
||||
|
||||
it("doesn't sleep if it's the final attempt", async () => {
|
||||
await assert.isRejected(
|
||||
handleMultipleSendErrors({
|
||||
...defaultOptions,
|
||||
errors: [new Error('uh oh')],
|
||||
isFinalAttempt: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('508 handling', () => {
|
||||
it('resolves with no error if any 508 is received', async () => {
|
||||
await assert.isFulfilled(
|
||||
handleMultipleSendErrors({
|
||||
...defaultOptions,
|
||||
errors: [new Error('uh oh'), { code: 508 }, make413(99999)],
|
||||
markFailed: noop,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('marks the send failed on a 508', async () => {
|
||||
const markFailed = sinon.stub();
|
||||
|
||||
await handleMultipleSendErrors({
|
||||
...defaultOptions,
|
||||
errors: [{ code: 508 }],
|
||||
markFailed,
|
||||
});
|
||||
|
||||
sinon.assert.calledOnceWithExactly(markFailed);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue