import test from 'node:test'; import assert from 'node:assert/strict'; import { FileDownloader } from '../js/services/file-downloader.js'; import { FileViewer } from '../js/viewer/file-viewer.js'; class FakeElement { constructor(tagName = 'div') { this.tagName = tagName.toUpperCase(); this.children = []; this.attributes = new Map(); this.dataset = {}; this.eventListeners = new Map(); this.style = {}; this.className = ''; this.href = ''; this.src = ''; this.title = ''; this.textContent = ''; this.innerHTML = ''; this.download = ''; } append(...nodes) { this.children.push(...nodes); } appendChild(node) { this.children.push(node); return node; } prepend(node) { this.children.unshift(node); return node; } removeChild(node) { this.children = this.children.filter(child => child !== node); return node; } replaceChildren(...nodes) { this.children = [...nodes]; } remove() { this.removed = true; } setAttribute(name, value) { this.attributes.set(name, String(value)); } getAttribute(name) { return this.attributes.get(name); } removeAttribute(name) { this.attributes.delete(name); } addEventListener(type, handler) { this.eventListeners.set(type, handler); } click() { this.clicked = true; } } function installViewerDom(search) { const previous = { document: globalThis.document, window: globalThis.window, URL: globalThis.URL, fetch: globalThis.fetch, setTimeout: globalThis.setTimeout, consoleError: console.error, consoleWarn: console.warn, }; const elements = { title: new FakeElement('h1'), type: new FakeElement('span'), download: new FakeElement('a'), content: new FakeElement('main'), }; const body = new FakeElement('body'); const created = []; globalThis.document = { title: '', body, getElementById(id) { return { 'viewer-title': elements.title, 'viewer-type': elements.type, 'viewer-download': elements.download, 'viewer-content': elements.content, }[id]; }, createElement(tagName) { const node = new FakeElement(tagName); created.push(node); return node; }, }; globalThis.window = { location: { search }, open(url) { this.openedUrl = url; }, }; globalThis.URL = { createObjectURL() { return 'blob:tapops-download'; }, revokeObjectURL(url) { this.revokedUrl = url; }, }; globalThis.setTimeout = callback => { callback(); return 1; }; console.error = () => {}; console.warn = () => {}; return { elements, created, restore() { globalThis.document = previous.document; globalThis.window = previous.window; globalThis.URL = previous.URL; globalThis.fetch = previous.fetch; globalThis.setTimeout = previous.setTimeout; console.error = previous.consoleError; console.warn = previous.consoleWarn; }, }; } test('repository download fetches the Directus original-file URL', async (t) => { const { created, restore } = installViewerDom(''); t.after(restore); let fetchedUrl = ''; globalThis.fetch = async (url) => { fetchedUrl = url; return { ok: true, blob: async () => new Blob(['docx']), }; }; await FileDownloader.download('https://api.ifuntanhub.dev/assets/docx-id', 'Form KP.docx'); const clickedAnchor = created.find(node => node.tagName === 'A' && node.clicked); assert.equal(fetchedUrl, 'https://api.ifuntanhub.dev/assets/docx-id?download'); assert.equal(clickedAnchor.download, 'Form KP.docx'); }); test('DOCX preview renders Microsoft Office Online Viewer iframe', async (t) => { const { elements, restore } = installViewerDom('?id=docx-id&name=Form%20KP.docx&type=docx'); t.after(restore); await new FileViewer().init(); const iframe = elements.content.children[0]; const assetUrl = 'https://api.ifuntanhub.dev/assets/docx-id'; assert.equal(iframe.tagName, 'IFRAME'); assert.equal(iframe.className, 'viewer-office-frame'); assert.equal(iframe.src, `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(assetUrl)}`); }); test('viewer download uses the Directus original-file URL', async (t) => { const { elements, created, restore } = installViewerDom('?id=pdf-id&name=Panduan.pdf&type=pdf'); t.after(restore); let fetchedUrl = ''; globalThis.fetch = async (url) => { fetchedUrl = url; return { ok: true, headers: { get: () => null }, blob: async () => new Blob(['pdf']), }; }; await new FileViewer().init(); await elements.download.eventListeners.get('click')({ preventDefault() {} }); const clickedAnchor = created.find(node => node.tagName === 'A' && node.clicked); assert.equal(fetchedUrl, 'https://api.ifuntanhub.dev/assets/pdf-id?download'); assert.equal(clickedAnchor.download, 'Panduan.pdf'); });