import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
/**
* Tests for data formatting utilities
*/
import {
formatStamp,
formatCollection,
formatToken,
formatTimestamp,
formatNumber,
formatSupply,
} from '../../utils/formatters.js';
import { createMockStamp, createMockCollection, createMockToken } from '../utils/test-helpers.js';
describe('Formatter Utilities', () => {
describe('formatStamp', () => {
it('should format complete stamp data', () => {
const stamp = createMockStamp({
stamp: 12345,
creator: 'bc1qtest123456789012345678901234567890abcdef',
supply: 1,
locked: 1,
divisible: 0,
block_time: '2024-01-15T10:30:00Z',
stamp_url: 'https://stampchain.io/stamp/12345.png',
block_index: 800000, // Override to match test expectation
});
const formatted = formatStamp(stamp);
expect(formatted).toContain('Stamp #12345');
expect(formatted).toContain('Creator: bc1qtest123456789012345678901234567890abcdef');
expect(formatted).toContain('Supply: 1');
expect(formatted).toContain('Status: LOCKED');
expect(formatted).toContain('Type: STAMP');
expect(formatted).toContain('Block: 800000');
expect(formatted).toContain('URL: https://stampchain.io/stamp/12345.png');
});
it('should format stamp without optional fields', () => {
const stamp = createMockStamp({
stamp: 12345,
creator: 'bc1qtest123456789012345678901234567890abcdef',
supply: 1,
locked: 1,
divisible: 0,
block_time: '2024-01-15T10:30:00Z',
stamp_url: undefined,
});
const formatted = formatStamp(stamp);
expect(formatted).toContain('Stamp #12345');
expect(formatted).not.toContain('Collection:');
expect(formatted).not.toContain('Image:');
});
it('should format large supply numbers', () => {
const stamp = createMockStamp({
supply: 21000000,
divisible: 1,
});
const formatted = formatStamp(stamp);
expect(formatted).toContain('Supply: 0.21');
expect(formatted).toContain('Type: STAMP');
});
});
describe('formatCollection', () => {
it('should format complete collection data', () => {
const collection = createMockCollection({
collection_name: 'Rare Pepes Collection',
collection_description: 'Original rare pepe stamps from the early days',
creators: ['bc1qtest123456789012345678901234567890abcdef'],
stamp_count: 1500,
total_editions: 1500,
});
const formatted = formatCollection(collection);
expect(formatted).toContain('Collection: Rare Pepes Collection');
expect(formatted).toContain('Description: Original rare pepe stamps from the early days');
expect(formatted).toContain('Creators: bc1qtest123456789012345678901234567890abcdef');
expect(formatted).toContain('Stamps: 1500');
expect(formatted).toContain('Total Editions: 1500');
// Note: API doesn't include created date or website fields
});
it('should format collection without optional fields', () => {
const collection = createMockCollection({
collection_name: 'Simple Collection',
creators: ['bc1qtest123456789012345678901234567890abcdef'],
stamp_count: 10,
total_editions: 10,
});
const formatted = formatCollection(collection);
expect(formatted).toContain('Collection: Simple Collection');
expect(formatted).toContain('Creators: bc1qtest123456789012345678901234567890abcdef');
expect(formatted).not.toContain('Created:');
expect(formatted).not.toContain('Website:');
});
it('should handle multiple creators', () => {
const collection = createMockCollection({
creators: ['bc1qtest1', 'bc1qtest2', 'bc1qtest3'],
});
const formatted = formatCollection(collection);
expect(formatted).toContain('Creators: bc1qtest1, bc1qtest2, bc1qtest3');
});
});
describe('formatToken', () => {
it('should format complete token data', () => {
const token = createMockToken({
tick: 'UNCOMMON',
max: '21000000',
lim: '1000',
deci: 8,
creator: 'bc1qtest123456789012345678901234567890abcdef',
});
const formatted = formatToken(token);
expect(formatted).toContain('Token: UNCOMMON');
expect(formatted).toContain('Max Supply: 21000000');
expect(formatted).toContain('Mint Limit: 1000');
expect(formatted).toContain('Creator: bc1qtest123456789012345678901234567890abcdef');
});
it('should show percent minted when available', () => {
const token = createMockToken({
max: '10000',
});
const formatted = formatToken(token);
expect(formatted).toContain('Max Supply: 10000');
});
it('should handle zero decimal places', () => {
const token = createMockToken({
deci: 0,
max: '1000000',
lim: '100',
});
const formatted = formatToken(token);
expect(formatted).toContain('Decimals: 0');
expect(formatted).toContain('Max Supply: 1000000');
expect(formatted).toContain('Mint Limit: 100');
});
it('should handle fully minted tokens', () => {
const token = createMockToken({
max: '1000',
});
const formatted = formatToken(token);
expect(formatted).toContain('Max Supply: 1000');
});
});
describe('formatTimestamp', () => {
it('should format ISO timestamp to readable format', () => {
const timestamp = '2024-01-15T10:30:45Z';
const formatted = formatTimestamp(timestamp);
expect(formatted).toContain('Jan 15, 2024');
});
it('should handle timestamps with milliseconds', () => {
const timestamp = '2024-01-15T10:30:45.123Z';
const formatted = formatTimestamp(timestamp);
expect(formatted).toContain('Jan 15, 2024');
});
it('should handle different timezone formats', () => {
const timestamp = '2024-01-15T10:30:45+00:00';
const formatted = formatTimestamp(timestamp);
expect(formatted).toContain('Jan 15, 2024');
});
it('should handle invalid timestamps gracefully', () => {
const invalidTimestamp = 'not-a-timestamp';
const formatted = formatTimestamp(invalidTimestamp);
expect(formatted).toBe('Invalid Date');
});
});
describe('formatNumber', () => {
it('should format numbers with thousand separators', () => {
expect(formatNumber(1234)).toBe('1,234');
expect(formatNumber(1234567)).toBe('1,234,567');
expect(formatNumber(1234567890)).toBe('1,234,567,890');
});
it('should handle small numbers', () => {
expect(formatNumber(0)).toBe('0');
expect(formatNumber(42)).toBe('42');
expect(formatNumber(999)).toBe('999');
});
it('should handle string numbers', () => {
expect(formatNumber('1234567')).toBe('1,234,567');
expect(formatNumber('999')).toBe('999');
});
it('should handle decimal numbers', () => {
expect(formatNumber(1234.56)).toBe('1,234.56');
expect(formatNumber('1234567.89')).toBe('1,234,567.89');
});
it('should handle invalid numbers gracefully', () => {
expect(formatNumber('not-a-number')).toBe('not-a-number');
expect(formatNumber(NaN)).toBe('NaN');
});
});
describe('formatSupply', () => {
it('should format non-divisible supply numbers', () => {
expect(formatSupply(1234, 0)).toBe('1,234');
expect(formatSupply(1234567, 0)).toBe('1,234,567');
});
it('should format divisible supply numbers', () => {
expect(formatSupply(100000000, 1)).toBe('1');
expect(formatSupply(2100000000000000, 1)).toBe('21000000');
});
it('should handle large non-divisible numbers', () => {
expect(formatSupply(21000000, 0)).toBe('21,000,000');
expect(formatSupply(1000000000, 0)).toBe('1,000,000,000');
});
});
describe('Edge Cases and Error Handling', () => {
it('should handle null/undefined inputs gracefully', () => {
expect(() => formatStamp(null as any)).toThrow();
expect(() => formatCollection(undefined as any)).toThrow();
expect(() => formatToken(null as any)).toThrow();
});
it('should handle objects with missing properties', () => {
const incompleteStamp = { stamp: 12345 } as any;
expect(() => formatStamp(incompleteStamp)).not.toThrow();
const incompleteCollection = { collection_id: 'test', creators: ['test'] } as any;
expect(() => formatCollection(incompleteCollection)).not.toThrow();
const incompleteToken = { tick: 'TEST' } as any;
expect(() => formatToken(incompleteToken)).not.toThrow();
});
it('should handle very large numbers', () => {
const largeNumber = '999999999999999999999';
expect(() => formatNumber(largeNumber)).not.toThrow();
expect(formatNumber(largeNumber)).toContain(',');
});
it('should handle special Unicode characters in names', () => {
const collection = createMockCollection({
collection_name: 'Collection with émojis 🚀 and spéciál chars',
collection_description: 'Dëscription with ünīcøde',
});
const formatted = formatCollection(collection);
expect(formatted).toContain('Collection with émojis 🚀 and spéciál chars');
expect(formatted).toContain('Dëscription with ünīcøde');
});
});
});