diff --git a/app/soapbox/normalizers/__tests__/attachment-test.js b/app/soapbox/normalizers/__tests__/attachment-test.js new file mode 100644 index 000000000..ecf3813e7 --- /dev/null +++ b/app/soapbox/normalizers/__tests__/attachment-test.js @@ -0,0 +1,21 @@ +import { Record as ImmutableRecord, fromJS } from 'immutable'; + +import { normalizeAttachment } from '../attachment'; + +describe('normalizeAttachment()', () => { + it('adds base fields', () => { + const attachment = fromJS({}); + const result = normalizeAttachment(attachment); + + expect(ImmutableRecord.isRecord(result)).toBe(true); + expect(result.type).toEqual('unknown'); + expect(result.url).toEqual(''); + }); + + it('infers preview_url from url', () => { + const attachment = fromJS({ url: 'https://site.fedi/123.png' }); + const result = normalizeAttachment(attachment); + + expect(result.preview_url).toEqual('https://site.fedi/123.png'); + }); +}); diff --git a/app/soapbox/normalizers/attachment.ts b/app/soapbox/normalizers/attachment.ts new file mode 100644 index 000000000..9599fc1ce --- /dev/null +++ b/app/soapbox/normalizers/attachment.ts @@ -0,0 +1,45 @@ +/** + * Attachment normalizer: + * Converts API attachments into our internal format. + * @see {@link https://docs.joinmastodon.org/entities/attachment/} + */ +import { + Map as ImmutableMap, + Record as ImmutableRecord, +} from 'immutable'; + +import { mergeDefined } from 'soapbox/utils/normalizers'; + +// https://docs.joinmastodon.org/entities/attachment/ +const AttachmentRecord = ImmutableRecord({ + blurhash: undefined, + description: '', + id: '', + meta: ImmutableMap(), + pleroma: ImmutableMap(), + preview_url: '', + remote_url: null, + type: 'unknown', + url: '', + + // Internal fields + // TODO: Remove these? They're set in selectors/index.js + account: null, + status: null, +}); + +// Ensure attachments have required fields +export const normalizeAttachment = (attachment: ImmutableMap) => { + const url = [ + attachment.get('url'), + attachment.get('preview_url'), + attachment.get('remote_url'), + ].find(url => url) || ''; + + const base = ImmutableMap({ + url, + preview_url: url, + }); + + return AttachmentRecord(attachment.mergeWith(mergeDefined, base)); +}; diff --git a/app/soapbox/normalizers/status.ts b/app/soapbox/normalizers/status.ts index 91c52cfa3..4cbf83e5b 100644 --- a/app/soapbox/normalizers/status.ts +++ b/app/soapbox/normalizers/status.ts @@ -9,11 +9,11 @@ import { Record as ImmutableRecord, } from 'immutable'; +import { normalizeAttachment } from 'soapbox/normalizers/attachment'; import { normalizeEmoji } from 'soapbox/normalizers/emoji'; import { normalizeMention } from 'soapbox/normalizers/mention'; import { normalizePoll } from 'soapbox/normalizers/poll'; import { IStatus } from 'soapbox/types'; -import { mergeDefined } from 'soapbox/utils/normalizers'; // https://docs.joinmastodon.org/entities/status/ const StatusRecord = ImmutableRecord({ @@ -55,39 +55,6 @@ const StatusRecord = ImmutableRecord({ spoilerHtml: '', }); -// https://docs.joinmastodon.org/entities/attachment/ -const AttachmentRecord = ImmutableRecord({ - blurhash: undefined, - description: '', - id: '', - meta: ImmutableMap(), - pleroma: ImmutableMap(), - preview_url: '', - remote_url: null, - type: 'unknown', - url: '', - - // Internal fields - account: null, - status: null, -}); - -// Ensure attachments have required fields -const normalizeAttachment = (attachment: ImmutableMap) => { - const url = [ - attachment.get('url'), - attachment.get('preview_url'), - attachment.get('remote_url'), - ].find(url => url) || ''; - - const base = ImmutableMap({ - url, - preview_url: url, - }); - - return AttachmentRecord(attachment.mergeWith(mergeDefined, base)); -}; - const normalizeAttachments = (status: ImmutableMap) => { return status.update('media_attachments', ImmutableList(), attachments => { return attachments.map(normalizeAttachment);