@nuwa-ai/identity-kit-web
Version:
Web extensions for Nuwa Identity Kit
155 lines (131 loc) • 4.49 kB
text/typescript
import { describe, it, expect } from '@jest/globals';
// Mock crypto.getRandomValues for testing
Object.defineProperty(global, 'crypto', {
value: {
getRandomValues: (arr: Uint8Array) => {
for (let i = 0; i < arr.length; i++) {
arr[i] = Math.floor(Math.random() * 256);
}
return arr;
}
}
});
// Mock window for testing
if (typeof window === 'undefined') {
Object.defineProperty(global, 'window', {
value: {
location: {
origin: 'http://localhost:3000'
},
sessionStorage: {
getItem: () => null,
setItem: () => {},
removeItem: () => {}
}
}
});
}
describe('DeepLinkManager Scopes Validation', () => {
// Test scope validation logic directly without importing the full DeepLinkManager
function validateScopeFormat(scope: string): boolean {
if (!scope || typeof scope !== 'string') {
return false;
}
const parts = scope.split('::');
if (parts.length !== 3) {
return false;
}
const [address, module, func] = parts;
// Each part must be non-empty
if (!address || !module || !func) {
return false;
}
// Basic address format validation (hex or wildcard)
if (address !== '*' && !isValidAddressFormat(address)) {
return false;
}
return true;
}
function isValidAddressFormat(address: string): boolean {
// Accept hex addresses (0x...) and bech32 addresses (rooch1...)
if (address.startsWith('0x')) {
return /^0x[a-fA-F0-9]+$/.test(address);
}
if (address.startsWith('rooch1')) {
return /^rooch1[a-z0-9]+$/.test(address);
}
return false;
}
describe('scope format validation', () => {
it('should accept valid scope formats', () => {
const validScopes = [
'0x123::defi::swap',
'*::nft::mint',
'0xabc::gamefi::*',
'rooch1abc123::module::function'
];
validScopes.forEach(scope => {
expect(validateScopeFormat(scope)).toBe(true);
});
});
it('should reject invalid scope formats', () => {
const invalidScopes = [
'invalid', // Missing :: separators
'0x123::defi', // Only two parts
'::defi::swap', // Empty address
'0x123::', // Empty module and function
'0x123::::swap', // Extra separators
'' // Empty string
];
invalidScopes.forEach(scope => {
expect(validateScopeFormat(scope)).toBe(false);
});
});
it('should accept wildcard patterns', () => {
const wildcardScopes = [
'*::*::*',
'0x123::*::*',
'*::defi::*',
'*::*::mint'
];
wildcardScopes.forEach(scope => {
expect(validateScopeFormat(scope)).toBe(true);
});
});
it('should validate address formats correctly', () => {
expect(isValidAddressFormat('0x123abc')).toBe(true);
expect(isValidAddressFormat('0xABCDEF1234567890')).toBe(true);
expect(isValidAddressFormat('rooch1abc123')).toBe(true);
expect(isValidAddressFormat('*')).toBe(false); // * is handled separately
expect(isValidAddressFormat('invalid-address')).toBe(false);
expect(isValidAddressFormat('0xGGG')).toBe(false); // Invalid hex
expect(isValidAddressFormat('rooch2invalid')).toBe(false); // Invalid bech32
});
});
describe('validateScopes function', () => {
function validateScopes(scopes: string[]): { valid: boolean; invalidScopes: string[] } {
const invalidScopes = scopes.filter(scope => !validateScopeFormat(scope));
return {
valid: invalidScopes.length === 0,
invalidScopes,
};
}
it('should return valid for all valid scopes', () => {
const scopes = ['0x123::defi::swap', '*::nft::mint'];
const result = validateScopes(scopes);
expect(result.valid).toBe(true);
expect(result.invalidScopes).toEqual([]);
});
it('should return invalid scopes', () => {
const scopes = ['0x123::defi::swap', 'invalid-scope', '*::nft::mint'];
const result = validateScopes(scopes);
expect(result.valid).toBe(false);
expect(result.invalidScopes).toContain('invalid-scope');
});
it('should handle empty array', () => {
const result = validateScopes([]);
expect(result.valid).toBe(true);
expect(result.invalidScopes).toEqual([]);
});
});
});