xiangyixiangqin/miniapp/__tests__/properties/auth.property.test.js
2026-01-06 22:08:53 +08:00

91 lines
2.6 KiB
JavaScript

/**
* Property-based tests for authentication handling
* **Feature: miniapp-frontend, Property 2: Auth Redirect on Invalid Token**
* **Validates: Requirements 1.4**
*/
import { describe, it, expect, beforeEach } from 'vitest'
import * as fc from 'fast-check'
// Import mock before other modules
import '../mocks/uni.js'
import { setToken, getToken } from '../../utils/storage.js'
import { handleUnauthorized } from '../../api/request.js'
describe('Auth Property Tests', () => {
beforeEach(() => {
// Clear storage and reset redirect state before each test
uni._clearStorage()
uni._resetRedirectState()
})
/**
* Property 2: Auth Redirect on Invalid Token
* *For any* API response with 401 status code, the application SHALL
* clear the stored token.
* Note: Redirect is handled by the caller, not handleUnauthorized itself
* **Validates: Requirements 1.4**
*/
it('Property 2: Auth Redirect on Invalid Token - 401 should clear token', () => {
fc.assert(
fc.property(
// Generate any token that might be stored
fc.string({ minLength: 1 }).filter(s => s.trim().length > 0),
(token) => {
// Setup: Store a token (simulating logged-in state)
setToken(token)
// Verify token is stored
const storedToken = getToken()
if (storedToken !== token) return false
// Action: Handle unauthorized (simulating 401 response)
handleUnauthorized()
// Verify: Token should be cleared
const tokenAfterUnauth = getToken()
const tokenCleared = tokenAfterUnauth === ''
// Reset for next iteration
uni._clearStorage()
return tokenCleared
}
),
{ numRuns: 100 }
)
})
/**
* Property: handleUnauthorized should be idempotent
* Calling it multiple times should have the same effect as calling once
*/
it('handleUnauthorized should be idempotent', () => {
fc.assert(
fc.property(
fc.string({ minLength: 1 }).filter(s => s.trim().length > 0),
fc.integer({ min: 1, max: 5 }),
(token, callCount) => {
// Setup
setToken(token)
// Call handleUnauthorized multiple times
for (let i = 0; i < callCount; i++) {
handleUnauthorized()
}
// Token should still be cleared
const tokenAfter = getToken()
const tokenCleared = tokenAfter === ''
// Cleanup
uni._clearStorage()
return tokenCleared
}
),
{ numRuns: 100 }
)
})
})