Ensure that we resolve attachments before displaying them
This commit is contained in:
parent
72f979ea1d
commit
d8708e4e73
9 changed files with 319 additions and 31 deletions
178
ts/test-electron/state/ducks/stories_test.ts
Normal file
178
ts/test-electron/state/ducks/stories_test.ts
Normal file
|
@ -0,0 +1,178 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import * as sinon from 'sinon';
|
||||
import path from 'path';
|
||||
import { assert } from 'chai';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import type { StoriesStateType } from '../../../state/ducks/stories';
|
||||
import type { MessageAttributesType } from '../../../model-types.d';
|
||||
import { IMAGE_JPEG } from '../../../types/MIME';
|
||||
import {
|
||||
actions,
|
||||
getEmptyState,
|
||||
reducer,
|
||||
RESOLVE_ATTACHMENT_URL,
|
||||
} from '../../../state/ducks/stories';
|
||||
import { noopAction } from '../../../state/ducks/noop';
|
||||
import { reducer as rootReducer } from '../../../state/reducer';
|
||||
|
||||
describe('both/state/ducks/stories', () => {
|
||||
const getEmptyRootState = () => ({
|
||||
...rootReducer(undefined, noopAction()),
|
||||
stories: getEmptyState(),
|
||||
});
|
||||
|
||||
function getStoryMessage(id: string): MessageAttributesType {
|
||||
const now = Date.now();
|
||||
|
||||
return {
|
||||
conversationId: uuid(),
|
||||
id,
|
||||
received_at: now,
|
||||
sent_at: now,
|
||||
timestamp: now,
|
||||
type: 'story',
|
||||
};
|
||||
}
|
||||
|
||||
describe('queueStoryDownload', () => {
|
||||
const { queueStoryDownload } = actions;
|
||||
|
||||
it('no attachment, no dispatch', async function test() {
|
||||
const storyId = uuid();
|
||||
const messageAttributes = getStoryMessage(storyId);
|
||||
|
||||
window.MessageController.register(storyId, messageAttributes);
|
||||
|
||||
const dispatch = sinon.spy();
|
||||
await queueStoryDownload(storyId)(dispatch, getEmptyRootState, null);
|
||||
|
||||
sinon.assert.notCalled(dispatch);
|
||||
});
|
||||
|
||||
it('downloading, no dispatch', async function test() {
|
||||
const storyId = uuid();
|
||||
const messageAttributes = {
|
||||
...getStoryMessage(storyId),
|
||||
attachments: [
|
||||
{
|
||||
contentType: IMAGE_JPEG,
|
||||
downloadJobId: uuid(),
|
||||
pending: true,
|
||||
size: 0,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
window.MessageController.register(storyId, messageAttributes);
|
||||
|
||||
const dispatch = sinon.spy();
|
||||
await queueStoryDownload(storyId)(dispatch, getEmptyRootState, null);
|
||||
|
||||
sinon.assert.notCalled(dispatch);
|
||||
});
|
||||
|
||||
it('downloaded, no dispatch', async function test() {
|
||||
const storyId = uuid();
|
||||
const messageAttributes = {
|
||||
...getStoryMessage(storyId),
|
||||
attachments: [
|
||||
{
|
||||
contentType: IMAGE_JPEG,
|
||||
path: 'image.jpg',
|
||||
url: '/path/to/image.jpg',
|
||||
size: 0,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
window.MessageController.register(storyId, messageAttributes);
|
||||
|
||||
const dispatch = sinon.spy();
|
||||
await queueStoryDownload(storyId)(dispatch, getEmptyRootState, null);
|
||||
|
||||
sinon.assert.notCalled(dispatch);
|
||||
});
|
||||
|
||||
it('downloaded, but unresolved, we should resolve the path', async function test() {
|
||||
const storyId = uuid();
|
||||
const attachment = {
|
||||
contentType: IMAGE_JPEG,
|
||||
path: 'image.jpg',
|
||||
size: 0,
|
||||
};
|
||||
const messageAttributes = {
|
||||
...getStoryMessage(storyId),
|
||||
attachments: [attachment],
|
||||
};
|
||||
|
||||
window.MessageController.register(storyId, messageAttributes);
|
||||
|
||||
const dispatch = sinon.spy();
|
||||
await queueStoryDownload(storyId)(dispatch, getEmptyRootState, null);
|
||||
|
||||
const action = dispatch.getCall(0).args[0];
|
||||
|
||||
sinon.assert.calledWith(dispatch, {
|
||||
type: RESOLVE_ATTACHMENT_URL,
|
||||
payload: {
|
||||
messageId: storyId,
|
||||
attachmentUrl: action.payload.attachmentUrl,
|
||||
},
|
||||
});
|
||||
assert.equal(
|
||||
attachment.path,
|
||||
path.basename(action.payload.attachmentUrl)
|
||||
);
|
||||
|
||||
const stateWithStory: StoriesStateType = {
|
||||
...getEmptyRootState().stories,
|
||||
stories: [
|
||||
{
|
||||
...messageAttributes,
|
||||
messageId: storyId,
|
||||
attachment,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const nextState = reducer(stateWithStory, action);
|
||||
assert.isDefined(nextState.stories);
|
||||
assert.equal(
|
||||
nextState.stories[0].attachment?.url,
|
||||
action.payload.attachmentUrl
|
||||
);
|
||||
|
||||
const state = getEmptyRootState().stories;
|
||||
|
||||
const sameState = reducer(state, action);
|
||||
assert.isDefined(sameState.stories);
|
||||
assert.equal(sameState, state);
|
||||
});
|
||||
|
||||
it('not downloaded, queued for download', async function test() {
|
||||
const storyId = uuid();
|
||||
const messageAttributes = {
|
||||
...getStoryMessage(storyId),
|
||||
attachments: [
|
||||
{
|
||||
contentType: IMAGE_JPEG,
|
||||
size: 0,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
window.MessageController.register(storyId, messageAttributes);
|
||||
|
||||
const dispatch = sinon.spy();
|
||||
await queueStoryDownload(storyId)(dispatch, getEmptyRootState, null);
|
||||
|
||||
sinon.assert.calledWith(dispatch, {
|
||||
type: 'NOOP',
|
||||
payload: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue