@openzeppelin/contracts-ui-builder-adapter-stellar
Version:
Stellar Adapter for Contracts UI Builder
268 lines (205 loc) • 9.72 kB
text/typescript
// Import the mocked StrKey for use in tests
import { StrKey } from '@stellar/stellar-sdk';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import {
isValidAccountAddress,
isValidAddress,
isValidContractAddress,
isValidMuxedAddress,
isValidSecretSeed,
isValidSignedPayloadAddress,
type StellarAddressType,
} from '../address';
// Mock StrKey from stellar-sdk
vi.mock('@stellar/stellar-sdk', () => ({
StrKey: {
isValidEd25519PublicKey: vi.fn(),
isValidContract: vi.fn(),
isValidMed25519PublicKey: vi.fn(),
isValidEd25519SecretSeed: vi.fn(),
isValidSignedPayload: vi.fn(),
decodePreAuthTx: vi.fn(),
decodeSha256Hash: vi.fn(),
},
}));
const mockStrKey = StrKey as unknown as {
isValidEd25519PublicKey: ReturnType<typeof vi.fn>;
isValidContract: ReturnType<typeof vi.fn>;
isValidMed25519PublicKey: ReturnType<typeof vi.fn>;
isValidEd25519SecretSeed: ReturnType<typeof vi.fn>;
isValidSignedPayload: ReturnType<typeof vi.fn>;
decodePreAuthTx: ReturnType<typeof vi.fn>;
decodeSha256Hash: ReturnType<typeof vi.fn>;
};
describe('Specific validation functions', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('isValidAccountAddress', () => {
it('should return true for valid account address (G...)', () => {
const accountAddress = 'GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
mockStrKey.isValidEd25519PublicKey.mockReturnValue(true);
const result = isValidAccountAddress(accountAddress);
expect(result).toBe(true);
expect(mockStrKey.isValidEd25519PublicKey).toHaveBeenCalledWith(accountAddress);
});
it('should return false for invalid account address', () => {
const invalidAddress = 'INVALID_ACCOUNT';
mockStrKey.isValidEd25519PublicKey.mockReturnValue(false);
const result = isValidAccountAddress(invalidAddress);
expect(result).toBe(false);
});
});
describe('isValidContractAddress', () => {
it('should return true for valid contract address (C...)', () => {
const contractAddress = 'CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQAUHKENIFEJ';
mockStrKey.isValidContract.mockReturnValue(true);
const result = isValidContractAddress(contractAddress);
expect(result).toBe(true);
expect(mockStrKey.isValidContract).toHaveBeenCalledWith(contractAddress);
});
});
describe('isValidMuxedAddress', () => {
it('should return true for valid muxed address (M...)', () => {
const muxedAddress = 'MDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37AAAAAAAAAAAA';
mockStrKey.isValidMed25519PublicKey.mockReturnValue(true);
const result = isValidMuxedAddress(muxedAddress);
expect(result).toBe(true);
expect(mockStrKey.isValidMed25519PublicKey).toHaveBeenCalledWith(muxedAddress);
});
});
describe('isValidSecretSeed', () => {
it('should return true for valid secret seed (S...)', () => {
const secretSeed = 'SDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
mockStrKey.isValidEd25519SecretSeed.mockReturnValue(true);
const result = isValidSecretSeed(secretSeed);
expect(result).toBe(true);
expect(mockStrKey.isValidEd25519SecretSeed).toHaveBeenCalledWith(secretSeed);
});
});
describe('isValidSignedPayloadAddress', () => {
it('should return true for valid signed payload address (P...)', () => {
const signedPayload = 'PDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
mockStrKey.isValidSignedPayload.mockReturnValue(true);
const result = isValidSignedPayloadAddress(signedPayload);
expect(result).toBe(true);
expect(mockStrKey.isValidSignedPayload).toHaveBeenCalledWith(signedPayload);
});
});
});
describe('isValidAddress (main function)', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('without specific type (validates common types)', () => {
it('should return true for valid account address (G...)', () => {
const accountAddress = 'GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
mockStrKey.isValidEd25519PublicKey.mockReturnValue(true);
mockStrKey.isValidContract.mockReturnValue(false);
mockStrKey.isValidMed25519PublicKey.mockReturnValue(false);
const result = isValidAddress(accountAddress);
expect(result).toBe(true);
});
it('should return true for valid contract address (C...)', () => {
const contractAddress = 'CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQAUHKENIFEJ';
mockStrKey.isValidEd25519PublicKey.mockReturnValue(false);
mockStrKey.isValidContract.mockReturnValue(true);
mockStrKey.isValidMed25519PublicKey.mockReturnValue(false);
const result = isValidAddress(contractAddress);
expect(result).toBe(true);
});
it('should return true for valid muxed address (M...)', () => {
const muxedAddress = 'MDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37AAAAAAAAAAAA';
mockStrKey.isValidEd25519PublicKey.mockReturnValue(false);
mockStrKey.isValidContract.mockReturnValue(false);
mockStrKey.isValidMed25519PublicKey.mockReturnValue(true);
const result = isValidAddress(muxedAddress);
expect(result).toBe(true);
});
it('should return false for secret seeds (security)', () => {
const secretSeed = 'SDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
mockStrKey.isValidEd25519PublicKey.mockReturnValue(false);
mockStrKey.isValidContract.mockReturnValue(false);
mockStrKey.isValidMed25519PublicKey.mockReturnValue(false);
const result = isValidAddress(secretSeed);
expect(result).toBe(false);
// Secret validation should NOT be called for security
expect(mockStrKey.isValidEd25519SecretSeed).not.toHaveBeenCalled();
});
});
describe('with specific address type', () => {
it('should validate only account type when specified', () => {
const accountAddress = 'GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
mockStrKey.isValidEd25519PublicKey.mockReturnValue(true);
const result = isValidAddress(accountAddress, 'account');
expect(result).toBe(true);
expect(mockStrKey.isValidEd25519PublicKey).toHaveBeenCalledWith(accountAddress);
// Other validation methods should not be called
expect(mockStrKey.isValidContract).not.toHaveBeenCalled();
});
it('should validate only contract type when specified', () => {
const contractAddress = 'CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQAUHKENIFEJ';
mockStrKey.isValidContract.mockReturnValue(true);
const result = isValidAddress(contractAddress, 'contract');
expect(result).toBe(true);
expect(mockStrKey.isValidContract).toHaveBeenCalledWith(contractAddress);
// Other validation methods should not be called
expect(mockStrKey.isValidEd25519PublicKey).not.toHaveBeenCalled();
});
it('should validate only muxed type when specified', () => {
const muxedAddress = 'MDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37AAAAAAAAAAAA';
mockStrKey.isValidMed25519PublicKey.mockReturnValue(true);
const result = isValidAddress(muxedAddress, 'muxed');
expect(result).toBe(true);
expect(mockStrKey.isValidMed25519PublicKey).toHaveBeenCalledWith(muxedAddress);
});
it('should validate secret seeds when specifically requested', () => {
const secretSeed = 'SDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
mockStrKey.isValidEd25519SecretSeed.mockReturnValue(true);
const result = isValidAddress(secretSeed, 'secret');
expect(result).toBe(true);
expect(mockStrKey.isValidEd25519SecretSeed).toHaveBeenCalledWith(secretSeed);
});
it('should validate pre-auth-tx when specified', () => {
const preAuthTx = 'TDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
mockStrKey.decodePreAuthTx.mockReturnValue(new Uint8Array([1, 2, 3, 4]));
const result = isValidAddress(preAuthTx, 'pre-auth-tx');
expect(result).toBe(true);
expect(mockStrKey.decodePreAuthTx).toHaveBeenCalledWith(preAuthTx);
});
it('should validate hash-x when specified', () => {
const hashX = 'XDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
mockStrKey.decodeSha256Hash.mockReturnValue(new Uint8Array([1, 2, 3, 4]));
const result = isValidAddress(hashX, 'hash-x');
expect(result).toBe(true);
expect(mockStrKey.decodeSha256Hash).toHaveBeenCalledWith(hashX);
});
it('should return false for unknown address type', () => {
const address = 'GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37';
const result = isValidAddress(address, 'unknown' as StellarAddressType);
expect(result).toBe(false);
});
});
describe('edge cases', () => {
it('should return false for empty string', () => {
const result = isValidAddress('');
expect(result).toBe(false);
});
it('should return false for null/undefined input', () => {
// @ts-expect-error Testing invalid input
const resultNull = isValidAddress(null);
// @ts-expect-error Testing invalid input
const resultUndefined = isValidAddress(undefined);
expect(resultNull).toBe(false);
expect(resultUndefined).toBe(false);
});
it('should handle exceptions gracefully', () => {
const address = 'MALFORMED_ADDRESS';
mockStrKey.isValidEd25519PublicKey.mockImplementation(() => {
throw new Error('Invalid format');
});
const result = isValidAddress(address);
expect(result).toBe(false);
});
});
});