mirror of
https://github.com/supabase/supabase.git
synced 2026-10-09 19:35:06 +03:00
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
194 lines
6.3 KiB
TypeScript
194 lines
6.3 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import { PermissionRowSchema, TokenSchema } from './AccessToken.schemas'
|
|
|
|
const validTokenData = {
|
|
tokenName: 'My Token',
|
|
expiresAt: 'day',
|
|
resourceAccess: 'all-orgs' as const,
|
|
permissionRows: [{ resource: 'organization:billing', actions: ['read'] }],
|
|
}
|
|
|
|
// --- PermissionRowSchema ---
|
|
|
|
describe('PermissionRowSchema', () => {
|
|
it('should pass for a valid permission row', () => {
|
|
const result = PermissionRowSchema.safeParse({
|
|
resource: 'organization:billing',
|
|
actions: ['read'],
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it('should fail when resource is empty', () => {
|
|
const result = PermissionRowSchema.safeParse({
|
|
resource: '',
|
|
actions: ['read'],
|
|
})
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
expect(result.error.issues[0].message).toBe('Please select a resource')
|
|
}
|
|
})
|
|
|
|
it('should fail when actions is empty', () => {
|
|
const result = PermissionRowSchema.safeParse({
|
|
resource: 'organization:billing',
|
|
actions: [],
|
|
})
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
expect(result.error.issues[0].message).toBe('Please select at least one action')
|
|
}
|
|
})
|
|
|
|
it('should fail when resource is missing', () => {
|
|
const result = PermissionRowSchema.safeParse({ actions: ['read'] })
|
|
expect(result.success).toBe(false)
|
|
})
|
|
|
|
it('should fail when actions is missing', () => {
|
|
const result = PermissionRowSchema.safeParse({ resource: 'organization:billing' })
|
|
expect(result.success).toBe(false)
|
|
})
|
|
})
|
|
|
|
// --- TokenSchema ---
|
|
|
|
describe('TokenSchema', () => {
|
|
it('should pass for valid token data', () => {
|
|
const result = TokenSchema.safeParse(validTokenData)
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it('should fail when tokenName is empty', () => {
|
|
const result = TokenSchema.safeParse({ ...validTokenData, tokenName: '' })
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
const nameError = result.error.issues.find((i) => i.path.includes('tokenName'))
|
|
expect(nameError?.message).toBe('Please enter a name for the token')
|
|
}
|
|
})
|
|
|
|
it('should fail when tokenName is missing', () => {
|
|
const { tokenName, ...rest } = validTokenData
|
|
const result = TokenSchema.safeParse(rest)
|
|
expect(result.success).toBe(false)
|
|
})
|
|
|
|
it('should fail when permissionRows is empty', () => {
|
|
const result = TokenSchema.safeParse({ ...validTokenData, permissionRows: [] })
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
const permError = result.error.issues.find((i) => i.path.includes('permissionRows'))
|
|
expect(permError?.message).toBe('Please configure at least one permission')
|
|
}
|
|
})
|
|
|
|
it('should fail when resourceAccess is not a valid enum value', () => {
|
|
const result = TokenSchema.safeParse({ ...validTokenData, resourceAccess: 'invalid' })
|
|
expect(result.success).toBe(false)
|
|
})
|
|
|
|
it('should accept all valid resourceAccess enum values', () => {
|
|
for (const value of ['all-orgs', 'selected-orgs', 'selected-projects'] as const) {
|
|
const result = TokenSchema.safeParse({ ...validTokenData, resourceAccess: value })
|
|
expect(result.success).toBe(true)
|
|
}
|
|
})
|
|
|
|
describe('expiresAt preprocessing', () => {
|
|
it('should convert "never" to undefined', () => {
|
|
const result = TokenSchema.safeParse({ ...validTokenData, expiresAt: 'never' })
|
|
expect(result.success).toBe(true)
|
|
if (result.success) {
|
|
expect(result.data.expiresAt).toBeUndefined()
|
|
}
|
|
})
|
|
|
|
it('should pass through other string values', () => {
|
|
const result = TokenSchema.safeParse({ ...validTokenData, expiresAt: 'day' })
|
|
expect(result.success).toBe(true)
|
|
if (result.success) {
|
|
expect(result.data.expiresAt).toBe('day')
|
|
}
|
|
})
|
|
|
|
it('should allow expiresAt to be omitted', () => {
|
|
const { expiresAt, ...rest } = validTokenData
|
|
const result = TokenSchema.safeParse(rest)
|
|
expect(result.success).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('custom expiry refinement', () => {
|
|
it('should fail when expiresAt is "custom" and customExpiryDate is not provided', () => {
|
|
const result = TokenSchema.safeParse({
|
|
...validTokenData,
|
|
expiresAt: 'custom',
|
|
customExpiryDate: undefined,
|
|
})
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
const customError = result.error.issues.find((i) => i.path.includes('expiresAt'))
|
|
expect(customError?.message).toBe('Please select a custom expiry date')
|
|
}
|
|
})
|
|
|
|
it('should fail when expiresAt is "custom" and customExpiryDate is empty string', () => {
|
|
const result = TokenSchema.safeParse({
|
|
...validTokenData,
|
|
expiresAt: 'custom',
|
|
customExpiryDate: '',
|
|
})
|
|
expect(result.success).toBe(false)
|
|
})
|
|
|
|
it('should pass when expiresAt is "custom" and customExpiryDate is provided', () => {
|
|
const result = TokenSchema.safeParse({
|
|
...validTokenData,
|
|
expiresAt: 'custom',
|
|
customExpiryDate: '2026-12-31T00:00:00Z',
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it('should pass when expiresAt is not "custom" even without customExpiryDate', () => {
|
|
const result = TokenSchema.safeParse({
|
|
...validTokenData,
|
|
expiresAt: 'day',
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('nested permissionRows validation', () => {
|
|
it('should fail when a permission row has an empty resource', () => {
|
|
const result = TokenSchema.safeParse({
|
|
...validTokenData,
|
|
permissionRows: [{ resource: '', actions: ['read'] }],
|
|
})
|
|
expect(result.success).toBe(false)
|
|
})
|
|
|
|
it('should fail when a permission row has empty actions', () => {
|
|
const result = TokenSchema.safeParse({
|
|
...validTokenData,
|
|
permissionRows: [{ resource: 'organization:billing', actions: [] }],
|
|
})
|
|
expect(result.success).toBe(false)
|
|
})
|
|
|
|
it('should pass with multiple valid permission rows', () => {
|
|
const result = TokenSchema.safeParse({
|
|
...validTokenData,
|
|
permissionRows: [
|
|
{ resource: 'organization:billing', actions: ['read'] },
|
|
{ resource: 'organization:members', actions: ['read', 'write'] },
|
|
],
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
})
|
|
})
|