godcrm/pes-core/platform/test-base.js
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

800 lines
24 KiB
JavaScript

// ============================================================
// Tests for PES Platform — Base Adapter
// ============================================================
import { strict as assert } from 'node:assert';
import { EventEmitter } from 'node:events';
import { PesPlatformAdapter, RENDER_MODE, PRESENCE, MEDIA_TYPE } from './base.js';
let passed = 0;
let total = 0;
function test(name, fn) {
total++;
try {
fn();
passed++;
console.log(`${name}`);
} catch (err) {
console.log(`${name}: ${err.message}`);
}
}
async function testAsync(name, fn) {
total++;
try {
await fn();
passed++;
console.log(`${name}`);
} catch (err) {
console.log(`${name}: ${err.message}`);
}
}
// ── Mock PES ────────────────────────────────────────────────
class MockPes extends EventEmitter {
constructor() {
super();
this.name = 'Тестик';
this.ownerId = 'nikitron';
this.mode = 'active';
this._reactions = [];
}
react(expressionId, reaction) {
this._reactions.push({ expressionId, reaction });
}
}
// ── Test Adapter (concrete implementation) ──────────────────
class TestAdapter extends PesPlatformAdapter {
constructor(pes, config = {}) {
super(pes, { platformName: 'test', ...config });
this.sentMessages = [];
this.collecting = false;
this.presenceState = null;
}
async sendMessage(output) {
const msgId = `msg_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
this.sentMessages.push({ output, msgId });
return msgId;
}
async startCollecting() {
this.collecting = true;
}
async stopCollecting() {
this.collecting = false;
}
async setPresence(state) {
this.presenceState = state;
}
}
// ── Mock ExpressionResult ───────────────────────────────────
function mockExpressionResult(overrides = {}) {
const mockExpression = {
bodyKey: 'butt_wiggle_fast',
voiceKey: 'bark_excitement',
glyphKeys: ['paw', 'arrow', 'heart'],
renderBody() { return '~🍑~🍑~'; },
renderVoice() { return 'ГАВгавгавгавГАВ!'; },
renderGlyphs() { return '🐾→💛'; },
toJSON() {
return {
id: this.id || 'expr_test',
bodyKey: this.bodyKey,
voiceKey: this.voiceKey,
glyphKeys: this.glyphKeys,
};
},
...overrides.expression,
};
return {
id: 'er_test_001',
expression: mockExpression,
priority: 50,
triggerName: 'owner_returned',
combo: null,
suppressed: false,
shouldNotify: false,
emotionSnapshot: { current: 'happy', intensity: 0.7 },
platformHints: {},
timestamp: Date.now(),
...overrides,
};
}
// ── TESTS ───────────────────────────────────────────────────
console.log('\n══════ PesPlatformAdapter — Constructor ══════');
test('creates adapter with pes', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter.platformName, 'test');
assert.equal(adapter.renderMode, RENDER_MODE.FULL);
assert.equal(adapter.isConnected, false);
});
test('throws without pes', () => {
assert.throws(() => new TestAdapter(null), /requires a Pes instance/);
});
test('custom config', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes, { renderMode: RENDER_MODE.COMPACT });
assert.equal(adapter.renderMode, RENDER_MODE.COMPACT);
});
test('initial stats are zero', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.deepEqual(adapter.deliveryStats, { sent: 0, failed: 0, reactions: 0 });
});
console.log('\n══════ Media Registry ══════');
test('registerMedia and getMedia', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.STICKER, 'butt_wiggle_fast', 'sticker_file_id_123');
assert.equal(adapter.getMedia(MEDIA_TYPE.STICKER, 'butt_wiggle_fast'), 'sticker_file_id_123');
});
test('getMedia returns null for missing', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter.getMedia(MEDIA_TYPE.STICKER, 'nonexistent'), null);
});
test('loadMediaPack — bulk load', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.loadMediaPack({
[MEDIA_TYPE.STICKER]: {
'butt_wiggle_fast': 'sticker_1',
'sploot': 'sticker_2',
'play_bow': 'sticker_3',
},
[MEDIA_TYPE.SOUND]: {
'bark_excitement': 'bark.ogg',
'whine': 'whine.ogg',
},
[MEDIA_TYPE.REACTION]: {
'happy': '❤️',
'angry': '😡',
},
});
assert.equal(adapter.getMedia(MEDIA_TYPE.STICKER, 'butt_wiggle_fast'), 'sticker_1');
assert.equal(adapter.getMedia(MEDIA_TYPE.STICKER, 'sploot'), 'sticker_2');
assert.equal(adapter.getMedia(MEDIA_TYPE.SOUND, 'bark_excitement'), 'bark.ogg');
assert.equal(adapter.getMedia(MEDIA_TYPE.REACTION, 'happy'), '❤️');
});
test('hasMedia', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.STICKER, 'test_key', 'value');
assert.equal(adapter.hasMedia(MEDIA_TYPE.STICKER, 'test_key'), true);
assert.equal(adapter.hasMedia(MEDIA_TYPE.STICKER, 'missing'), false);
});
test('getMediaKeys', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.STICKER, 'a', '1');
adapter.registerMedia(MEDIA_TYPE.STICKER, 'b', '2');
const keys = adapter.getMediaKeys(MEDIA_TYPE.STICKER);
assert.deepEqual(keys, ['a', 'b']);
});
console.log('\n══════ Render Expression — FULL mode ══════');
test('renders full expression with text fallback', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
const result = mockExpressionResult();
const output = adapter.renderExpression(result);
assert.ok(output);
assert.equal(output.text, '🐾→💛');
assert.equal(output.sticker, '~🍑~🍑~'); // falls back to renderBody()
assert.ok(output.meta.voiceText);
assert.equal(output.expressionId, 'er_test_001');
});
test('renders with sticker from registry', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.STICKER, 'butt_wiggle_fast', 'CAACAgI_corgi_wiggle');
const result = mockExpressionResult();
const output = adapter.renderExpression(result);
assert.equal(output.sticker, 'CAACAgI_corgi_wiggle');
});
test('renders with sticker from emotion fallback', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.STICKER, 'happy', 'CAACAgI_happy_corgi');
const result = mockExpressionResult();
const output = adapter.renderExpression(result);
// bodyKey 'butt_wiggle_fast' not in registry, but emotion 'happy' is
assert.equal(output.sticker, 'CAACAgI_happy_corgi');
});
test('renders with sound from registry', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.SOUND, 'bark_excitement', 'bark.ogg');
const result = mockExpressionResult();
const output = adapter.renderExpression(result);
assert.equal(output.sound, 'bark.ogg');
assert.ok(output.meta.voiceText);
});
test('renders reaction from emotion registry', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.REACTION, 'happy', '🐾');
const result = mockExpressionResult();
const output = adapter.renderExpression(result);
assert.equal(output.reaction, '🐾');
});
test('renders reaction from platformHints', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
const result = mockExpressionResult({ platformHints: { reaction: '🔥' } });
const output = adapter.renderExpression(result);
assert.equal(output.reaction, '🔥');
});
test('null expression returns null', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter.renderExpression(null), null);
assert.equal(adapter.renderExpression({ expression: null }), null);
});
console.log('\n══════ Render Expression — COMPACT mode ══════');
test('compact mode: only glyphs', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes, { renderMode: RENDER_MODE.COMPACT });
const result = mockExpressionResult();
const output = adapter.renderExpression(result);
assert.equal(output.text, '🐾→💛');
assert.equal(output.sticker, null); // no body in compact
assert.equal(output.sound, null); // no voice in compact
});
console.log('\n══════ Render Expression — DEBUG mode ══════');
test('debug mode: includes internal state', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes, { renderMode: RENDER_MODE.DEBUG });
const result = mockExpressionResult();
const output = adapter.renderExpression(result);
assert.ok(output.meta.emotion);
assert.equal(output.meta.triggerName, 'owner_returned');
assert.equal(output.meta.emotion.current, 'happy');
});
console.log('\n══════ Render Expression — RICH mode ══════');
test('rich mode: sticker + caption', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes, { renderMode: RENDER_MODE.RICH });
adapter.registerMedia(MEDIA_TYPE.STICKER, 'butt_wiggle_fast', 'sticker_rich');
const result = mockExpressionResult();
const output = adapter.renderExpression(result);
assert.equal(output.sticker, 'sticker_rich');
assert.ok(output.meta.caption);
});
console.log('\n══════ Delivery ══════');
await testAsync('deliver sends message and tracks', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
const result = mockExpressionResult();
const success = await adapter.deliver(result);
assert.equal(success, true);
assert.equal(adapter.stats.sent, 1);
assert.equal(adapter.sentMessages.length, 1);
assert.equal(adapter.trackedMessages, 1);
});
await testAsync('deliver skips suppressed', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
const result = mockExpressionResult({ suppressed: true });
const success = await adapter.deliver(result);
assert.equal(success, false);
assert.equal(adapter.stats.sent, 0);
});
await testAsync('deliver tracks failure', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
// Override sendMessage to throw
adapter.sendMessage = async () => { throw new Error('network error'); };
const result = mockExpressionResult();
const success = await adapter.deliver(result);
assert.equal(success, false);
assert.equal(adapter.stats.failed, 1);
});
await testAsync('deliver null returns false', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(await adapter.deliver(null), false);
});
console.log('\n══════ Feedback Bridge ══════');
await testAsync('onUserReaction feeds back to PES', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
// Deliver a message first to create tracking
const result = mockExpressionResult();
await adapter.deliver(result);
// Get the platform message ID
const msgId = adapter.sentMessages[0].msgId;
// Simulate owner reaction
adapter.onUserReaction(msgId, '👍', 'nikitron', { isOwner: true, speed_ms: 2000 });
assert.equal(pes._reactions.length, 1);
assert.equal(pes._reactions[0].expressionId, 'er_test_001');
assert.equal(pes._reactions[0].reaction.from, 'owner');
assert.equal(pes._reactions[0].reaction.type, 'emoji_positive');
assert.equal(pes._reactions[0].reaction.value, '👍');
assert.equal(adapter.stats.reactions, 1);
});
test('onUserReaction — unknown message ignored', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.onUserReaction('unknown_msg', '👍', 'nikitron');
assert.equal(pes._reactions.length, 0);
});
await testAsync('onUserReaction — group member', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
const result = mockExpressionResult();
await adapter.deliver(result);
const msgId = adapter.sentMessages[0].msgId;
adapter.onUserReaction(msgId, '😂', 'dev1', { isOwner: false });
assert.equal(pes._reactions[0].reaction.from, 'group:dev1');
assert.equal(pes._reactions[0].reaction.type, 'emoji_positive');
});
await testAsync('onUserReaction — negative emoji', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
const result = mockExpressionResult();
await adapter.deliver(result);
const msgId = adapter.sentMessages[0].msgId;
adapter.onUserReaction(msgId, '👎', 'nikitron', { isOwner: true });
assert.equal(pes._reactions[0].reaction.type, 'emoji_negative');
});
await testAsync('onUserReaction — text reaction', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
const result = mockExpressionResult();
await adapter.deliver(result);
const msgId = adapter.sentMessages[0].msgId;
adapter.onUserReaction(msgId, 'молодец!', 'nikitron', { isOwner: true });
assert.equal(pes._reactions[0].reaction.type, 'text');
assert.equal(pes._reactions[0].reaction.value, 'молодец!');
});
console.log('\n══════ Reaction Classification ══════');
test('classifies positive emojis', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter._classifyReaction('👍'), 'emoji_positive');
assert.equal(adapter._classifyReaction('❤️'), 'emoji_positive');
assert.equal(adapter._classifyReaction('🔥'), 'emoji_positive');
assert.equal(adapter._classifyReaction('😂'), 'emoji_positive');
assert.equal(adapter._classifyReaction('💯'), 'emoji_positive');
});
test('classifies negative emojis', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter._classifyReaction('👎'), 'emoji_negative');
assert.equal(adapter._classifyReaction('😡'), 'emoji_negative');
assert.equal(adapter._classifyReaction('💩'), 'emoji_negative');
});
test('classifies text', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter._classifyReaction('молодец'), 'text');
assert.equal(adapter._classifyReaction('плохо'), 'text');
});
test('classifies silence', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter._classifyReaction(null), 'silence');
assert.equal(adapter._classifyReaction(''), 'silence');
});
console.log('\n══════ Message Tracking ══════');
test('trackMessage and lookup', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.trackMessage('expr_1', 'msg_1');
adapter.trackMessage('expr_2', 'msg_2');
assert.equal(adapter._lookupExpression('msg_1'), 'expr_1');
assert.equal(adapter._lookupExpression('msg_2'), 'expr_2');
assert.equal(adapter._lookupExpression('msg_3'), null);
});
test('trackMessage evicts oldest when full', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.messageMapMaxSize = 3;
adapter.trackMessage('expr_1', 'msg_1');
adapter.trackMessage('expr_2', 'msg_2');
adapter.trackMessage('expr_3', 'msg_3');
adapter.trackMessage('expr_4', 'msg_4'); // should evict msg_1
assert.equal(adapter._lookupExpression('msg_1'), null); // evicted
assert.equal(adapter._lookupExpression('msg_4'), 'expr_4');
assert.equal(adapter.trackedMessages, 3);
});
console.log('\n══════ Listening ══════');
await testAsync('startListening sets connected and presence', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
await adapter.startListening();
assert.equal(adapter.isConnected, true);
assert.equal(adapter.collecting, true);
assert.equal(adapter.presenceState, PRESENCE.ONLINE);
});
await testAsync('stopListening disconnects', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
await adapter.startListening();
await adapter.stopListening();
assert.equal(adapter.isConnected, false);
assert.equal(adapter.collecting, false);
assert.equal(adapter.presenceState, PRESENCE.OFFLINE);
});
console.log('\n══════ Auto-delivery on PES expression event ══════');
await testAsync('auto-delivers when connected', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
await adapter.startListening();
// Simulate PES emitting an expression
const result = mockExpressionResult();
pes.emit('expression', result);
// Wait for async delivery
await new Promise(r => setTimeout(r, 50));
assert.equal(adapter.sentMessages.length, 1);
assert.equal(adapter.stats.sent, 1);
});
await testAsync('does not deliver when disconnected', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
// NOT connected
const result = mockExpressionResult();
pes.emit('expression', result);
await new Promise(r => setTimeout(r, 50));
assert.equal(adapter.sentMessages.length, 0);
});
console.log('\n══════ Lifecycle Events ══════');
await testAsync('onBorn emits lifecycle event', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
let received = null;
adapter.on('lifecycle', (data) => { received = data; });
pes.emit('born', { name: 'Тестик' });
await new Promise(r => setTimeout(r, 20));
assert.ok(received);
assert.equal(received.event, 'born');
});
await testAsync('onWake sets presence ONLINE', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
pes.emit('wake', {});
await new Promise(r => setTimeout(r, 20));
assert.equal(adapter.presenceState, PRESENCE.ONLINE);
});
await testAsync('onSleep sets presence SLEEPING', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
pes.emit('sleep', {});
await new Promise(r => setTimeout(r, 20));
assert.equal(adapter.presenceState, PRESENCE.SLEEPING);
});
await testAsync('onRunaway sets presence OFFLINE', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
pes.emit('runaway', { letter: 'прощай' });
await new Promise(r => setTimeout(r, 20));
assert.equal(adapter.presenceState, PRESENCE.OFFLINE);
});
await testAsync('onModeChange updates presence', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
pes.emit('modeChange', { oldMode: 'active', newMode: 'idle' });
await new Promise(r => setTimeout(r, 20));
assert.equal(adapter.presenceState, PRESENCE.IDLE);
pes.emit('modeChange', { oldMode: 'idle', newMode: 'sleeping' });
await new Promise(r => setTimeout(r, 20));
assert.equal(adapter.presenceState, PRESENCE.SLEEPING);
});
console.log('\n══════ Render Mode ══════');
test('setRenderMode changes mode', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.setRenderMode(RENDER_MODE.DEBUG);
assert.equal(adapter.renderMode, RENDER_MODE.DEBUG);
});
test('setRenderMode ignores invalid', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.setRenderMode('invalid_mode');
assert.equal(adapter.renderMode, RENDER_MODE.FULL); // unchanged
});
console.log('\n══════ Destroy ══════');
test('destroy cleans up', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.trackMessage('e1', 'm1');
adapter.destroy();
assert.equal(adapter.isConnected, false);
assert.equal(adapter.trackedMessages, 0);
});
console.log('\n══════ Custom Emoji in Glyphs ══════');
test('custom emoji replaces default glyphs', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.EMOJI, 'paw', '🐕'); // custom emoji for 'paw' glyph
const result = mockExpressionResult();
const output = adapter.renderExpression(result);
// Should contain custom emoji
assert.ok(output.text.includes('🐕'));
});
console.log('\n══════ Format Methods ══════');
test('formatBody — no body returns null', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter.formatBody(null, {}), null);
});
test('formatVoice — no voice returns null', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter.formatVoice(null, {}), null);
});
test('formatGlyphs — empty returns null', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter.formatGlyphs([], {}), null);
assert.equal(adapter.formatGlyphs(null, {}), null);
});
test('formatReaction — null returns null', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
assert.equal(adapter.formatReaction(null), null);
});
test('formatAnimation — with registry', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.ANIMATION, 'butt_wiggle_fast', 'corgi_run.gif');
const result = mockExpressionResult();
assert.equal(adapter.formatAnimation('butt_wiggle_fast', result), 'corgi_run.gif');
});
test('formatAnimation — emotion fallback', () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.registerMedia(MEDIA_TYPE.ANIMATION, 'happy', 'happy_corgi.gif');
const result = mockExpressionResult();
assert.equal(adapter.formatAnimation('unknown_body', result), 'happy_corgi.gif');
});
console.log('\n══════ Events Emitted ══════');
await testAsync('emits delivered event', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
let deliveredEvent = null;
adapter.on('delivered', (data) => { deliveredEvent = data; });
await adapter.deliver(mockExpressionResult());
assert.ok(deliveredEvent);
assert.equal(deliveredEvent.expressionId, 'er_test_001');
assert.ok(deliveredEvent.messageId);
});
await testAsync('emits deliveryFailed event', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
adapter.sendMessage = async () => { throw new Error('timeout'); };
let failedEvent = null;
adapter.on('deliveryFailed', (data) => { failedEvent = data; });
await adapter.deliver(mockExpressionResult());
assert.ok(failedEvent);
assert.equal(failedEvent.error, 'timeout');
});
await testAsync('emits reactionProcessed event', async () => {
const pes = new MockPes();
const adapter = new TestAdapter(pes);
let reactionEvent = null;
adapter.on('reactionProcessed', (data) => { reactionEvent = data; });
await adapter.deliver(mockExpressionResult());
const msgId = adapter.sentMessages[0].msgId;
adapter.onUserReaction(msgId, '🔥', 'nikitron');
assert.ok(reactionEvent);
assert.equal(reactionEvent.reaction, '🔥');
});
console.log('\n══════ Constants ══════');
test('RENDER_MODE constants', () => {
assert.equal(RENDER_MODE.FULL, 'full');
assert.equal(RENDER_MODE.COMPACT, 'compact');
assert.equal(RENDER_MODE.RICH, 'rich');
assert.equal(RENDER_MODE.DEBUG, 'debug');
});
test('PRESENCE constants', () => {
assert.equal(PRESENCE.ONLINE, 'online');
assert.equal(PRESENCE.TYPING, 'typing');
assert.equal(PRESENCE.SLEEPING, 'sleeping');
assert.equal(PRESENCE.OFFLINE, 'offline');
});
test('MEDIA_TYPE constants', () => {
assert.equal(MEDIA_TYPE.STICKER, 'sticker');
assert.equal(MEDIA_TYPE.ANIMATION, 'animation');
assert.equal(MEDIA_TYPE.SOUND, 'sound');
assert.equal(MEDIA_TYPE.EMOJI, 'emoji');
assert.equal(MEDIA_TYPE.REACTION, 'reaction');
});
// ── SUMMARY ─────────────────────────────────────────────────
console.log(`\n${'═'.repeat(50)}`);
console.log(` РЕЗУЛЬТАТ: ${passed}/${total} тестов пройдено`);
console.log(`${'═'.repeat(50)}\n`);
if (passed !== total) process.exit(1);