messenzy-widget/tests/unit/config.test.ts
Serge RAKOTO HARRY-NAIVO 8d0696584c feat(config): parse data-shadow attribute on script tag
Adds the boolean field consumed by the upcoming Shadow DOM mount path.
Strict equality with the string "true" — anything else (absent, "false",
"1", "yes", empty) yields false, so accidental opt-in is impossible.

Tests cover the full parseConfig surface (required fields, server-url
derivation, position default) plus the new shadow attribute parsing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:52:27 +02:00

119 lines
3.3 KiB
TypeScript

import { describe, it, expect, beforeEach } from 'vitest';
import { parseConfig } from '@/config';
function createScript(
attrs: Record<string, string>,
src = 'https://cdn.example.com/messenzy-widget.iife.js',
): HTMLScriptElement {
const script = document.createElement('script');
script.src = src;
for (const [key, value] of Object.entries(attrs)) {
script.setAttribute(key, value);
}
document.head.appendChild(script);
return script;
}
beforeEach(() => {
document.head.innerHTML = '';
document.body.innerHTML = '';
});
describe('parseConfig', () => {
it('returns null when no script with data-bot-id is present', () => {
expect(parseConfig()).toBeNull();
});
it('returns null when data-api-key is missing', () => {
createScript({ 'data-bot-id': 'b1' });
expect(parseConfig()).toBeNull();
});
it('returns null when data-bot-id is missing', () => {
createScript({ 'data-api-key': 'k1' });
expect(parseConfig()).toBeNull();
});
it('parses required fields', () => {
createScript({ 'data-bot-id': 'b1', 'data-api-key': 'k1' });
const config = parseConfig();
expect(config).not.toBeNull();
expect(config?.botId).toBe('b1');
expect(config?.apiKey).toBe('k1');
});
it('derives serverUrl from script src when data-server-url absent', () => {
createScript(
{ 'data-bot-id': 'b1', 'data-api-key': 'k1' },
'https://widgets.example.com/path/messenzy.iife.js',
);
expect(parseConfig()?.serverUrl).toBe('https://widgets.example.com');
});
it('respects explicit data-server-url override', () => {
createScript({
'data-bot-id': 'b1',
'data-api-key': 'k1',
'data-server-url': 'https://api.foo.test',
});
expect(parseConfig()?.serverUrl).toBe('https://api.foo.test');
});
it('defaults position to bottom-right', () => {
createScript({ 'data-bot-id': 'b1', 'data-api-key': 'k1' });
expect(parseConfig()?.position).toBe('bottom-right');
});
it('parses position bottom-left', () => {
createScript({
'data-bot-id': 'b1',
'data-api-key': 'k1',
'data-position': 'bottom-left',
});
expect(parseConfig()?.position).toBe('bottom-left');
});
describe('shadow attribute (PR B opt-in)', () => {
it('shadow=false when data-shadow absent', () => {
createScript({ 'data-bot-id': 'b1', 'data-api-key': 'k1' });
expect(parseConfig()?.shadow).toBe(false);
});
it('shadow=true when data-shadow="true"', () => {
createScript({
'data-bot-id': 'b1',
'data-api-key': 'k1',
'data-shadow': 'true',
});
expect(parseConfig()?.shadow).toBe(true);
});
it('shadow=false when data-shadow="false"', () => {
createScript({
'data-bot-id': 'b1',
'data-api-key': 'k1',
'data-shadow': 'false',
});
expect(parseConfig()?.shadow).toBe(false);
});
it('shadow=false when data-shadow="" (empty)', () => {
createScript({
'data-bot-id': 'b1',
'data-api-key': 'k1',
'data-shadow': '',
});
expect(parseConfig()?.shadow).toBe(false);
});
it('shadow=false for unrecognized values (e.g. "1", "yes")', () => {
createScript({
'data-bot-id': 'b1',
'data-api-key': 'k1',
'data-shadow': '1',
});
expect(parseConfig()?.shadow).toBe(false);
});
});
});