@atproto/oauth-scopes
Version:
A library for manipulating and validating ATproto OAuth scopes in TypeScript.
127 lines (111 loc) • 4.4 kB
text/typescript
import { BlobPermission } from './blob-permission.js'
describe('BlobPermission', () => {
describe('static', () => {
describe('fromString', () => {
it('should parse positional scope', () => {
const scope = BlobPermission.fromString('blob:image/png')
expect(scope).not.toBeNull()
expect(scope!.accept).toEqual(['image/png'])
})
it('should parse valid blob scope with multiple accept parameters', () => {
const scope = BlobPermission.fromString(
'blob?accept=image/png&accept=image/jpeg',
)
expect(scope).not.toBeNull()
expect(scope!.accept).toEqual(['image/png', 'image/jpeg'])
})
it('should reject blob scope without accept', () => {
const scope = BlobPermission.fromString('blob')
expect(scope).toBeNull()
})
for (const invalid of [
'invalid',
'scope',
'blob:invalid',
'blob?accept=invalid-mime',
'blob?accept=invalid',
'blob:*/**',
'blob:*/png',
]) {
it(`should return null for invalid rpc scope: ${invalid}`, () => {
expect(BlobPermission.fromString(invalid)).toBeNull()
})
}
})
describe('scopeNeededFor', () => {
it('should return correct scope string for specific MIME type', () => {
const scope = BlobPermission.scopeNeededFor({ mime: 'image/png' })
expect(scope).toBe('blob:image/png')
})
it('should return scope that accepts all MIME types', () => {
const scope = BlobPermission.scopeNeededFor({
mime: 'application/json',
})
expect(scope).toBe('blob:application/json')
})
})
})
describe('instance', () => {
describe('matches', () => {
it('should match exact MIME type', () => {
const scope = BlobPermission.fromString('blob:image/png')
expect(scope).not.toBeNull()
expect(scope!.matches({ mime: 'image/png' })).toBe(true)
})
it('should match wildcard MIME type', () => {
const scope = BlobPermission.fromString('blob:*/*')
expect(scope).not.toBeNull()
expect(scope!.matches({ mime: 'image/jpeg' })).toBe(true)
expect(scope!.matches({ mime: 'application/json' })).toBe(true)
})
it('should match subtype wildcard MIME type', () => {
const scope = BlobPermission.fromString('blob:image/*')
expect(scope).not.toBeNull()
expect(scope!.matches({ mime: 'image/gif' })).toBe(true)
})
it('should not match different MIME type', () => {
const scope = BlobPermission.fromString('blob:image/png')
expect(scope).not.toBeNull()
expect(scope!.matches({ mime: 'image/jpeg' })).toBe(false)
})
it('should match multiple accept values', () => {
const scope = BlobPermission.fromString(
'blob?accept=image/png&accept=image/jpeg',
)
expect(scope).not.toBeNull()
expect(scope!.matches({ mime: 'image/png' })).toBe(true)
expect(scope!.matches({ mime: 'image/jpeg' })).toBe(true)
expect(scope!.matches({ mime: 'image/gif' })).toBe(false)
})
})
describe('toString', () => {
it('should format scope with accept parameter', () => {
const scope = new BlobPermission(['image/png', 'image/jpeg'])
expect(scope.toString()).toBe('blob?accept=image/jpeg&accept=image/png')
})
it('should strip redundant accept parameters', () => {
expect(new BlobPermission(['*/*', 'image/*']).toString()).toBe(
'blob:*/*',
)
expect(new BlobPermission(['*/*', 'image/png']).toString()).toBe(
'blob:*/*',
)
expect(new BlobPermission(['image/*', 'image/png']).toString()).toBe(
'blob:image/*',
)
})
it('should use positional format for single accept', () => {
expect(new BlobPermission(['image/png']).toString()).toBe(
'blob:image/png',
)
expect(new BlobPermission(['image/*']).toString()).toBe('blob:image/*')
expect(new BlobPermission(['*/*']).toString()).toBe('blob:*/*')
})
it('should use query format for multiple accepts', () => {
expect(new BlobPermission(['image/png', 'image/jpeg']).toString()).toBe(
'blob?accept=image/jpeg&accept=image/png',
)
})
})
})
})