Merge branch 'normalizer-exports' into 'develop'

Normalizer exports, use fromJS in all normalizers

See merge request soapbox-pub/soapbox-fe!1105
This commit is contained in:
Alex Gleason 2022-03-17 03:03:43 +00:00
commit c413d94459
21 changed files with 122 additions and 98 deletions

View File

@ -6,7 +6,7 @@ const AVATAR_MISSING = require('images/avatar-missing.png');
describe('normalizeAccount()', () => { describe('normalizeAccount()', () => {
it('adds base fields', () => { it('adds base fields', () => {
const account = fromJS({}); const account = {};
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(ImmutableRecord.isRecord(result)).toBe(true); expect(ImmutableRecord.isRecord(result)).toBe(true);
@ -16,12 +16,12 @@ describe('normalizeAccount()', () => {
}); });
it('normalizes a mention', () => { it('normalizes a mention', () => {
const mention = fromJS({ const mention = {
acct: 'NEETzsche@iddqd.social', acct: 'NEETzsche@iddqd.social',
id: '9v5bw7hEGBPc9nrpzc', id: '9v5bw7hEGBPc9nrpzc',
url: 'https://iddqd.social/users/NEETzsche', url: 'https://iddqd.social/users/NEETzsche',
username: 'NEETzsche', username: 'NEETzsche',
}); };
const result = normalizeAccount(mention); const result = normalizeAccount(mention);
expect(result.emojis).toEqual(fromJS([])); expect(result.emojis).toEqual(fromJS([]));
@ -32,21 +32,21 @@ describe('normalizeAccount()', () => {
}); });
it('normalizes Fedibird birthday', () => { it('normalizes Fedibird birthday', () => {
const account = fromJS(require('soapbox/__fixtures__/fedibird-account.json')); const account = require('soapbox/__fixtures__/fedibird-account.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.birthday).toEqual('1993-07-03'); expect(result.birthday).toEqual('1993-07-03');
}); });
it('normalizes Pleroma birthday', () => { it('normalizes Pleroma birthday', () => {
const account = fromJS(require('soapbox/__fixtures__/pleroma-account.json')); const account = require('soapbox/__fixtures__/pleroma-account.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.birthday).toEqual('1993-07-03'); expect(result.birthday).toEqual('1993-07-03');
}); });
it('normalizes Pleroma legacy fields', () => { it('normalizes Pleroma legacy fields', () => {
const account = fromJS(require('soapbox/__fixtures__/pleroma-2.2.2-account.json')); const account = require('soapbox/__fixtures__/pleroma-2.2.2-account.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.getIn(['pleroma', 'is_active'])).toBe(true); expect(result.getIn(['pleroma', 'is_active'])).toBe(true);
@ -57,7 +57,7 @@ describe('normalizeAccount()', () => {
}); });
it('prefers new Pleroma fields', () => { it('prefers new Pleroma fields', () => {
const account = fromJS(require('soapbox/__fixtures__/pleroma-account.json')); const account = require('soapbox/__fixtures__/pleroma-account.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.getIn(['pleroma', 'is_active'])).toBe(true); expect(result.getIn(['pleroma', 'is_active'])).toBe(true);
@ -66,76 +66,76 @@ describe('normalizeAccount()', () => {
}); });
it('normalizes a verified Pleroma user', () => { it('normalizes a verified Pleroma user', () => {
const account = fromJS(require('soapbox/__fixtures__/mk.json')); const account = require('soapbox/__fixtures__/mk.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.verified).toBe(true); expect(result.verified).toBe(true);
}); });
it('normalizes an unverified Pleroma user', () => { it('normalizes an unverified Pleroma user', () => {
const account = fromJS(require('soapbox/__fixtures__/pleroma-account.json')); const account = require('soapbox/__fixtures__/pleroma-account.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.verified).toBe(false); expect(result.verified).toBe(false);
}); });
it('normalizes a verified Truth Social user', () => { it('normalizes a verified Truth Social user', () => {
const account = fromJS(require('soapbox/__fixtures__/realDonaldTrump.json')); const account = require('soapbox/__fixtures__/realDonaldTrump.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.verified).toBe(true); expect(result.verified).toBe(true);
}); });
it('normalizes Fedibird location', () => { it('normalizes Fedibird location', () => {
const account = fromJS(require('soapbox/__fixtures__/fedibird-account.json')); const account = require('soapbox/__fixtures__/fedibird-account.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.location).toBe('Texas, USA'); expect(result.location).toBe('Texas, USA');
}); });
it('normalizes Truth Social location', () => { it('normalizes Truth Social location', () => {
const account = fromJS(require('soapbox/__fixtures__/truthsocial-account.json')); const account = require('soapbox/__fixtures__/truthsocial-account.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.location).toBe('Texas'); expect(result.location).toBe('Texas');
}); });
it('sets display_name from username', () => { it('sets display_name from username', () => {
const account = fromJS({ username: 'alex' }); const account = { username: 'alex' };
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.display_name).toBe('alex'); expect(result.display_name).toBe('alex');
}); });
it('sets display_name from acct', () => { it('sets display_name from acct', () => {
const account = fromJS({ acct: 'alex@gleasonator.com' }); const account = { acct: 'alex@gleasonator.com' };
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.display_name).toBe('alex'); expect(result.display_name).toBe('alex');
}); });
it('overrides a whitespace display_name', () => { it('overrides a whitespace display_name', () => {
const account = fromJS({ username: 'alex', display_name: ' ' }); const account = { username: 'alex', display_name: ' ' };
const result = normalizeAccount(account); const result = normalizeAccount(account);
expect(result.display_name).toBe('alex'); expect(result.display_name).toBe('alex');
}); });
it('emojifies display name as `display_name_html`', () => { it('emojifies display name as `display_name_html`', () => {
const account = fromJS(require('soapbox/__fixtures__/account-with-emojis.json')); const account = require('soapbox/__fixtures__/account-with-emojis.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
const expected = 'Alex Gleason <img draggable="false" class="emojione" alt="😂" title=":joy:" src="/packs/emoji/1f602.svg" /> <img draggable="false" class="emojione" alt=":soapbox:" title=":soapbox:" src="https://gleasonator.com/emoji/Gleasonator/soapbox.png" /> <img draggable="false" class="emojione" alt=":ablobcatrainbow:" title=":ablobcatrainbow:" src="https://gleasonator.com/emoji/blobcat/ablobcatrainbow.png" />'; const expected = 'Alex Gleason <img draggable="false" class="emojione" alt="😂" title=":joy:" src="/packs/emoji/1f602.svg" /> <img draggable="false" class="emojione" alt=":soapbox:" title=":soapbox:" src="https://gleasonator.com/emoji/Gleasonator/soapbox.png" /> <img draggable="false" class="emojione" alt=":ablobcatrainbow:" title=":ablobcatrainbow:" src="https://gleasonator.com/emoji/blobcat/ablobcatrainbow.png" />';
expect(result.display_name_html).toBe(expected); expect(result.display_name_html).toBe(expected);
}); });
it('emojifies note as `note_emojified`', () => { it('emojifies note as `note_emojified`', () => {
const account = fromJS(require('soapbox/__fixtures__/account-with-emojis.json')); const account = require('soapbox/__fixtures__/account-with-emojis.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
const expected = 'I create Fediverse software that empowers people online. <img draggable="false" class="emojione" alt=":soapbox:" title=":soapbox:" src="https://gleasonator.com/emoji/Gleasonator/soapbox.png" /><br/><br/>I&#39;m vegan btw<br/><br/>Note: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.'; const expected = 'I create Fediverse software that empowers people online. <img draggable="false" class="emojione" alt=":soapbox:" title=":soapbox:" src="https://gleasonator.com/emoji/Gleasonator/soapbox.png" /><br/><br/>I&#39;m vegan btw<br/><br/>Note: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.';
expect(result.note_emojified).toBe(expected); expect(result.note_emojified).toBe(expected);
}); });
it('unescapes HTML note as `note_plain`', () => { it('unescapes HTML note as `note_plain`', () => {
const account = fromJS(require('soapbox/__fixtures__/account-with-emojis.json')); const account = require('soapbox/__fixtures__/account-with-emojis.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
const expected = 'I create Fediverse software that empowers people online. :soapbox:\n\nI\'m vegan btw\n\nNote: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.'; const expected = 'I create Fediverse software that empowers people online. :soapbox:\n\nI\'m vegan btw\n\nNote: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.';
expect(result.note_plain).toBe(expected); expect(result.note_plain).toBe(expected);
}); });
it('emojifies custom profile field', () => { it('emojifies custom profile field', () => {
const account = fromJS(require('soapbox/__fixtures__/account-with-emojis.json')); const account = require('soapbox/__fixtures__/account-with-emojis.json');
const result = normalizeAccount(account); const result = normalizeAccount(account);
const field = result.fields.get(1); const field = result.fields.get(1);

View File

@ -1,10 +1,10 @@
import { Record as ImmutableRecord, fromJS } from 'immutable'; import { Record as ImmutableRecord } from 'immutable';
import { normalizeAttachment } from '../attachment'; import { normalizeAttachment } from '../attachment';
describe('normalizeAttachment()', () => { describe('normalizeAttachment()', () => {
it('adds base fields', () => { it('adds base fields', () => {
const attachment = fromJS({}); const attachment = {};
const result = normalizeAttachment(attachment); const result = normalizeAttachment(attachment);
expect(ImmutableRecord.isRecord(result)).toBe(true); expect(ImmutableRecord.isRecord(result)).toBe(true);
@ -13,7 +13,7 @@ describe('normalizeAttachment()', () => {
}); });
it('infers preview_url from url', () => { it('infers preview_url from url', () => {
const attachment = fromJS({ url: 'https://site.fedi/123.png' }); const attachment = { url: 'https://site.fedi/123.png' };
const result = normalizeAttachment(attachment); const result = normalizeAttachment(attachment);
expect(result.preview_url).toEqual('https://site.fedi/123.png'); expect(result.preview_url).toEqual('https://site.fedi/123.png');

View File

@ -1,10 +1,10 @@
import { Record as ImmutableRecord, fromJS } from 'immutable'; import { Record as ImmutableRecord } from 'immutable';
import { normalizeCard } from '../card'; import { normalizeCard } from '../card';
describe('normalizeCard()', () => { describe('normalizeCard()', () => {
it('adds base fields', () => { it('adds base fields', () => {
const card = fromJS({}); const card = {};
const result = normalizeCard(card); const result = normalizeCard(card);
expect(ImmutableRecord.isRecord(result)).toBe(true); expect(ImmutableRecord.isRecord(result)).toBe(true);

View File

@ -59,7 +59,7 @@ describe('normalizeInstance()', () => {
}); });
it('normalizes Pleroma instance with Mastodon configuration format', () => { it('normalizes Pleroma instance with Mastodon configuration format', () => {
const instance = fromJS(require('soapbox/__fixtures__/pleroma-instance.json')); const instance = require('soapbox/__fixtures__/pleroma-instance.json');
const expected = { const expected = {
configuration: { configuration: {
@ -81,7 +81,7 @@ describe('normalizeInstance()', () => {
}); });
it('normalizes Mastodon instance with retained configuration', () => { it('normalizes Mastodon instance with retained configuration', () => {
const instance = fromJS(require('soapbox/__fixtures__/mastodon-instance.json')); const instance = require('soapbox/__fixtures__/mastodon-instance.json');
const expected = { const expected = {
configuration: { configuration: {
@ -111,7 +111,7 @@ describe('normalizeInstance()', () => {
}); });
it('normalizes Mastodon 3.0.0 instance with default configuration', () => { it('normalizes Mastodon 3.0.0 instance with default configuration', () => {
const instance = fromJS(require('soapbox/__fixtures__/mastodon-3.0.0-instance.json')); const instance = require('soapbox/__fixtures__/mastodon-3.0.0-instance.json');
const expected = { const expected = {
configuration: { configuration: {
@ -133,18 +133,18 @@ describe('normalizeInstance()', () => {
}); });
it('normalizes Fedibird instance', () => { it('normalizes Fedibird instance', () => {
const instance = fromJS(require('soapbox/__fixtures__/fedibird-instance.json')); const instance = require('soapbox/__fixtures__/fedibird-instance.json');
const result = normalizeInstance(instance); const result = normalizeInstance(instance);
// Sets description_limit // Sets description_limit
expect(result.description_limit).toEqual(1500); expect(result.description_limit).toEqual(1500);
// Preserves fedibird_capabilities // Preserves fedibird_capabilities
expect(result.fedibird_capabilities).toEqual(instance.get('fedibird_capabilities')); expect(result.fedibird_capabilities).toEqual(fromJS(instance.fedibird_capabilities));
}); });
it('normalizes Mitra instance', () => { it('normalizes Mitra instance', () => {
const instance = fromJS(require('soapbox/__fixtures__/mitra-instance.json')); const instance = require('soapbox/__fixtures__/mitra-instance.json');
const result = normalizeInstance(instance); const result = normalizeInstance(instance);
// Adds configuration and description_limit // Adds configuration and description_limit
@ -153,7 +153,7 @@ describe('normalizeInstance()', () => {
}); });
it('normalizes GoToSocial instance', () => { it('normalizes GoToSocial instance', () => {
const instance = fromJS(require('soapbox/__fixtures__/gotosocial-instance.json')); const instance = require('soapbox/__fixtures__/gotosocial-instance.json');
const result = normalizeInstance(instance); const result = normalizeInstance(instance);
// Normalizes max_toot_chars // Normalizes max_toot_chars
@ -166,7 +166,7 @@ describe('normalizeInstance()', () => {
}); });
it('normalizes Friendica instance', () => { it('normalizes Friendica instance', () => {
const instance = fromJS(require('soapbox/__fixtures__/friendica-instance.json')); const instance = require('soapbox/__fixtures__/friendica-instance.json');
const result = normalizeInstance(instance); const result = normalizeInstance(instance);
// Normalizes max_toot_chars // Normalizes max_toot_chars

View File

@ -1,10 +1,10 @@
import { Record as ImmutableRecord, fromJS } from 'immutable'; import { Record as ImmutableRecord } from 'immutable';
import { normalizeMention } from '../mention'; import { normalizeMention } from '../mention';
describe('normalizeMention()', () => { describe('normalizeMention()', () => {
it('adds base fields', () => { it('adds base fields', () => {
const account = fromJS({}); const account = {};
const result = normalizeMention(account); const result = normalizeMention(account);
expect(ImmutableRecord.isRecord(result)).toBe(true); expect(ImmutableRecord.isRecord(result)).toBe(true);
@ -15,7 +15,7 @@ describe('normalizeMention()', () => {
}); });
it('infers username from acct', () => { it('infers username from acct', () => {
const account = fromJS({ acct: 'alex@gleasonator.com' }); const account = { acct: 'alex@gleasonator.com' };
const result = normalizeMention(account); const result = normalizeMention(account);
expect(result.username).toEqual('alex'); expect(result.username).toEqual('alex');

View File

@ -1,10 +1,10 @@
import { Record as ImmutableRecord, fromJS } from 'immutable'; import { Record as ImmutableRecord } from 'immutable';
import { normalizeNotification } from '../notification'; import { normalizeNotification } from '../notification';
describe('normalizeNotification()', () => { describe('normalizeNotification()', () => {
it('normalizes an empty map', () => { it('normalizes an empty map', () => {
const notification = fromJS({}); const notification = {};
const result = normalizeNotification(notification); const result = normalizeNotification(notification);
expect(ImmutableRecord.isRecord(result)).toBe(true); expect(ImmutableRecord.isRecord(result)).toBe(true);

View File

@ -1,10 +1,10 @@
import { Record as ImmutableRecord, fromJS } from 'immutable'; import { Record as ImmutableRecord } from 'immutable';
import { normalizePoll } from '../poll'; import { normalizePoll } from '../poll';
describe('normalizePoll()', () => { describe('normalizePoll()', () => {
it('adds base fields', () => { it('adds base fields', () => {
const poll = fromJS({ options: [{ title: 'Apples' }] }); const poll = { options: [{ title: 'Apples' }] };
const result = normalizePoll(poll); const result = normalizePoll(poll);
const expected = { const expected = {
@ -25,7 +25,7 @@ describe('normalizePoll()', () => {
}); });
it('normalizes a Pleroma logged-out poll', () => { it('normalizes a Pleroma logged-out poll', () => {
const poll = fromJS(require('soapbox/__fixtures__/pleroma-status-with-poll.json')).get('poll'); const { poll } = require('soapbox/__fixtures__/pleroma-status-with-poll.json');
const result = normalizePoll(poll); const result = normalizePoll(poll);
// Adds logged-in fields // Adds logged-in fields
@ -34,7 +34,7 @@ describe('normalizePoll()', () => {
}); });
it('normalizes poll with emojis', () => { it('normalizes poll with emojis', () => {
const poll = fromJS(require('soapbox/__fixtures__/pleroma-status-with-poll-with-emojis.json')).get('poll'); const { poll } = require('soapbox/__fixtures__/pleroma-status-with-poll-with-emojis.json');
const result = normalizePoll(poll); const result = normalizePoll(poll);
// Emojifies poll options // Emojifies poll options

View File

@ -4,7 +4,7 @@ import { normalizeStatus } from '../status';
describe('normalizeStatus()', () => { describe('normalizeStatus()', () => {
it('adds base fields', () => { it('adds base fields', () => {
const status = fromJS({}); const status = {};
const result = normalizeStatus(status); const result = normalizeStatus(status);
expect(ImmutableRecord.isRecord(result)).toBe(true); expect(ImmutableRecord.isRecord(result)).toBe(true);
@ -17,7 +17,7 @@ describe('normalizeStatus()', () => {
}); });
it('fixes the order of mentions', () => { it('fixes the order of mentions', () => {
const status = fromJS(require('soapbox/__fixtures__/status-unordered-mentions.json')); const status = require('soapbox/__fixtures__/status-unordered-mentions.json');
const expected = ['NEETzsche', 'alex', 'Lumeinshin', 'sneeden']; const expected = ['NEETzsche', 'alex', 'Lumeinshin', 'sneeden'];
@ -30,7 +30,7 @@ describe('normalizeStatus()', () => {
}); });
it('adds mention to self in self-reply on Mastodon', () => { it('adds mention to self in self-reply on Mastodon', () => {
const status = fromJS(require('soapbox/__fixtures__/mastodon-reply-to-self.json')); const status = require('soapbox/__fixtures__/mastodon-reply-to-self.json');
const expected = { const expected = {
id: '106801667066418367', id: '106801667066418367',
@ -48,7 +48,7 @@ describe('normalizeStatus()', () => {
}); });
it('normalizes mentions with only acct', () => { it('normalizes mentions with only acct', () => {
const status = fromJS({ mentions: [{ acct: 'alex@gleasonator.com' }] }); const status = { mentions: [{ acct: 'alex@gleasonator.com' }] };
const expected = [{ const expected = [{
id: '', id: '',
@ -63,7 +63,7 @@ describe('normalizeStatus()', () => {
}); });
it('normalizes Mitra attachments', () => { it('normalizes Mitra attachments', () => {
const status = fromJS(require('soapbox/__fixtures__/mitra-status-with-attachments.json')); const status = require('soapbox/__fixtures__/mitra-status-with-attachments.json');
const expected = [{ const expected = [{
id: '017eeb0e-e5df-30a4-77a7-a929145cb836', id: '017eeb0e-e5df-30a4-77a7-a929145cb836',
@ -97,7 +97,7 @@ describe('normalizeStatus()', () => {
}); });
it('leaves Pleroma attachments alone', () => { it('leaves Pleroma attachments alone', () => {
const status = fromJS(require('soapbox/__fixtures__/pleroma-status-with-attachments.json')); const status = require('soapbox/__fixtures__/pleroma-status-with-attachments.json');
const result = normalizeStatus(status).media_attachments; const result = normalizeStatus(status).media_attachments;
expect(result.size).toBe(4); expect(result.size).toBe(4);
@ -108,15 +108,15 @@ describe('normalizeStatus()', () => {
}); });
it('normalizes Pleroma quote post', () => { it('normalizes Pleroma quote post', () => {
const status = fromJS(require('soapbox/__fixtures__/pleroma-quote-post.json')); const status = require('soapbox/__fixtures__/pleroma-quote-post.json');
const result = normalizeStatus(status); const result = normalizeStatus(status);
expect(result.quote).toEqual(status.getIn(['pleroma', 'quote'])); expect(result.quote).toEqual(fromJS(status.pleroma.quote));
expect(result.pleroma.get('quote')).toBe(undefined); expect(result.pleroma.get('quote')).toBe(undefined);
}); });
it('normalizes GoToSocial status', () => { it('normalizes GoToSocial status', () => {
const status = fromJS(require('soapbox/__fixtures__/gotosocial-status.json')); const status = require('soapbox/__fixtures__/gotosocial-status.json');
const result = normalizeStatus(status); const result = normalizeStatus(status);
// Adds missing fields // Adds missing fields
@ -132,7 +132,7 @@ describe('normalizeStatus()', () => {
}); });
it('normalizes Friendica status', () => { it('normalizes Friendica status', () => {
const status = fromJS(require('soapbox/__fixtures__/friendica-status.json')); const status = require('soapbox/__fixtures__/friendica-status.json');
const result = normalizeStatus(status); const result = normalizeStatus(status);
// Adds missing fields // Adds missing fields
@ -145,7 +145,7 @@ describe('normalizeStatus()', () => {
}); });
it('normalizes poll and poll options', () => { it('normalizes poll and poll options', () => {
const status = fromJS({ poll: { options: [{ title: 'Apples' }] } }); const status = { poll: { options: [{ title: 'Apples' }] } };
const result = normalizeStatus(status); const result = normalizeStatus(status);
const expected = { const expected = {
@ -166,7 +166,7 @@ describe('normalizeStatus()', () => {
}); });
it('normalizes a Pleroma logged-out poll', () => { it('normalizes a Pleroma logged-out poll', () => {
const status = fromJS(require('soapbox/__fixtures__/pleroma-status-with-poll.json')); const status = require('soapbox/__fixtures__/pleroma-status-with-poll.json');
const result = normalizeStatus(status); const result = normalizeStatus(status);
// Adds logged-in fields // Adds logged-in fields
@ -175,7 +175,7 @@ describe('normalizeStatus()', () => {
}); });
it('normalizes poll with emojis', () => { it('normalizes poll with emojis', () => {
const status = fromJS(require('soapbox/__fixtures__/pleroma-status-with-poll-with-emojis.json')); const status = require('soapbox/__fixtures__/pleroma-status-with-poll-with-emojis.json');
const result = normalizeStatus(status); const result = normalizeStatus(status);
// Emojifies poll options // Emojifies poll options
@ -188,7 +188,7 @@ describe('normalizeStatus()', () => {
}); });
it('normalizes a card', () => { it('normalizes a card', () => {
const status = fromJS(require('soapbox/__fixtures__/status-with-card.json')); const status = require('soapbox/__fixtures__/status-with-card.json');
const result = normalizeStatus(status); const result = normalizeStatus(status);
expect(ImmutableRecord.isRecord(result.card)).toBe(true); expect(ImmutableRecord.isRecord(result.card)).toBe(true);

View File

@ -8,6 +8,7 @@ import {
Map as ImmutableMap, Map as ImmutableMap,
List as ImmutableList, List as ImmutableList,
Record as ImmutableRecord, Record as ImmutableRecord,
fromJS,
} from 'immutable'; } from 'immutable';
import emojify from 'soapbox/features/emoji/emoji'; import emojify from 'soapbox/features/emoji/emoji';
@ -17,7 +18,7 @@ import { unescapeHTML } from 'soapbox/utils/html';
import { mergeDefined, makeEmojiMap } from 'soapbox/utils/normalizers'; import { mergeDefined, makeEmojiMap } from 'soapbox/utils/normalizers';
// https://docs.joinmastodon.org/entities/account/ // https://docs.joinmastodon.org/entities/account/
const AccountRecord = ImmutableRecord({ export const AccountRecord = ImmutableRecord({
acct: '', acct: '',
avatar: '', avatar: '',
avatar_static: '', avatar_static: '',
@ -56,7 +57,7 @@ const AccountRecord = ImmutableRecord({
}); });
// https://docs.joinmastodon.org/entities/field/ // https://docs.joinmastodon.org/entities/field/
const FieldRecord = ImmutableRecord({ export const FieldRecord = ImmutableRecord({
name: '', name: '',
value: '', value: '',
verified_at: null, verified_at: null,
@ -181,9 +182,9 @@ const addInternalFields = (account: ImmutableMap<string, any>) => {
}); });
}; };
export const normalizeAccount = (account: ImmutableMap<string, any>): IAccount => { export const normalizeAccount = (account: Record<string, any>): IAccount => {
return AccountRecord( return AccountRecord(
account.withMutations(account => { ImmutableMap(fromJS(account)).withMutations(account => {
normalizePleromaLegacyFields(account); normalizePleromaLegacyFields(account);
normalizeEmojis(account); normalizeEmojis(account);
normalizeAvatar(account); normalizeAvatar(account);

View File

@ -6,12 +6,13 @@
import { import {
Map as ImmutableMap, Map as ImmutableMap,
Record as ImmutableRecord, Record as ImmutableRecord,
fromJS,
} from 'immutable'; } from 'immutable';
import { mergeDefined } from 'soapbox/utils/normalizers'; import { mergeDefined } from 'soapbox/utils/normalizers';
// https://docs.joinmastodon.org/entities/attachment/ // https://docs.joinmastodon.org/entities/attachment/
const AttachmentRecord = ImmutableRecord({ export const AttachmentRecord = ImmutableRecord({
blurhash: undefined, blurhash: undefined,
description: '', description: '',
id: '', id: '',
@ -29,7 +30,7 @@ const AttachmentRecord = ImmutableRecord({
}); });
// Ensure attachments have required fields // Ensure attachments have required fields
export const normalizeAttachment = (attachment: ImmutableMap<string, any>) => { const normalizeUrls = (attachment: ImmutableMap<string, any>) => {
const url = [ const url = [
attachment.get('url'), attachment.get('url'),
attachment.get('preview_url'), attachment.get('preview_url'),
@ -41,5 +42,11 @@ export const normalizeAttachment = (attachment: ImmutableMap<string, any>) => {
preview_url: url, preview_url: url,
}); });
return AttachmentRecord(attachment.mergeWith(mergeDefined, base)); return attachment.mergeWith(mergeDefined, base);
};
export const normalizeAttachment = (attachment: Record<string, any>) => {
return AttachmentRecord(
normalizeUrls(ImmutableMap(fromJS(attachment))),
);
}; };

View File

@ -3,10 +3,10 @@
* Converts API cards into our internal format. * Converts API cards into our internal format.
* @see {@link https://docs.joinmastodon.org/entities/card/} * @see {@link https://docs.joinmastodon.org/entities/card/}
*/ */
import { Record as ImmutableRecord, Map as ImmutableMap } from 'immutable'; import { Record as ImmutableRecord, Map as ImmutableMap, fromJS } from 'immutable';
// https://docs.joinmastodon.org/entities/card/ // https://docs.joinmastodon.org/entities/card/
const CardRecord = ImmutableRecord({ export const CardRecord = ImmutableRecord({
author_name: '', author_name: '',
author_url: '', author_url: '',
blurhash: null, blurhash: null,
@ -23,6 +23,8 @@ const CardRecord = ImmutableRecord({
width: 0, width: 0,
}); });
export const normalizeCard = (card: ImmutableMap<string, any>) => { export const normalizeCard = (card: Record<string, any>) => {
return CardRecord(card); return CardRecord(
ImmutableMap(fromJS(card)),
);
}; };

View File

@ -3,10 +3,10 @@
* Converts API emojis into our internal format. * Converts API emojis into our internal format.
* @see {@link https://docs.joinmastodon.org/entities/emoji/} * @see {@link https://docs.joinmastodon.org/entities/emoji/}
*/ */
import { Record as ImmutableRecord, Map as ImmutableMap } from 'immutable'; import { Record as ImmutableRecord, Map as ImmutableMap, fromJS } from 'immutable';
// https://docs.joinmastodon.org/entities/emoji/ // https://docs.joinmastodon.org/entities/emoji/
const EmojiRecord = ImmutableRecord({ export const EmojiRecord = ImmutableRecord({
category: '', category: '',
shortcode: '', shortcode: '',
static_url: '', static_url: '',
@ -14,6 +14,8 @@ const EmojiRecord = ImmutableRecord({
visible_in_picker: true, visible_in_picker: true,
}); });
export const normalizeEmoji = (emoji: ImmutableMap<string, any>) => { export const normalizeEmoji = (emoji: Record<string, any>) => {
return EmojiRecord(emoji); return EmojiRecord(
ImmutableMap(fromJS(emoji)),
);
}; };

View File

@ -0,0 +1,9 @@
export { AccountRecord, FieldRecord, normalizeAccount } from './account';
export { AttachmentRecord, normalizeAttachment } from './attachment';
export { CardRecord, normalizeCard } from './card';
export { EmojiRecord, normalizeEmoji } from './emoji';
export { InstanceRecord, normalizeInstance } from './instance';
export { MentionRecord, normalizeMention } from './mention';
export { NotificationRecord, normalizeNotification } from './notification';
export { PollRecord, PollOptionRecord, normalizePoll } from './poll';
export { StatusRecord, normalizeStatus } from './status';

View File

@ -7,6 +7,7 @@ import {
Map as ImmutableMap, Map as ImmutableMap,
List as ImmutableList, List as ImmutableList,
Record as ImmutableRecord, Record as ImmutableRecord,
fromJS,
} from 'immutable'; } from 'immutable';
import { parseVersion, PLEROMA } from 'soapbox/utils/features'; import { parseVersion, PLEROMA } from 'soapbox/utils/features';
@ -15,7 +16,7 @@ import { isNumber } from 'soapbox/utils/numbers';
// Use Mastodon defaults // Use Mastodon defaults
// https://docs.joinmastodon.org/entities/instance/ // https://docs.joinmastodon.org/entities/instance/
const InstanceRecord = ImmutableRecord({ export const InstanceRecord = ImmutableRecord({
approval_required: false, approval_required: false,
contact_account: ImmutableMap(), contact_account: ImmutableMap(),
configuration: ImmutableMap({ configuration: ImmutableMap({
@ -84,12 +85,12 @@ const pleromaToMastodonConfig = (instance: ImmutableMap<string, any>) => {
const getAttachmentLimit = (software: string) => software === PLEROMA ? Infinity : 4; const getAttachmentLimit = (software: string) => software === PLEROMA ? Infinity : 4;
// Normalize instance (Pleroma, Mastodon, etc.) to Mastodon's format // Normalize instance (Pleroma, Mastodon, etc.) to Mastodon's format
export const normalizeInstance = (instance: ImmutableMap<string, any>) => { export const normalizeInstance = (instance: Record<string, any>) => {
const { software } = parseVersion(instance.get('version'));
const mastodonConfig = pleromaToMastodonConfig(instance);
return InstanceRecord( return InstanceRecord(
instance.withMutations(instance => { ImmutableMap(fromJS(instance)).withMutations((instance: ImmutableMap<string, any>) => {
const { software } = parseVersion(instance.get('version'));
const mastodonConfig = pleromaToMastodonConfig(instance);
// Merge configuration // Merge configuration
instance.update('configuration', ImmutableMap(), configuration => ( instance.update('configuration', ImmutableMap(), configuration => (
configuration.mergeDeepWith(mergeDefined, mastodonConfig) configuration.mergeDeepWith(mergeDefined, mastodonConfig)

View File

@ -3,22 +3,19 @@
* Converts API mentions into our internal format. * Converts API mentions into our internal format.
* @see {@link https://docs.joinmastodon.org/entities/mention/} * @see {@link https://docs.joinmastodon.org/entities/mention/}
*/ */
import { import { Record as ImmutableRecord } from 'immutable';
Map as ImmutableMap,
Record as ImmutableRecord,
} from 'immutable';
import { normalizeAccount } from 'soapbox/normalizers/account'; import { normalizeAccount } from 'soapbox/normalizers/account';
// https://docs.joinmastodon.org/entities/mention/ // https://docs.joinmastodon.org/entities/mention/
const MentionRecord = ImmutableRecord({ export const MentionRecord = ImmutableRecord({
id: '', id: '',
acct: '', acct: '',
username: '', username: '',
url: '', url: '',
}); });
export const normalizeMention = (mention: ImmutableMap<string, any>) => { export const normalizeMention = (mention: Record<string, any>) => {
// Simply normalize it as an account then cast it as a mention ¯\_(ツ)_/¯ // Simply normalize it as an account then cast it as a mention ¯\_(ツ)_/¯
return MentionRecord(normalizeAccount(mention)); return MentionRecord(normalizeAccount(mention));
}; };

View File

@ -6,10 +6,11 @@
import { import {
Map as ImmutableMap, Map as ImmutableMap,
Record as ImmutableRecord, Record as ImmutableRecord,
fromJS,
} from 'immutable'; } from 'immutable';
// https://docs.joinmastodon.org/entities/notification/ // https://docs.joinmastodon.org/entities/notification/
const NotificationRecord = ImmutableRecord({ export const NotificationRecord = ImmutableRecord({
account: null, account: null,
chat_message: null, // pleroma:chat_mention chat_message: null, // pleroma:chat_mention
created_at: new Date(), created_at: new Date(),
@ -20,6 +21,8 @@ const NotificationRecord = ImmutableRecord({
type: '', type: '',
}); });
export const normalizeNotification = (notification: ImmutableMap<string, any>) => { export const normalizeNotification = (notification: Record<string, any>) => {
return NotificationRecord(notification); return NotificationRecord(
ImmutableMap(fromJS(notification)),
);
}; };

View File

@ -8,6 +8,7 @@ import {
Map as ImmutableMap, Map as ImmutableMap,
List as ImmutableList, List as ImmutableList,
Record as ImmutableRecord, Record as ImmutableRecord,
fromJS,
} from 'immutable'; } from 'immutable';
import emojify from 'soapbox/features/emoji/emoji'; import emojify from 'soapbox/features/emoji/emoji';
@ -15,7 +16,7 @@ import { normalizeEmoji } from 'soapbox/normalizers/emoji';
import { makeEmojiMap } from 'soapbox/utils/normalizers'; import { makeEmojiMap } from 'soapbox/utils/normalizers';
// https://docs.joinmastodon.org/entities/poll/ // https://docs.joinmastodon.org/entities/poll/
const PollRecord = ImmutableRecord({ export const PollRecord = ImmutableRecord({
emojis: ImmutableList(), emojis: ImmutableList(),
expired: false, expired: false,
expires_at: new Date(), expires_at: new Date(),
@ -29,7 +30,7 @@ const PollRecord = ImmutableRecord({
}); });
// Sub-entity of Poll // Sub-entity of Poll
const PollOptionRecord = ImmutableRecord({ export const PollOptionRecord = ImmutableRecord({
title: '', title: '',
votes_count: 0, votes_count: 0,
@ -76,9 +77,9 @@ const normalizePollVoted = (poll: ImmutableMap<string, any>) => {
}); });
}; };
export const normalizePoll = (poll: ImmutableMap<string, any>) => { export const normalizePoll = (poll: Record<string, any>) => {
return PollRecord( return PollRecord(
poll.withMutations((poll: ImmutableMap<string, any>) => { ImmutableMap(fromJS(poll)).withMutations((poll: ImmutableMap<string, any>) => {
normalizeEmojis(poll); normalizeEmojis(poll);
normalizePollOptions(poll); normalizePollOptions(poll);
normalizePollOwnVotes(poll); normalizePollOwnVotes(poll);

View File

@ -7,6 +7,7 @@ import {
Map as ImmutableMap, Map as ImmutableMap,
List as ImmutableList, List as ImmutableList,
Record as ImmutableRecord, Record as ImmutableRecord,
fromJS,
} from 'immutable'; } from 'immutable';
import { normalizeAttachment } from 'soapbox/normalizers/attachment'; import { normalizeAttachment } from 'soapbox/normalizers/attachment';
@ -17,7 +18,7 @@ import { normalizePoll } from 'soapbox/normalizers/poll';
import { IStatus } from 'soapbox/types'; import { IStatus } from 'soapbox/types';
// https://docs.joinmastodon.org/entities/status/ // https://docs.joinmastodon.org/entities/status/
const StatusRecord = ImmutableRecord({ export const StatusRecord = ImmutableRecord({
account: null, account: null,
application: null, application: null,
bookmarked: false, bookmarked: false,
@ -135,9 +136,9 @@ const fixQuote = (status: ImmutableMap<string, any>) => {
}); });
}; };
export const normalizeStatus = (status: ImmutableMap<string, any>): IStatus => { export const normalizeStatus = (status: Record<string, any>): IStatus => {
return StatusRecord( return StatusRecord(
status.withMutations(status => { ImmutableMap(fromJS(status)).withMutations(status => {
normalizeAttachments(status); normalizeAttachments(status);
normalizeMentions(status); normalizeMentions(status);
normalizeEmojis(status); normalizeEmojis(status);

View File

@ -46,7 +46,7 @@ const minifyAccount = account => {
}; };
const fixAccount = (state, account) => { const fixAccount = (state, account) => {
const normalized = minifyAccount(normalizeAccount(fromJS(account))); const normalized = minifyAccount(normalizeAccount(account));
return state.set(account.id, normalized); return state.set(account.id, normalized);
}; };
@ -119,7 +119,7 @@ const removePermission = (state, accountIds, permissionGroup) => {
}); });
}; };
const buildAccount = adminUser => normalizeAccount(fromJS({ const buildAccount = adminUser => normalizeAccount({
id: adminUser.get('id'), id: adminUser.get('id'),
username: adminUser.get('nickname').split('@')[0], username: adminUser.get('nickname').split('@')[0],
acct: adminUser.get('nickname'), acct: adminUser.get('nickname'),
@ -142,7 +142,7 @@ const buildAccount = adminUser => normalizeAccount(fromJS({
}, },
}, },
should_refetch: true, should_refetch: true,
})); });
const mergeAdminUser = (account, adminUser) => { const mergeAdminUser = (account, adminUser) => {
return account.withMutations(account => { return account.withMutations(account => {

View File

@ -116,7 +116,7 @@ const reducers = {
}; };
// Build a default state from all reducers: it has the key and `undefined` // Build a default state from all reducers: it has the key and `undefined`
const StateRecord = ImmutableRecord( export const StateRecord = ImmutableRecord(
Object.keys(reducers).reduce((params, reducer) => { Object.keys(reducers).reduce((params, reducer) => {
params[reducer] = undefined; params[reducer] = undefined;
return params; return params;

View File

@ -1,4 +1,4 @@
import { Map as ImmutableMap, fromJS } from 'immutable'; import { Map as ImmutableMap } from 'immutable';
import { POLLS_IMPORT } from 'soapbox/actions/importer'; import { POLLS_IMPORT } from 'soapbox/actions/importer';
import { normalizeStatus } from 'soapbox/normalizers/status'; import { normalizeStatus } from 'soapbox/normalizers/status';
@ -6,7 +6,7 @@ import { normalizeStatus } from 'soapbox/normalizers/status';
// HOTFIX: Convert the poll into a fake status to normalize it... // HOTFIX: Convert the poll into a fake status to normalize it...
// TODO: get rid of POLLS_IMPORT and use STATUS_IMPORT here. // TODO: get rid of POLLS_IMPORT and use STATUS_IMPORT here.
const normalizePoll = poll => { const normalizePoll = poll => {
const status = fromJS({ poll }); const status = { poll };
return normalizeStatus(status).poll; return normalizeStatus(status).poll;
}; };