210 lines
5.4 KiB
TypeScript
210 lines
5.4 KiB
TypeScript
// 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],
|
|
};
|
|
|
|
const rootState = getEmptyRootState();
|
|
|
|
const getState = () => ({
|
|
...rootState,
|
|
stories: {
|
|
...rootState.stories,
|
|
stories: [
|
|
{
|
|
...messageAttributes,
|
|
attachment: messageAttributes.attachments[0],
|
|
messageId: messageAttributes.id,
|
|
},
|
|
],
|
|
},
|
|
});
|
|
|
|
window.MessageController.register(storyId, messageAttributes);
|
|
|
|
const dispatch = sinon.spy();
|
|
await queueStoryDownload(storyId)(dispatch, getState, 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,
|
|
},
|
|
],
|
|
};
|
|
|
|
const rootState = getEmptyRootState();
|
|
|
|
const getState = () => ({
|
|
...rootState,
|
|
stories: {
|
|
...rootState.stories,
|
|
stories: [
|
|
{
|
|
...messageAttributes,
|
|
attachment: messageAttributes.attachments[0],
|
|
messageId: messageAttributes.id,
|
|
},
|
|
],
|
|
},
|
|
});
|
|
|
|
window.MessageController.register(storyId, messageAttributes);
|
|
|
|
const dispatch = sinon.spy();
|
|
await queueStoryDownload(storyId)(dispatch, getState, null);
|
|
|
|
sinon.assert.calledWith(dispatch, {
|
|
type: 'NOOP',
|
|
payload: null,
|
|
});
|
|
});
|
|
});
|
|
});
|