Something went wrong. Try again.
Browser extension: detect and subscribe to standard.site publications on ATProto
Something went wrong. Try again.
8.4 kB · 229 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230import { describe, expect, it } from 'vitest'import { DEFAULT_READER_ID, READERS, catalogGaps, docLinksBackTo, docUrl, migrateReaderId, pubSiteUrl, pubUrl,} from './readers'import type { DocInfo, PubInfo } from './types'
const pub: PubInfo = { uri: 'at://did:plc:abc123/site.standard.publication/3kpubrkey', did: 'did:plc:abc123', pds: 'https://pds.example.com', record: { $type: 'site.standard.publication', url: 'https://blog.example.com', name: 'Blog' }, verified: true,}
const doc: DocInfo = { uri: 'at://did:plc:abc123/site.standard.document/3kdocrkey', record: { $type: 'site.standard.document', site: pub.uri, title: 'Post', publishedAt: '2026-01-01T00:00:00Z', },}
describe('pubUrl', () => { it('builds the Standard Reader /p/{did}/{rkey} URL from the publication at-uri', () => { expect(pubUrl('standardReader', pub)).toBe( 'https://standard-reader.app/p/did:plc:abc123/3kpubrkey', ) })
it('returns null for Standard Reader when the publication uri has no parseable rkey', () => { expect(pubUrl('standardReader', { ...pub, uri: 'at://did:plc:abc123' })).toBeNull() })
it('builds the Leaflet /lish/{did}/{rkey} URL from the publication at-uri', () => { expect(pubUrl('leaflet', pub)).toBe( 'https://leaflet.pub/lish/did:plc:abc123/3kpubrkey', ) })
it('returns null for Leaflet when the publication uri has no parseable rkey', () => { expect(pubUrl('leaflet', { ...pub, uri: 'at://did:plc:abc123' })).toBeNull() })
it('builds the PDSls URL from the raw at-uri', () => { expect(pubUrl('pdsls', pub)).toBe(`https://pdsls.dev/${pub.uri}`) })
it('returns null for an unknown reader id', () => { expect(pubUrl('nonexistent', pub)).toBeNull() })})
describe('docUrl', () => { it('builds the Standard Reader /a/{did}/{rkey} URL from the document at-uri', () => { expect(docUrl('standardReader', pub, doc)).toBe( 'https://standard-reader.app/a/did:plc:abc123/3kdocrkey', ) })
it('returns null for Standard Reader when the document uri is unparseable', () => { expect(docUrl('standardReader', pub, { ...doc, uri: 'at://did:plc:abc123' })).toBeNull() })
it('builds the article under its publication for Leaflet', () => { expect(docUrl('leaflet', pub, doc)).toBe( `https://leaflet.pub/lish/${pub.did}/3kpubrkey/3kdocrkey`, ) })
it('returns null for Leaflet when the publication uri is unparseable', () => { expect(docUrl('leaflet', { ...pub, uri: 'at://did:plc:abc123' }, doc)).toBeNull() })
it('builds document URLs for readers that support them', () => { expect(docUrl('pdsls', pub, doc)).toBe(`https://pdsls.dev/${doc.uri}`) })
it('returns null for an unknown reader id', () => { expect(docUrl('nonexistent', pub, doc)).toBeNull() })})
describe('docLinksBackTo', () => { // A textContent-only record: no structured `content`, so Standard Reader // 307s its article URL to publication url + path. const plainDoc: DocInfo = { ...doc, record: { ...doc.record, path: '/writing/post/' }, } const page = 'https://blog.example.com/writing/post/'
it('detects the self-link: no content, canonical url is the page itself', () => { expect(docLinksBackTo(pub, plainDoc, page)).toBe(true) })
it('ignores trailing slash, query, and fragment differences', () => { expect(docLinksBackTo(pub, plainDoc, 'https://blog.example.com/writing/post?utm=x#top')).toBe( true, ) })
it('does not trigger with structured content in the record', () => { const richDoc = { ...plainDoc, record: { ...plainDoc.record, content: { $type: 'x' } } } expect(docLinksBackTo(pub, richDoc, page)).toBe(false) })
it('does not trigger from a different page', () => { expect(docLinksBackTo(pub, plainDoc, 'https://blog.example.com/writing/other/')).toBe(false) expect(docLinksBackTo(pub, plainDoc, 'https://elsewhere.example.com/writing/post/')).toBe(false) })
it('does not trigger without a document path', () => { expect(docLinksBackTo(pub, doc, page)).toBe(false) })
it('concatenates a non-root publication base with the path, like the reader does', () => { const nested = { ...pub, record: { ...pub.record, url: 'https://example.com/blog/' } } expect(docLinksBackTo(nested, plainDoc, 'https://example.com/blog/writing/post/')).toBe(true) expect(docLinksBackTo(nested, plainDoc, 'https://example.com/writing/post/')).toBe(false) })
it('makes the standard docUrl fall back to null on the canonical page', () => { expect(docUrl('standardReader', pub, plainDoc, page)).toBeNull() // Off the canonical page (or with no page context) the article link stays. expect(docUrl('standardReader', pub, plainDoc, 'https://blog.example.com/')).toMatch( /^https:\/\/standard-reader\.app\/a\//, ) expect(docUrl('standardReader', pub, plainDoc)).toMatch(/^https:\/\/standard-reader\.app\/a\//) })})
describe('pubSiteUrl', () => { it('returns the record url when it is http(s)', () => { expect(pubSiteUrl(pub)).toBe('https://blog.example.com/') })
it('returns null for non-http schemes', () => { const evil = { ...pub, record: { ...pub.record, url: 'javascript:alert(1)' } } expect(pubSiteUrl(evil)).toBeNull() })
it('returns null for an unparseable url', () => { const bad = { ...pub, record: { ...pub.record, url: 'not a url' } } expect(pubSiteUrl(bad)).toBeNull() })})
describe('READERS', () => { it('every reader can show the publication or the article, and says which', () => { for (const r of READERS) { const shows = [r.pubUrl(pub), r.docUrl(pub, doc)].filter((u) => typeof u === 'string') // A reader that can render neither has no reason to be in the list. expect(shows.length, r.id).toBeGreaterThan(0) for (const url of shows) expect(url, r.id).toMatch(/^https:\/\//) } })
it('offers the readers confirmed against the live services, in catalog order', () => { expect(READERS.map((r) => r.id)).toEqual([ 'leaflet', 'standardReader', 'pdsls', 'taproot', ]) })
// The rule the menu depends on: a reader that works on a publication but // not an article (or the reverse) shows up as a greyed row whose reason is // invisible, which is why Anisota is not offered. it('offers only readers that open both a publication and an article', () => { for (const reader of READERS) { expect(reader.pubUrl(pub), `${reader.id} publication`).toMatch(/^https:\/\//) expect(reader.docUrl(pub, doc), `${reader.id} article`).toMatch(/^https:\/\//) } })
it('carries no catalogued standard.site reader we have not checked', () => { // Fails after a @aturi.to/waypoints bump that adds one: the catalog can // supply the list, but only a person who opened the link can say it works. expect(catalogGaps()).toEqual([]) })
it('keeps an older install pointed at the reader it chose', () => { expect(migrateReaderId('standard')).toBe('standardReader') expect(READERS.some((r) => r.id === migrateReaderId('standard'))).toBe(true) // Ids that never changed pass through, including ones we do not know. expect(migrateReaderId('pdsls')).toBe('pdsls') expect(migrateReaderId('nonexistent')).toBe('nonexistent') })
it('reader ids are unique', () => { expect(new Set(READERS.map((r) => r.id)).size).toBe(READERS.length) })
it('DEFAULT_READER_ID refers to an existing reader', () => { expect(READERS.some((r) => r.id === DEFAULT_READER_ID)).toBe(true) })
// Existence of the files themselves is checked post-build by // scripts/verify-dist.mjs, which scans built JS for /vendored/ references. it('every reader icon is an extension-rooted vendored path', () => { for (const r of READERS) { expect(r.icon, r.id).toMatch(/^\/vendored\/[\w.-]+\.(png|svg)$/) } })})
describe('describe', () => { it('passes on the catalog’s own words for what a reader does', () => { const pdsls = READERS.find((r) => r.id === 'pdsls')! expect(pdsls.describe('site.standard.document')).toMatch(/pdsls\.dev/) })
it('varies by record type for the readers whose description does', () => { const standard = READERS.find((r) => r.id === 'standardReader')! expect(standard.describe('site.standard.document')).not.toBe( standard.describe('app.bsky.feed.post'), ) })})