themeLoader.test.mjs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import test from 'node:test'
  2. import assert from 'node:assert/strict'
  3. function installThemeDom () {
  4. const styleEl = { textContent: '' }
  5. const body = { attributes: {}, setAttribute (name, value) { this.attributes[name] = value } }
  6. globalThis.document = {
  7. getElementById: (id) => (id === 'theme-style' ? styleEl : null),
  8. createElement: () => styleEl,
  9. head: { appendChild: () => {} },
  10. body
  11. }
  12. return { styleEl, body }
  13. }
  14. test('applyThemeStyles times out when the response body stalls', async (t) => {
  15. const originalFetch = globalThis.fetch
  16. const originalDocument = globalThis.document
  17. const originalAbortSignal = globalThis.AbortSignal
  18. t.after(() => {
  19. globalThis.fetch = originalFetch
  20. globalThis.document = originalDocument
  21. globalThis.AbortSignal = originalAbortSignal
  22. })
  23. installThemeDom()
  24. globalThis.AbortSignal = {
  25. timeout () {
  26. const controller = new AbortController()
  27. setTimeout(() => controller.abort(), 50)
  28. return controller.signal
  29. }
  30. }
  31. globalThis.fetch = (_url, options) => Promise.resolve({
  32. ok: true,
  33. status: 200,
  34. text () {
  35. return new Promise((_resolve, reject) => {
  36. options.signal.addEventListener('abort', () => {
  37. reject(new DOMException('The operation was aborted.', 'AbortError'))
  38. })
  39. })
  40. }
  41. })
  42. const { applyThemeStyles } = await import('./themeLoader.js')
  43. await assert.rejects(
  44. () => applyThemeStyles(''),
  45. (err) => err.name === 'AbortError' || err.name === 'TimeoutError'
  46. )
  47. })