mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-09-09 12:45:35 +00:00
82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
/**
|
|
* Tests for MeshCore Open rich-chat payload parsing (GIFs and reactions).
|
|
*
|
|
* Formats are ported from meshcore-open; see meshcoreOpenPayloads.ts.
|
|
*/
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import {
|
|
REACTION_EMOJIS,
|
|
giphyUrlForId,
|
|
parseGif,
|
|
parseReaction,
|
|
} from '../utils/meshcoreOpenPayloads';
|
|
|
|
describe('parseGif', () => {
|
|
it('parses a g:<id> payload', () => {
|
|
expect(parseGif('g:abc123')).toBe('abc123');
|
|
});
|
|
|
|
it('accepts ids with underscores and dashes', () => {
|
|
expect(parseGif('g:aB3_-xY')).toBe('aB3_-xY');
|
|
});
|
|
|
|
it('trims surrounding whitespace', () => {
|
|
expect(parseGif(' g:abc123 ')).toBe('abc123');
|
|
});
|
|
|
|
it('returns null for non-gif text', () => {
|
|
expect(parseGif('hello world')).toBeNull();
|
|
expect(parseGif('g:')).toBeNull();
|
|
expect(parseGif('g:abc 123')).toBeNull();
|
|
expect(parseGif('prefix g:abc')).toBeNull();
|
|
expect(parseGif('g:abc!')).toBeNull();
|
|
});
|
|
|
|
it('builds the Giphy media URL', () => {
|
|
expect(giphyUrlForId('abc123')).toBe('https://media.giphy.com/media/abc123/giphy.gif');
|
|
});
|
|
});
|
|
|
|
describe('parseReaction', () => {
|
|
it('decodes the first emoji (index 00)', () => {
|
|
const result = parseReaction('r:1a2b:00');
|
|
expect(result).toEqual({ emoji: REACTION_EMOJIS[0], targetHash: '1a2b' });
|
|
expect(result?.emoji).toBe('👍');
|
|
});
|
|
|
|
it('decodes a non-zero index', () => {
|
|
// index 0x06 -> first smiley (after the 6 quick emojis)
|
|
const result = parseReaction('r:ffff:06');
|
|
expect(result?.emoji).toBe(REACTION_EMOJIS[6]);
|
|
expect(result?.targetHash).toBe('ffff');
|
|
});
|
|
|
|
it('trims surrounding whitespace', () => {
|
|
expect(parseReaction(' r:1a2b:00 ')?.emoji).toBe('👍');
|
|
});
|
|
|
|
it('returns null for an out-of-range index', () => {
|
|
// 0xff (255) is beyond the emoji list length
|
|
expect(parseReaction('r:1a2b:ff')).toBeNull();
|
|
});
|
|
|
|
it('returns null for malformed reactions', () => {
|
|
expect(parseReaction('r:1a2b')).toBeNull();
|
|
expect(parseReaction('r:1a2:00')).toBeNull(); // hash too short
|
|
expect(parseReaction('r:1A2B:00')).toBeNull(); // uppercase hex not accepted
|
|
expect(parseReaction('r:1a2b:0')).toBeNull(); // index too short
|
|
expect(parseReaction('hello')).toBeNull();
|
|
});
|
|
|
|
it('exposes a stable, deduplication-free emoji index range', () => {
|
|
// 6 quick + 64 smileys + 33 gestures + 32 hearts + 49 objects
|
|
expect(REACTION_EMOJIS.length).toBe(184);
|
|
// every defined index decodes to a string
|
|
for (let i = 0; i < REACTION_EMOJIS.length; i++) {
|
|
const hex = i.toString(16).padStart(2, '0');
|
|
expect(parseReaction(`r:0000:${hex}`)?.emoji).toBe(REACTION_EMOJIS[i]);
|
|
}
|
|
});
|
|
});
|