mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-14 12:23:52 +02:00
315 lines
11 KiB
JavaScript
315 lines
11 KiB
JavaScript
import {
|
|
getPrintFileName,
|
|
getPrintLocalDate,
|
|
getEmojiFileName
|
|
} from '../gallery';
|
|
|
|
describe('Gallery Utils', () => {
|
|
describe('getPrintFileName', () => {
|
|
test('generates filename with createdAt', () => {
|
|
const print = {
|
|
authorName: 'TestUser',
|
|
createdAt: '2023-01-15T10:30:45.123Z',
|
|
id: 'print_12345'
|
|
};
|
|
const result = getPrintFileName(print);
|
|
expect(result).toContain('TestUser');
|
|
expect(result).toContain('print_12345');
|
|
expect(result).toContain('.png');
|
|
// Check date formatting - should replace : with - and T with _
|
|
expect(result).toMatch(
|
|
/\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\.\d{3}/
|
|
);
|
|
});
|
|
|
|
test('generates filename with timestamp fallback', () => {
|
|
const print = {
|
|
authorName: 'TestUser2',
|
|
timestamp: 1673776245123, // 2023-01-15T10:30:45.123Z
|
|
id: 'print_67890'
|
|
};
|
|
const result = getPrintFileName(print);
|
|
expect(result).toContain('TestUser2');
|
|
expect(result).toContain('print_67890');
|
|
expect(result).toContain('.png');
|
|
});
|
|
|
|
test('generates filename with current date fallback', () => {
|
|
const print = {
|
|
authorName: 'TestUser3',
|
|
id: 'print_fallback'
|
|
};
|
|
const result = getPrintFileName(print);
|
|
expect(result).toContain('TestUser3');
|
|
expect(result).toContain('print_fallback');
|
|
expect(result).toContain('.png');
|
|
// Should still have valid date format
|
|
expect(result).toMatch(
|
|
/\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\.\d{3}/
|
|
);
|
|
});
|
|
|
|
test('handles missing authorName', () => {
|
|
const print = {
|
|
createdAt: '2023-01-15T10:30:45.123Z',
|
|
id: 'print_no_author'
|
|
};
|
|
const result = getPrintFileName(print);
|
|
expect(result).toContain('undefined_'); // authorName will be undefined
|
|
expect(result).toContain('print_no_author');
|
|
});
|
|
|
|
test('handles special characters in authorName', () => {
|
|
const print = {
|
|
authorName: 'Test User / With : Chars',
|
|
createdAt: '2023-01-15T10:30:45.123Z',
|
|
id: 'print_special'
|
|
};
|
|
const result = getPrintFileName(print);
|
|
expect(result).toContain('Test User / With : Chars'); // Should preserve original chars
|
|
expect(result).toContain('print_special');
|
|
});
|
|
|
|
test('handles missing data gracefully', () => {
|
|
const print = { id: 'test' };
|
|
const result = getPrintFileName(print);
|
|
expect(typeof result).toBe('string');
|
|
expect(result).toContain('test');
|
|
expect(result).toContain('.png');
|
|
});
|
|
});
|
|
|
|
describe('getPrintLocalDate', () => {
|
|
test('converts createdAt to local date', () => {
|
|
const print = { createdAt: '2023-01-15T10:30:45.123Z' };
|
|
const result = getPrintLocalDate(print);
|
|
expect(result).toBeInstanceOf(Date);
|
|
// Should have timezone offset applied
|
|
const originalDate = new Date('2023-01-15T10:30:45.123Z');
|
|
const expectedLocalTime =
|
|
originalDate.getTime() -
|
|
originalDate.getTimezoneOffset() * 60000;
|
|
expect(result.getTime()).toBe(expectedLocalTime);
|
|
});
|
|
|
|
test('uses timestamp without timezone conversion', () => {
|
|
const timestamp = 1673776245123; // 2023-01-15T10:30:45.123Z
|
|
const print = { timestamp };
|
|
const result = getPrintLocalDate(print);
|
|
expect(result).toBeInstanceOf(Date);
|
|
expect(result.getTime()).toBe(timestamp);
|
|
});
|
|
|
|
test('prefers createdAt over timestamp', () => {
|
|
const print = {
|
|
createdAt: '2023-01-15T10:30:45.123Z',
|
|
timestamp: 1673000000000 // Different timestamp
|
|
};
|
|
const result = getPrintLocalDate(print);
|
|
// Should use createdAt, not timestamp
|
|
const originalDate = new Date('2023-01-15T10:30:45.123Z');
|
|
const expectedLocalTime =
|
|
originalDate.getTime() -
|
|
originalDate.getTimezoneOffset() * 60000;
|
|
expect(result.getTime()).toBe(expectedLocalTime);
|
|
});
|
|
|
|
test('defaults to current date with timezone adjustment', () => {
|
|
const print = {};
|
|
const result = getPrintLocalDate(print);
|
|
|
|
expect(result).toBeInstanceOf(Date);
|
|
// Should be approximately current time with timezone offset
|
|
const currentDate = new Date();
|
|
const expectedLocalTime =
|
|
currentDate.getTime() - currentDate.getTimezoneOffset() * 60000;
|
|
// Allow some tolerance for execution time
|
|
expect(Math.abs(result.getTime() - expectedLocalTime)).toBeLessThan(
|
|
1000
|
|
);
|
|
});
|
|
|
|
test('handles invalid createdAt gracefully', () => {
|
|
const print = { createdAt: 'invalid-date' };
|
|
const result = getPrintLocalDate(print);
|
|
expect(result).toBeInstanceOf(Date);
|
|
// Should fall back to current date when createdAt is invalid
|
|
});
|
|
|
|
test('handles null/undefined inputs', () => {
|
|
expect(getPrintLocalDate({})).toBeInstanceOf(Date);
|
|
expect(getPrintLocalDate({ createdAt: null })).toBeInstanceOf(Date);
|
|
expect(getPrintLocalDate({ timestamp: null })).toBeInstanceOf(Date);
|
|
});
|
|
});
|
|
|
|
describe('getEmojiFileName', () => {
|
|
test('creates animated filename with all properties', () => {
|
|
const emoji = {
|
|
name: 'happy',
|
|
animationStyle: 'bounce',
|
|
frames: 10,
|
|
framesOverTime: 30,
|
|
loopStyle: 'loop'
|
|
};
|
|
const result = getEmojiFileName(emoji);
|
|
expect(result).toBe(
|
|
'happy_bounceanimationStyle_10frames_30fps_looploopStyle.png'
|
|
);
|
|
});
|
|
|
|
test('creates animated filename with default loopStyle', () => {
|
|
const emoji = {
|
|
name: 'wave',
|
|
animationStyle: 'wiggle',
|
|
frames: 5,
|
|
framesOverTime: 15
|
|
};
|
|
const result = getEmojiFileName(emoji);
|
|
expect(result).toBe(
|
|
'wave_wiggleanimationStyle_5frames_15fps_linearloopStyle.png'
|
|
);
|
|
});
|
|
|
|
test('creates static filename without frames', () => {
|
|
const emoji = {
|
|
name: 'smile',
|
|
animationStyle: 'static'
|
|
};
|
|
const result = getEmojiFileName(emoji);
|
|
expect(result).toBe('smile_staticanimationStyle.png');
|
|
});
|
|
|
|
test('treats zero frames as static', () => {
|
|
const emoji = {
|
|
name: 'neutral',
|
|
animationStyle: 'none',
|
|
frames: 0,
|
|
framesOverTime: 0
|
|
};
|
|
const result = getEmojiFileName(emoji);
|
|
expect(result).toBe('neutral_noneanimationStyle.png');
|
|
});
|
|
|
|
test('handles missing name gracefully', () => {
|
|
const emoji = {
|
|
animationStyle: 'bounce',
|
|
frames: 5,
|
|
framesOverTime: 10
|
|
};
|
|
const result = getEmojiFileName(emoji);
|
|
expect(result).toContain('undefined_bounceanimationStyle');
|
|
});
|
|
|
|
test('handles missing animationStyle', () => {
|
|
const emoji = {
|
|
name: 'test',
|
|
frames: 3,
|
|
framesOverTime: 20
|
|
};
|
|
const result = getEmojiFileName(emoji);
|
|
expect(result).toContain('test_undefinedanimationStyle');
|
|
});
|
|
|
|
test('handles special characters in name', () => {
|
|
const emoji = {
|
|
name: 'emoji-with_special.chars',
|
|
animationStyle: 'bounce',
|
|
frames: 8,
|
|
framesOverTime: 24,
|
|
loopStyle: 'pingpong'
|
|
};
|
|
const result = getEmojiFileName(emoji);
|
|
expect(result).toBe(
|
|
'emoji-with_special.chars_bounceanimationStyle_8frames_24fps_pingpongloopStyle.png'
|
|
);
|
|
});
|
|
|
|
test('handles edge case values', () => {
|
|
const emoji = {
|
|
name: '',
|
|
animationStyle: '',
|
|
frames: -1,
|
|
framesOverTime: 0,
|
|
loopStyle: ''
|
|
};
|
|
const result = getEmojiFileName(emoji);
|
|
// Should still generate a valid filename structure
|
|
expect(result).toContain('animationStyle');
|
|
expect(result).toContain('.png');
|
|
});
|
|
});
|
|
|
|
describe('integration and edge cases', () => {
|
|
test('getPrintFileName produces valid file names', () => {
|
|
const testCases = [
|
|
{
|
|
print: {
|
|
authorName: 'ValidUser',
|
|
createdAt: '2023-12-31T23:59:59.999Z',
|
|
id: 'print_test123'
|
|
},
|
|
expectValid: true
|
|
},
|
|
{
|
|
print: {
|
|
authorName: '',
|
|
createdAt: '2023-01-01T00:00:00.000Z',
|
|
id: ''
|
|
},
|
|
expectValid: true
|
|
},
|
|
{
|
|
print: {},
|
|
expectValid: true
|
|
}
|
|
];
|
|
|
|
testCases.forEach(({ print, expectValid }) => {
|
|
const result = getPrintFileName(print);
|
|
if (expectValid) {
|
|
expect(result).toMatch(/.*\.png$/);
|
|
expect(result.length).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
});
|
|
|
|
test('date functions handle timezone consistency', () => {
|
|
const testDate = '2023-06-15T12:00:00.000Z';
|
|
const print = { createdAt: testDate };
|
|
|
|
const localDate = getPrintLocalDate(print);
|
|
const fileName = getPrintFileName({
|
|
...print,
|
|
authorName: 'test',
|
|
id: 'test'
|
|
});
|
|
|
|
// Both functions should produce consistent results
|
|
expect(localDate).toBeInstanceOf(Date);
|
|
expect(fileName).toMatch(
|
|
/test_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}\.\d{3}_test\.png/
|
|
);
|
|
});
|
|
|
|
test('emoji filename handles boundary conditions', () => {
|
|
const extremeCases = [
|
|
{ name: 'a'.repeat(100), animationStyle: 'test' },
|
|
{ name: 'テスト', animationStyle: 'unicode' },
|
|
{
|
|
name: 'test',
|
|
animationStyle: 'test',
|
|
frames: 999,
|
|
framesOverTime: 999
|
|
}
|
|
];
|
|
|
|
extremeCases.forEach((emoji) => {
|
|
const result = getEmojiFileName(emoji);
|
|
expect(typeof result).toBe('string');
|
|
expect(result.endsWith('.png')).toBe(true);
|
|
});
|
|
});
|
|
});
|
|
});
|