26d793af95
* Improve `AtUriString` type an utilities * review comments * tidy * tidy * tidy * tidy * Apply suggestion from @matthieusieben * Apply suggestion from @matthieusieben * review comments
212 lines
8.1 KiB
TypeScript
212 lines
8.1 KiB
TypeScript
import { readFileSync } from 'node:fs'
|
|
import { describe, expect, test } from 'vitest'
|
|
import { InvalidAtUriError, assertAtUriString, isAtUriString } from '../src'
|
|
|
|
describe('valid interop', () => {
|
|
for (const value of readLines(
|
|
`${__dirname}/../../../interop-test-files/syntax/aturi_syntax_valid.txt`,
|
|
)) {
|
|
testValid(value)
|
|
}
|
|
})
|
|
|
|
describe('invalid interop', () => {
|
|
for (const value of readLines(
|
|
`${__dirname}/../../../interop-test-files/syntax/aturi_syntax_invalid.txt`,
|
|
)) {
|
|
testInvalid(value)
|
|
}
|
|
})
|
|
|
|
describe('custom cases', () => {
|
|
describe('valid spec basics', () => {
|
|
testValid('at://did:plc:asdf123')
|
|
testValid('at://user.bsky.social')
|
|
testValid('at://did:plc:asdf123/com.atproto.feed.post')
|
|
testValid('at://did:plc:asdf123/com.atproto.feed.post/record')
|
|
|
|
testValid('at://did:plc:asdf123#/frag')
|
|
testValid('at://user.bsky.social#/frag')
|
|
testValid('at://did:plc:asdf123/com.atproto.feed.post#/frag')
|
|
testValid('at://did:plc:asdf123/com.atproto.feed.post/record#/frag')
|
|
})
|
|
|
|
describe('invalid spec basics', () => {
|
|
testInvalid('a://did:plc:asdf123')
|
|
testInvalid('at//did:plc:asdf123')
|
|
testInvalid('at:/a/did:plc:asdf123')
|
|
testInvalid('at:/did:plc:asdf123')
|
|
testInvalid('AT://did:plc:asdf123')
|
|
testInvalid('http://did:plc:asdf123')
|
|
testInvalid('://did:plc:asdf123')
|
|
testInvalid('at:did:plc:asdf123')
|
|
testInvalid('at:/did:plc:asdf123')
|
|
testInvalid('at:///did:plc:asdf123')
|
|
testInvalid('at://:/did:plc:asdf123')
|
|
testInvalid('at:/ /did:plc:asdf123')
|
|
testInvalid('at://did:plc:asdf123 ')
|
|
testInvalid('at://did:plc:asdf123/ ')
|
|
testInvalid(' at://did:plc:asdf123')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post ')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post# ')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post#/ ')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post#/frag ')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post#fr ag')
|
|
testInvalid('//did:plc:asdf123')
|
|
testInvalid('at://name')
|
|
testInvalid('at://name.0')
|
|
testInvalid('at://diD:plc:asdf123')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.p@st')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.p$st')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.p%st')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.p&st')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.p()t')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed_post')
|
|
testInvalid('at://did:plc:asdf123/-com.atproto.feed.post')
|
|
testInvalid('at://did:plc:asdf@123/com.atproto.feed.post')
|
|
|
|
testInvalid('at://did:plc:asdf123?a')
|
|
testInvalid('at://user.bsky.social?a=B')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post?foo=bar')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post/record?q=3')
|
|
|
|
testInvalid('at://did:plc:asdf123?a=b#/frag')
|
|
testInvalid('at://user.bsky.social?a=b#/frag')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post?a=b#/frag')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post/record?a=b#/frag')
|
|
|
|
testInvalid('at://DID:plc:asdf123')
|
|
testInvalid('at://user.bsky.123')
|
|
testInvalid('at://bsky')
|
|
testInvalid('at://did:plc:')
|
|
testInvalid('at://did:plc:')
|
|
testInvalid('at://frag')
|
|
})
|
|
|
|
describe('very long strings', () => {
|
|
testValid('at://did:plc:asdf123/com.atproto.feed.post/' + 'o'.repeat(512))
|
|
testValid(`at://did:web:x${'.y'.repeat(100)}/com.atproto.feed.post/record`)
|
|
testInvalid(`at://did:plc:${'o'.repeat(8200)}/com.atproto.feed.post/record`)
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post/' + 'o'.repeat(513))
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post/' + 'o'.repeat(800))
|
|
})
|
|
|
|
describe('invalid collection', () => {
|
|
testInvalid('at://did:plc:asdf123/short/stuff')
|
|
testInvalid('at://did:plc:asdf123/12345')
|
|
})
|
|
|
|
describe('invalid repeated slashes', () => {
|
|
testInvalid('at://user.bsky.social//')
|
|
testInvalid('at://user.bsky.social//com.atproto.feed.post')
|
|
testInvalid('at://user.bsky.social/com.atproto.feed.post//')
|
|
})
|
|
|
|
describe('invalid trailing slashes', () => {
|
|
testInvalid('at://did:plc:asdf123/')
|
|
testInvalid('at://user.bsky.social/')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post/')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post/record/')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post/record/#/frag')
|
|
})
|
|
|
|
describe('invalid segment count', () => {
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post/asdf123/asdf')
|
|
testInvalid('at://did:plc:asdf123/com.atproto.feed.post/asdf123/more/more')
|
|
})
|
|
|
|
describe('valid record key', () => {
|
|
testValid('at://did:plc:asdf123/com.atproto.feed.post/a')
|
|
testValid('at://did:plc:asdf123/com.atproto.feed.post/asdf123')
|
|
})
|
|
|
|
describe('loosely valid trailing slash', () => {
|
|
testLoose('at://did:plc:asdf123/')
|
|
testLoose('at://user.bsky.social/')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/record/')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/record/#/frag')
|
|
})
|
|
|
|
describe('loosely valid record keys', () => {
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/%23')
|
|
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/$@!*)(:,;~.sdf123')
|
|
testLoose("at://did:plc:asdf123/com.atproto.feed.post/~'sdf123")
|
|
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/$')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/@')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/!')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/*')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/(')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/,')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/;')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/abc%30123')
|
|
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/%30')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/%3')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/%')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/%zz')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/%%%')
|
|
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/[]')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/foo[')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/bar]')
|
|
testLoose('at://did:plc:asdf123/com.atproto.feed.post/[baz]')
|
|
})
|
|
|
|
describe('valid fragment', () => {
|
|
testValid('at://did:plc:asdf123#/frac')
|
|
})
|
|
|
|
describe('invalid fragment', () => {
|
|
testValid('at://did:plc:asdf123#/com.atproto.feed.post')
|
|
testValid('at://did:plc:asdf123#/com.atproto.feed.post/')
|
|
testValid('at://did:plc:asdf123#/asdf/')
|
|
|
|
testValid('at://did:plc:asdf123/com.atproto.feed.post#/$@!*():,;~.sdf123')
|
|
testValid('at://did:plc:asdf123#/[asfd]')
|
|
|
|
testValid('at://did:plc:asdf123#/$')
|
|
testValid('at://did:plc:asdf123#/*')
|
|
testValid('at://did:plc:asdf123#/;')
|
|
testValid('at://did:plc:asdf123#/,')
|
|
|
|
testInvalid('at://did:plc:asdf123#')
|
|
testInvalid('at://did:plc:asdf123##')
|
|
testInvalid('#at://did:plc:asdf123')
|
|
testInvalid('at://did:plc:asdf123#/asdf#/asdf')
|
|
})
|
|
})
|
|
|
|
function testValid(value: string) {
|
|
test(value, () => {
|
|
expect(isAtUriString(value)).toBe(true)
|
|
expect(isAtUriString(value, { strict: false })).toBe(true)
|
|
expect(() => assertAtUriString(value)).not.toThrow()
|
|
expect(() => assertAtUriString(value, { strict: false })).not.toThrow()
|
|
})
|
|
}
|
|
|
|
function testInvalid(value: string) {
|
|
test(value, () => {
|
|
expect(isAtUriString(value)).toBe(false)
|
|
expect(() => assertAtUriString(value)).toThrow(InvalidAtUriError)
|
|
})
|
|
}
|
|
|
|
function testLoose(value: string) {
|
|
test(value, () => {
|
|
expect(isAtUriString(value)).toBe(false)
|
|
expect(isAtUriString(value, { strict: false })).toBe(true)
|
|
expect(() => assertAtUriString(value)).toThrow()
|
|
expect(() => assertAtUriString(value, { strict: false })).not.toThrow()
|
|
})
|
|
}
|
|
|
|
function readLines(filePath: string): string[] {
|
|
return readFileSync(filePath, 'utf-8')
|
|
.split(/\r?\n/)
|
|
.filter((line) => !line.startsWith('#') && line.length > 0)
|
|
}
|