104 lines
3.0 KiB
JavaScript
104 lines
3.0 KiB
JavaScript
/**
|
|
* Property-based tests for storage module
|
|
* **Feature: miniapp-frontend, Property 1: Token Storage Consistency**
|
|
* **Validates: Requirements 1.2**
|
|
*/
|
|
|
|
import { describe, it, expect, beforeEach } from 'vitest'
|
|
import * as fc from 'fast-check'
|
|
|
|
// Import mock before storage module
|
|
import '../mocks/uni.js'
|
|
import { setToken, getToken, removeToken, setStorage, getStorage } from '../../utils/storage.js'
|
|
|
|
describe('Storage Property Tests', () => {
|
|
beforeEach(() => {
|
|
// Clear storage before each test
|
|
uni._clearStorage()
|
|
})
|
|
|
|
/**
|
|
* Property 1: Token Storage Consistency
|
|
* *For any* valid API login response containing a JWT token,
|
|
* storing the token SHALL result in the token being retrievable
|
|
* from storage with identical value.
|
|
* **Validates: Requirements 1.2**
|
|
*/
|
|
it('Property 1: Token Storage Consistency - stored token should be retrievable with identical value', () => {
|
|
fc.assert(
|
|
fc.property(
|
|
// Generate valid JWT-like tokens (non-empty strings)
|
|
fc.string({ minLength: 1 }).filter(s => s.trim().length > 0),
|
|
(token) => {
|
|
// Store the token
|
|
setToken(token)
|
|
|
|
// Retrieve the token
|
|
const retrievedToken = getToken()
|
|
|
|
// The retrieved token should be identical to the stored token
|
|
return retrievedToken === token
|
|
}
|
|
),
|
|
{ numRuns: 100 }
|
|
)
|
|
})
|
|
|
|
/**
|
|
* Additional property: Generic storage consistency
|
|
* For any key-value pair, storing and retrieving should return the same value
|
|
* Note: Empty strings and null values have special behavior in uni storage
|
|
*/
|
|
it('Generic storage consistency - stored values should be retrievable', () => {
|
|
fc.assert(
|
|
fc.property(
|
|
fc.string({ minLength: 1 }).filter(s => s.trim().length > 0),
|
|
fc.oneof(
|
|
// Exclude empty strings as they have special behavior (treated as "not set")
|
|
fc.string({ minLength: 1 }),
|
|
fc.integer(),
|
|
fc.boolean()
|
|
),
|
|
(key, value) => {
|
|
// Store the value
|
|
setStorage(key, value)
|
|
|
|
// Retrieve the value
|
|
const retrievedValue = getStorage(key)
|
|
|
|
// The retrieved value should equal the stored value
|
|
return retrievedValue === value
|
|
}
|
|
),
|
|
{ numRuns: 100 }
|
|
)
|
|
})
|
|
|
|
/**
|
|
* Property: Token removal should clear the token
|
|
*/
|
|
it('Token removal should result in empty token', () => {
|
|
fc.assert(
|
|
fc.property(
|
|
fc.string({ minLength: 1 }).filter(s => s.trim().length > 0),
|
|
(token) => {
|
|
// Store the token
|
|
setToken(token)
|
|
|
|
// Verify it's stored
|
|
const storedToken = getToken()
|
|
if (storedToken !== token) return false
|
|
|
|
// Remove the token
|
|
removeToken()
|
|
|
|
// Token should now be empty
|
|
const afterRemoval = getToken()
|
|
return afterRemoval === ''
|
|
}
|
|
),
|
|
{ numRuns: 100 }
|
|
)
|
|
})
|
|
})
|