diff --git a/app/soapbox/__fixtures__/status-with-card.json b/app/soapbox/__fixtures__/status-with-card.json
new file mode 100644
index 000000000..da2f83b94
--- /dev/null
+++ b/app/soapbox/__fixtures__/status-with-card.json
@@ -0,0 +1,210 @@
+{
+ "account": {
+ "acct": "alex",
+ "avatar": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
+ "avatar_static": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
+ "bot": false,
+ "created_at": "2020-01-08T01:25:43.000Z",
+ "display_name": "Alex Gleason",
+ "emojis": [
+ {
+ "shortcode": "soapbox",
+ "static_url": "https://gleasonator.com/emoji/Gleasonator/soapbox.png",
+ "url": "https://gleasonator.com/emoji/Gleasonator/soapbox.png",
+ "visible_in_picker": false
+ }
+ ],
+ "fields": [
+ {
+ "name": "Website",
+ "value": "https://alexgleason.me"
+ },
+ {
+ "name": "Soapbox :soapbox:",
+ "value": "https://soapbox.pub"
+ },
+ {
+ "name": "Email",
+ "value": "alex@alexgleason.me"
+ },
+ {
+ "name": "Gender identity",
+ "value": "Soyboy"
+ },
+ {
+ "name": "Donate (PayPal)",
+ "value": "https://paypal.me/gleasonator"
+ },
+ {
+ "name": "$BTC",
+ "value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
+ },
+ {
+ "name": "$ETH",
+ "value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
+ },
+ {
+ "name": "$DOGE",
+ "value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
+ },
+ {
+ "name": "$XMR",
+ "value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
+ }
+ ],
+ "followers_count": 2476,
+ "following_count": 1584,
+ "fqn": "alex@gleasonator.com",
+ "header": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
+ "header_static": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
+ "id": "9v5bmRalQvjOy0ECcC",
+ "last_status_at": "2022-03-12T16:35:10",
+ "locked": false,
+ "note": "I create Fediverse software that empowers people online. :soapbox:
I'm vegan btw
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.",
+ "pleroma": {
+ "accepts_chat_messages": true,
+ "also_known_as": [
+ "https://mitra.social/users/alex"
+ ],
+ "ap_id": "https://gleasonator.com/users/alex",
+ "background_image": null,
+ "birthday": "1993-07-03",
+ "favicon": "https://gleasonator.com/favicon.png",
+ "hide_favorites": true,
+ "hide_followers": false,
+ "hide_followers_count": false,
+ "hide_follows": false,
+ "hide_follows_count": false,
+ "is_admin": true,
+ "is_confirmed": true,
+ "is_moderator": false,
+ "is_suggested": true,
+ "relationship": {},
+ "skip_thread_containment": false,
+ "tags": []
+ },
+ "source": {
+ "fields": [
+ {
+ "name": "Website",
+ "value": "https://alexgleason.me"
+ },
+ {
+ "name": "Soapbox :soapbox:",
+ "value": "https://soapbox.pub"
+ },
+ {
+ "name": "Email",
+ "value": "alex@alexgleason.me"
+ },
+ {
+ "name": "Gender identity",
+ "value": "Soyboy"
+ },
+ {
+ "name": "Donate (PayPal)",
+ "value": "https://paypal.me/gleasonator"
+ },
+ {
+ "name": "$BTC",
+ "value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
+ },
+ {
+ "name": "$ETH",
+ "value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
+ },
+ {
+ "name": "$DOGE",
+ "value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
+ },
+ {
+ "name": "$XMR",
+ "value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
+ }
+ ],
+ "note": "I create Fediverse software that empowers people online. :soapbox:\r\n\r\nI'm vegan btw\r\n\r\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.",
+ "pleroma": {
+ "actor_type": "Person",
+ "discoverable": false
+ },
+ "sensitive": false
+ },
+ "statuses_count": 23674,
+ "url": "https://gleasonator.com/users/alex",
+ "username": "alex"
+ },
+ "application": null,
+ "bookmarked": false,
+ "card": {
+ "author_name": "Alex Gleason",
+ "author_url": "https://soapbox.pub/author/alex/",
+ "blurhash": null,
+ "description": "On cryptocurrency I’ve always believed integrated donations would be a necessary part of the Fediverse. Admins do all the heavy lifting; it’s a thankless job. Meanwhile users want to help secure their new online home, but feel powerless to do so. I have been running an experimental payment platform based on Stripe alongside my Soapbox […]",
+ "embed_url": null,
+ "height": 338,
+ "html": "",
+ "image": "https://gleasonator.com/proxy/L2kUi5uxMdoC6LYYrnAdlJviPGQ/aHR0cHM6Ly9tZWRpYS5zb2FwYm94LnB1Yi91cGxvYWRzLzIwMjEvMDcvdi0xLTMtdGh1bWIucG5n/v-1-3-thumb.png",
+ "provider_name": "Soapbox",
+ "provider_url": "https://soapbox.pub",
+ "title": "Soapbox FE v1.3: The Crypto Release - Soapbox",
+ "type": "link",
+ "url": "https://soapbox.pub/blog/soapbox-fe-v1.3-cryptocurrency-release/",
+ "width": 600
+ },
+ "content": "
Soapbox FE v1.3 released. Read about it here: https://soapbox.pub/blog/soapbox-fe-v1.3-cryptocurrency-release/
Enjoy!
", + "created_at": "2021-07-02T20:49:39.000Z", + "emojis": [], + "favourited": false, + "favourites_count": 29, + "id": "A8tEMYF2GNnfPcL4dc", + "in_reply_to_account_id": null, + "in_reply_to_id": null, + "language": null, + "media_attachments": [], + "mentions": [], + "muted": false, + "pinned": true, + "pleroma": { + "content": { + "text/plain": "Soapbox FE v1.3 released. Read about it here: https://soapbox.pub/blog/soapbox-fe-v1.3-cryptocurrency-release/Enjoy!" + }, + "conversation_id": "16496668", + "direct_conversation_id": null, + "emoji_reactions": [ + { + "count": 5, + "me": false, + "name": "❤️" + }, + { + "count": 1, + "me": false, + "name": "👍" + } + ], + "expires_at": null, + "in_reply_to_account_acct": null, + "local": true, + "parent_visible": false, + "pinned_at": "2021-11-23T01:38:44.000Z", + "quote": null, + "quote_url": null, + "quote_visible": false, + "spoiler_text": { + "text/plain": "" + }, + "thread_muted": false + }, + "poll": null, + "reblog": null, + "reblogged": false, + "reblogs_count": 16, + "replies_count": 7, + "sensitive": false, + "spoiler_text": "", + "tags": [], + "text": null, + "uri": "https://gleasonator.com/objects/3eabaf63-47f4-4314-9ddb-ce7dbf46b393", + "url": "https://gleasonator.com/notice/A8tEMYF2GNnfPcL4dc", + "visibility": "public" +} diff --git a/app/soapbox/normalizers/__tests__/card-test.js b/app/soapbox/normalizers/__tests__/card-test.js new file mode 100644 index 000000000..e8ac120b0 --- /dev/null +++ b/app/soapbox/normalizers/__tests__/card-test.js @@ -0,0 +1,14 @@ +import { Record as ImmutableRecord, fromJS } from 'immutable'; + +import { normalizeCard } from '../card'; + +describe('normalizeCard()', () => { + it('adds base fields', () => { + const card = fromJS({}); + const result = normalizeCard(card); + + expect(ImmutableRecord.isRecord(result)).toBe(true); + expect(result.type).toEqual('link'); + expect(result.url).toEqual(''); + }); +}); diff --git a/app/soapbox/normalizers/__tests__/status-test.js b/app/soapbox/normalizers/__tests__/status-test.js index fc8b351f2..2824615cc 100644 --- a/app/soapbox/normalizers/__tests__/status-test.js +++ b/app/soapbox/normalizers/__tests__/status-test.js @@ -186,4 +186,13 @@ describe('normalizeStatus()', () => { expect(ImmutableRecord.isRecord(result.poll.emojis.get(0))).toBe(true); expect(result.poll.emojis.get(1).shortcode).toEqual('soapbox'); }); + + it('normalizes a card', () => { + const status = fromJS(require('soapbox/__fixtures__/status-with-card.json')); + const result = normalizeStatus(status); + + expect(ImmutableRecord.isRecord(result.card)).toBe(true); + expect(result.card.type).toEqual('link'); + expect(result.card.provider_url).toEqual('https://soapbox.pub'); + }); }); diff --git a/app/soapbox/normalizers/card.ts b/app/soapbox/normalizers/card.ts new file mode 100644 index 000000000..c9ac76adb --- /dev/null +++ b/app/soapbox/normalizers/card.ts @@ -0,0 +1,28 @@ +/** + * Card normalizer: + * Converts API cards into our internal format. + * @see {@link https://docs.joinmastodon.org/entities/card/} + */ +import { Record as ImmutableRecord, Map as ImmutableMap } from 'immutable'; + +// https://docs.joinmastodon.org/entities/card/ +const CardRecord = ImmutableRecord({ + author_name: '', + author_url: '', + blurhash: null, + description: '', + embed_url: '', + height: 0, + html: '', + image: null, + provider_name: '', + provider_url: '', + title: '', + type: 'link', + url: '', + width: 0, +}); + +export const normalizeCard = (card: ImmutableMap