68 lines
2.6 KiB
JavaScript
68 lines
2.6 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {readFileSync} from 'node:fs';
|
|
|
|
const listeners={};
|
|
const input={value:'',addEventListener:(name,handler)=>{listeners[`input:${name}`]=handler},focus:()=>{}};
|
|
const closeButton={addEventListener:(name,handler)=>{listeners[`close:${name}`]=handler}};
|
|
const hint={hidden:true,setAttribute:()=>{},querySelector:()=>closeButton};
|
|
const form={dataset:{chatCoachKey:'test-ticket'},action:'/tickets/example/reply/',querySelector:()=>input};
|
|
const renderedMessages=[];
|
|
let appendedHint=null;
|
|
|
|
globalThis.document={
|
|
body:{append:node=>{appendedHint=node}},
|
|
querySelectorAll:selector=>selector==='form[data-chat-coach]'?[form]:renderedMessages,
|
|
querySelector:selector=>selector==='[data-conversation]'?{}:null,
|
|
createElement:()=>hint,
|
|
};
|
|
globalThis.location={origin:'http://testserver',pathname:'/tickets/example/'};
|
|
globalThis.MutationObserver=class{constructor(handler){listeners.mutation=handler}observe(){}};
|
|
globalThis.setTimeout=handler=>{listeners.autoDismiss=handler;return 1};
|
|
globalThis.clearTimeout=()=>{delete listeners.autoDismiss};
|
|
|
|
let now=1_000_000;
|
|
Date.now=()=>now;
|
|
await import('../../static/js/chat-coach.js');
|
|
|
|
test('mounts guidance directly on body so collapsed forms cannot hide it',()=>{
|
|
assert.equal(appendedHint,hint);
|
|
assert.match(hint.className,/chat-coach-floating/);
|
|
});
|
|
|
|
test('shows guidance when the last two messages are at most two minutes apart',()=>{
|
|
renderedMessages.push(
|
|
{dataset:{chatCoachAt:String((now-40_000)/1000)}},
|
|
{dataset:{chatCoachAt:String((now-10_000)/1000)}},
|
|
);
|
|
listeners.mutation();
|
|
assert.equal(hint.hidden,false);
|
|
});
|
|
|
|
test('hides guidance when the last two messages are more than two minutes apart',()=>{
|
|
renderedMessages.splice(0,renderedMessages.length,
|
|
{dataset:{chatCoachAt:String((now-200_000)/1000)}},
|
|
{dataset:{chatCoachAt:String((now-10_000)/1000)}},
|
|
);
|
|
listeners.mutation();
|
|
assert.equal(hint.hidden,true);
|
|
});
|
|
|
|
test('guidance is configured to disappear automatically after three seconds',()=>{
|
|
const script=readFileSync('static/js/chat-coach.js','utf8');
|
|
assert.match(script,/autoDismissMs=3000/);
|
|
assert.match(script,/setTimeout\(\(\)=>dismiss\(\),autoDismissMs\)/);
|
|
assert.equal(typeof listeners.autoDismiss,'function');
|
|
});
|
|
|
|
test('large close button dismisses the guidance for the current page',()=>{
|
|
renderedMessages.splice(0,renderedMessages.length,
|
|
{dataset:{chatCoachAt:String((now-30_000)/1000)}},
|
|
{dataset:{chatCoachAt:String((now-5_000)/1000)}},
|
|
);
|
|
listeners.mutation();
|
|
assert.equal(hint.hidden,false);
|
|
listeners['close:click']();
|
|
assert.equal(hint.hidden,true);
|
|
});
|