template-function.test.ts 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455
  1. import nock from "nock";
  2. import {
  3. RENDER_ERROR,
  4. REQUEST_OBJECT_ERROR,
  5. METHOD,
  6. BASE_URL,
  7. RESPONSE_ERROR,
  8. DEFAULT_ALLOWED_CONTENT_TYPES,
  9. REQUEST_INIT_ERROR,
  10. REQUEST_INIT_GET
  11. } from "../config/config";
  12. import { JSDOM } from "jsdom";
  13. import createDOMPurify from "dompurify";
  14. import { compile, stringify } from "../../src/main";
  15. import {
  16. waeq,
  17. e,
  18. eq,
  19. eaeq,
  20. aeq,
  21. aeqe,
  22. createTestObj2,
  23. createTestObj3,
  24. createTestObj4
  25. } from "./functions";
  26. import sinon from "sinon";
  27. /**
  28. * Template function
  29. */
  30. const eq0 = stringify({
  31. src: `${BASE_URL}/api/test`,
  32. indicators: [
  33. {
  34. trigger: "pending",
  35. content: "<p>Loading...</p>"
  36. },
  37. {
  38. trigger: "pending",
  39. content: "<p>Loading...</p>"
  40. }
  41. ]
  42. });
  43. const eq1 = stringify({
  44. src: `${BASE_URL}/api/test`,
  45. indicators: [
  46. {
  47. trigger: 123 as any,
  48. content: "<p>Loading...</p>"
  49. }
  50. ]
  51. });
  52. const eq2 = stringify({
  53. src: `${BASE_URL}/api/test`,
  54. indicators: [
  55. {
  56. content: "<p>Loading...</p>"
  57. } as any
  58. ]
  59. });
  60. const eq3 = stringify({
  61. src: `${BASE_URL}/api/test`,
  62. indicators: [
  63. {
  64. trigger: 100 as any
  65. } as any
  66. ]
  67. });
  68. const eaeq1 = stringify({
  69. src: `${BASE_URL}/api/test`,
  70. initId: "1"
  71. });
  72. const aeq0 = stringify({
  73. src: `${BASE_URL}/api/test`,
  74. indicators: [
  75. {
  76. trigger: "pending",
  77. content: "<p>Loading...</p>"
  78. }
  79. ]
  80. });
  81. const aeq1 = stringify({
  82. src: `${BASE_URL}/api/test`,
  83. after: "click:#click"
  84. });
  85. const aeq2 = stringify({
  86. src: `${BASE_URL}/api/test`,
  87. after: "click:#click",
  88. indicators: [
  89. {
  90. trigger: "pending",
  91. content: "<p>Loading...</p>"
  92. }
  93. ]
  94. });
  95. const aeq3 = stringify({
  96. src: `${BASE_URL}/api/getFormComponent`,
  97. after: "submit:#form",
  98. method: "post"
  99. });
  100. const aeq4 = stringify({
  101. src: `${BASE_URL}/api/test`,
  102. indicators: [
  103. {
  104. trigger: 405,
  105. content: "<p>405</p>"
  106. }
  107. ]
  108. });
  109. const aeq5 = stringify({
  110. src: `${BASE_URL}/api/test`,
  111. indicators: [
  112. {
  113. trigger: "error",
  114. content: "<p>Error</p>"
  115. }
  116. ]
  117. });
  118. const aeq6 = stringify({
  119. src: `${BASE_URL}/api/test`,
  120. indicators: [
  121. {
  122. trigger: "rejected",
  123. content: "<p>Rejected</p>"
  124. }
  125. ]
  126. });
  127. const aeq7 = stringify({
  128. src: `${BASE_URL}/api/test`,
  129. indicators: [
  130. {
  131. trigger: 100,
  132. content: "<p>100</p>"
  133. }
  134. ]
  135. });
  136. const aeq8 = stringify({
  137. src: `${BASE_URL}/api/test`,
  138. after: "click:#click",
  139. repeat: false
  140. });
  141. const aeqe0 = stringify({
  142. src: `${BASE_URL}/api/test`,
  143. after: "click:#click",
  144. initId: "1"
  145. });
  146. const contentType1 = "application/octet-stream";
  147. describe("template function", () => {
  148. e(
  149. `only accepts the '${METHOD}' property in the REQUEST OBJECT as GET, POST, PUT, PATCH or DELETE`,
  150. () =>
  151. compile(
  152. createTestObj2(
  153. `<button>Click</button>{{ "src":"/api/test", "method": "test", "after": "click:#increment" }}`
  154. )
  155. )(),
  156. `${REQUEST_OBJECT_ERROR}: The "${METHOD}" property has only GET, POST, PUT, PATCH or DELETE values`
  157. );
  158. e(
  159. "throws an error if the EVENT TARGET doesn't exist",
  160. () => compile(`{{ "src":"/api/test", "after": "click:#increment" }}`)(),
  161. `${RENDER_ERROR}: EventTarget is undefined`
  162. );
  163. e(
  164. "throws an error if Memoization enabled without the Repetition mode enabled",
  165. () => compile(`{{ "src":"/api/test", "memo": true }}`)(),
  166. `${REQUEST_OBJECT_ERROR}: Memoization works in the enabled repetition mode`
  167. );
  168. e(
  169. `throws an error if the '${REQUEST_INIT_GET}' property in the RequestInit object is a function`,
  170. () => compile(createTestObj2(`{{ "src":"123" }}`))({ get: "" as any }),
  171. `${REQUEST_INIT_ERROR}: The "${REQUEST_INIT_GET}" property has a function value`
  172. );
  173. e(
  174. "throws an error if the value being passed is a number for RequestInit",
  175. () =>
  176. compile(createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`))(123 as any),
  177. `${REQUEST_INIT_ERROR}: The type of the value being passed does not match the supported types for RequestInit`
  178. );
  179. e(
  180. "throws an error if passed duplicate IDs for the RequestInit objects",
  181. () =>
  182. compile(createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`))([
  183. { id: "1", value: {} },
  184. { id: "1", value: {} }
  185. ]),
  186. `${REQUEST_INIT_ERROR}: ID with value "1" already exists`
  187. );
  188. e(
  189. "",
  190. () =>
  191. compile(createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`))([
  192. { id: 1, value: {} },
  193. { id: 1, value: {} }
  194. ]),
  195. `${REQUEST_INIT_ERROR}: ID with value 1 already exists`
  196. );
  197. e(
  198. "throws an error if the ID is not a string or a number",
  199. () =>
  200. compile(createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`))([
  201. { id: [] as any, value: {} },
  202. { id: 1, value: {} }
  203. ]),
  204. `${REQUEST_INIT_ERROR}: ID must be a string or a number`
  205. );
  206. e(
  207. "throws an error if the value is not an object for RequestInit object",
  208. () =>
  209. compile(createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`))([
  210. "123" as any,
  211. { id: 1, value: {} }
  212. ]),
  213. `${REQUEST_INIT_ERROR}: IdentificationRequestInit is of type object`
  214. );
  215. e(
  216. "throws an error if the ID or value is not present for RequestInit object",
  217. () =>
  218. compile(createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`))([
  219. {} as any,
  220. { id: 1, value: {} }
  221. ]),
  222. `${REQUEST_INIT_ERROR}: Missing "id" or "value" property`
  223. );
  224. e(
  225. "throws an error if Memoization enabled without the Repetition mode enabled",
  226. () =>
  227. compile(
  228. createTestObj2(
  229. `<button>Click</button>{{ "src":"/api/test", "after": "click:#increment", "memo": true, "repeat": false }}`
  230. )
  231. )(),
  232. `${REQUEST_OBJECT_ERROR}: Memoization works in the enabled repetition mode`
  233. );
  234. e(
  235. "throws an error if the selector nodes are not found",
  236. () =>
  237. compile(
  238. createTestObj2(
  239. `<button>Click</button>{{ "src":"/api/test", "after":"click:#increment" }}`
  240. )
  241. )(),
  242. `${RENDER_ERROR}: Selectors nodes not found`
  243. );
  244. eq(
  245. "",
  246. compile(
  247. createTestObj2(
  248. `<button id="increment">Click</button>{{ "src":"/api/test", "after":"click:#increment" }}`
  249. ),
  250. { memo: true }
  251. )().response?.outerHTML,
  252. '<div><button id="increment">Click</button><!--hmpl0--></div>'
  253. );
  254. eq(
  255. "",
  256. compile(
  257. createTestObj2(
  258. `<button id="increment">Click</button>{{ "src":"/api/test", "after":"click:#increment", "repeat": false }}`
  259. ),
  260. { memo: true }
  261. )().response?.outerHTML,
  262. '<div><button id="increment">Click</button><!--hmpl0--></div>'
  263. );
  264. e(
  265. "throws an error if passed duplicate indicator triggers",
  266. () => compile(createTestObj2(`{${eq0}}`))(),
  267. `${REQUEST_OBJECT_ERROR}: Indicator trigger must be unique`
  268. );
  269. e(
  270. "throws an error if provided an invalid indicator trigger",
  271. () => compile(createTestObj2(`{${eq1}}`))(),
  272. `${REQUEST_OBJECT_ERROR}: Failed to activate or detect the indicator`
  273. );
  274. e(
  275. "throws an error if trigger is not provided to the indicators",
  276. () => compile(createTestObj2(`{${eq2}}`))(),
  277. `${REQUEST_OBJECT_ERROR}: Failed to activate or detect the indicator`
  278. );
  279. e(
  280. "throws an error if trigger is a number and the value is not provided to the indicators",
  281. () => compile(createTestObj2(`{${eq3}}`))(),
  282. `${REQUEST_OBJECT_ERROR}: Failed to activate or detect the indicator`
  283. );
  284. eq(
  285. "",
  286. compile(
  287. createTestObj2(
  288. `<button id="increment">Click</button>{{ "src":"/api/test", "after":"click:#increment", "memo": true }}`
  289. ),
  290. { memo: false }
  291. )().response?.outerHTML,
  292. '<div><button id="increment">Click</button><!--hmpl0--></div>'
  293. );
  294. eq(
  295. "",
  296. compile(
  297. createTestObj2(
  298. `<button id="increment">Click</button>{{ "src":"/api/test", "after":"click:#increment", "memo": true }}`
  299. ),
  300. { memo: false }
  301. )().response?.outerHTML,
  302. '<div><button id="increment">Click</button><!--hmpl0--></div>'
  303. );
  304. eq(
  305. "",
  306. compile(
  307. createTestObj2(
  308. `<button id="increment">Click</button>{{ "src":"/api/test", "after":"click:#increment", "memo": false }}`
  309. ),
  310. { memo: true }
  311. )().response?.outerHTML,
  312. '<div><button id="increment">Click</button><!--hmpl0--></div>'
  313. );
  314. eq(
  315. "",
  316. compile(createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`))().response
  317. ?.outerHTML,
  318. "<div><!--hmpl0--></div>"
  319. );
  320. eq(
  321. "",
  322. compile(
  323. createTestObj2(
  324. `<button id="increment">Click</button>{{ "src":"/api/test", "after":"click:#increment" }}`
  325. )
  326. )().response?.outerHTML,
  327. '<div><button id="increment">Click</button><!--hmpl0--></div>'
  328. );
  329. eaeq(
  330. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  331. `${RESPONSE_ERROR}: Expected ${DEFAULT_ALLOWED_CONTENT_TYPES.map(
  332. (type) => `"${type}"`
  333. ).join(", ")}, but received "${contentType1}"`,
  334. () => ({}) as any,
  335. {},
  336. {
  337. template: Buffer.from("<div>123</div>", "utf-8"),
  338. headers: {
  339. "Content-Type": contentType1
  340. }
  341. }
  342. );
  343. eaeq(
  344. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  345. `${RESPONSE_ERROR}: Expected ${DEFAULT_ALLOWED_CONTENT_TYPES.map(
  346. (type) => `"${type}"`
  347. ).join(", ")}, but received ""`,
  348. () => ({}) as any,
  349. {},
  350. {
  351. template: Buffer.from("<div>123</div>", "utf-8"),
  352. headers: {
  353. "Content-Type": ""
  354. }
  355. }
  356. );
  357. eaeq(
  358. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  359. `${REQUEST_INIT_ERROR}: Expected type string, but received type object`,
  360. () => ({}) as any,
  361. {
  362. headers: {
  363. a: {}
  364. }
  365. },
  366. {}
  367. );
  368. eaeq(
  369. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  370. `${REQUEST_INIT_ERROR}: Expected an object with initialization options`,
  371. () => ({}) as any,
  372. () => () => 1 as any,
  373. {}
  374. );
  375. eaeq(
  376. createTestObj2(
  377. `{{ "src":"${BASE_URL}/api/test" }}{{ "src":"${BASE_URL}/api/test" }}`
  378. ),
  379. `${REQUEST_INIT_ERROR}: Expected an object with initialization options`,
  380. () => ({}) as any,
  381. () => () => 1 as any,
  382. {}
  383. );
  384. eaeq(
  385. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  386. `${REQUEST_INIT_ERROR}: The "headers" property must contain a value object`,
  387. () => ({}) as any,
  388. {
  389. headers: []
  390. },
  391. {}
  392. );
  393. eaeq(
  394. createTestObj2(`{${eaeq1}}`),
  395. `${REQUEST_OBJECT_ERROR}: ID referenced by request not found`,
  396. () => ({}) as any,
  397. (res: any) => [
  398. {
  399. id: "2",
  400. value: {}
  401. }
  402. ],
  403. {}
  404. );
  405. eaeq(
  406. createTestObj2(`{${eaeq1}}`),
  407. `${REQUEST_OBJECT_ERROR}: ID referenced by request not found`,
  408. () => ({}) as any,
  409. (res: any) => [
  410. {
  411. id: "2",
  412. value: {}
  413. }
  414. ],
  415. {}
  416. );
  417. eaeq(
  418. createTestObj2(`{${eaeq1}}`),
  419. `${REQUEST_OBJECT_ERROR}: ID referenced by request not found`,
  420. () => ({}) as any,
  421. (res: any) => ({}),
  422. {}
  423. );
  424. aeq(
  425. createTestObj2(`{{ "src":"${BASE_URL}/api/test", initId:"" }}`),
  426. () => ({}),
  427. (res: any) => [
  428. {
  429. id: "2",
  430. value: {}
  431. }
  432. ],
  433. undefined,
  434. undefined,
  435. true
  436. );
  437. aeq(
  438. `{{ "src":"${BASE_URL}/api/test" }}`,
  439. (res, prop, value) => {
  440. switch (prop) {
  441. case "response":
  442. if (value?.outerHTML === `<template><div>123</div></template>`) {
  443. res(true);
  444. } else {
  445. res(false);
  446. }
  447. break;
  448. }
  449. },
  450. {}
  451. );
  452. aeq(
  453. createTestObj2(`{${aeq5}}`),
  454. (res, prop, value) => {
  455. switch (prop) {
  456. case "response":
  457. if (value?.outerHTML === `<div><p>Error</p></div>`) {
  458. res(true);
  459. } else {
  460. res(false);
  461. }
  462. break;
  463. }
  464. },
  465. {},
  466. {
  467. isRejected: true
  468. }
  469. );
  470. aeq(
  471. createTestObj2(`{{ src: "${BASE_URL}/api/test" }}`),
  472. (res, prop, value) => {
  473. switch (prop) {
  474. case "status":
  475. if (value === "rejected") {
  476. res(true);
  477. }
  478. break;
  479. }
  480. },
  481. {},
  482. {
  483. isRejected: true
  484. }
  485. );
  486. aeq(
  487. createTestObj2(`{${aeq7}}`),
  488. (res, prop, value) => {
  489. switch (prop) {
  490. case "status":
  491. if (value === "rejected") {
  492. res(true);
  493. }
  494. break;
  495. }
  496. },
  497. {},
  498. {
  499. isRejected: true
  500. }
  501. );
  502. aeq(
  503. createTestObj2(`{{ src: "${BASE_URL}/api/test", indicators:[] }}`),
  504. (res, prop, value) => {
  505. switch (prop) {
  506. case "status":
  507. if (value === 100) {
  508. res(true);
  509. }
  510. break;
  511. }
  512. },
  513. {},
  514. {
  515. code: 100
  516. }
  517. );
  518. aeq(
  519. createTestObj2(`{${aeq6}}`),
  520. (res, prop, value) => {
  521. switch (prop) {
  522. case "response":
  523. if (value?.outerHTML === `<div><p>Rejected</p></div>`) {
  524. res(true);
  525. } else {
  526. res(false);
  527. }
  528. break;
  529. }
  530. },
  531. {},
  532. {
  533. isRejected: true
  534. }
  535. );
  536. aeq(
  537. createTestObj2(`{${aeq7}}`),
  538. (res, prop, value) => {
  539. switch (prop) {
  540. case "response":
  541. if (value?.outerHTML === `<div><p>100</p></div>`) {
  542. res(true);
  543. } else {
  544. res(false);
  545. }
  546. break;
  547. }
  548. },
  549. {},
  550. {
  551. code: 100
  552. }
  553. );
  554. waeq(
  555. `{{ "src":"${BASE_URL}/api/test" }}`,
  556. `${REQUEST_INIT_ERROR}: The "signal" property overwrote the AbortSignal from "timeout"`,
  557. () => ({}) as any,
  558. {
  559. timeout: 1000,
  560. signal: new AbortController().signal
  561. },
  562. {}
  563. );
  564. waeq(
  565. `{{ "src":"${BASE_URL}/api/test" }}`,
  566. `${REQUEST_INIT_ERROR}: The "keepalive" property is not yet supported`,
  567. () => ({}) as any,
  568. {
  569. keepalive: true
  570. },
  571. {}
  572. );
  573. aeq(
  574. createTestObj2(
  575. `{{ "src":"${BASE_URL}/api/test", disallowedTags:["script"] }}`
  576. ),
  577. (res, prop, value) => {
  578. switch (prop) {
  579. case "response":
  580. if (value?.outerHTML === `<div><div>123</div></div>`) {
  581. res(true);
  582. } else {
  583. res(false);
  584. }
  585. break;
  586. }
  587. },
  588. {},
  589. {
  590. template: "<div>123</div><script></script>"
  591. }
  592. );
  593. aeq(
  594. createTestObj2(
  595. `{{ "src":"${BASE_URL}/api/test", disallowedTags:["script"] }}`
  596. ),
  597. (res, prop, value) => {
  598. switch (prop) {
  599. case "response":
  600. if (value?.outerHTML === `<div><div>123</div></div>`) {
  601. res(true);
  602. } else {
  603. res(false);
  604. }
  605. break;
  606. }
  607. },
  608. {},
  609. {
  610. template: "<div>123</div><script></script>"
  611. },
  612. {
  613. disallowedTags: ["style"]
  614. }
  615. );
  616. aeq(
  617. createTestObj2(`{{ "src":"${BASE_URL}/api/test", sanitize:true }}`),
  618. (res, prop, value) => {
  619. switch (prop) {
  620. case "response":
  621. if (value?.outerHTML === `<div><div>123</div></div>`) {
  622. res(true);
  623. } else {
  624. res(false);
  625. }
  626. break;
  627. }
  628. },
  629. {},
  630. {
  631. template: "<div>123</div><script></script>"
  632. },
  633. {}
  634. );
  635. aeq(
  636. createTestObj2(`{{ "src":"${BASE_URL}/api/test", sanitize:true }}`),
  637. (res, prop, value) => {
  638. switch (prop) {
  639. case "response":
  640. if (value?.outerHTML === `<div><div>123</div></div>`) {
  641. res(true);
  642. } else {
  643. res(false);
  644. }
  645. break;
  646. }
  647. },
  648. {},
  649. {
  650. template: "<div>123</div><script></script>"
  651. },
  652. {
  653. sanitize: false
  654. }
  655. );
  656. aeq(
  657. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  658. (res, prop, value) => {
  659. switch (prop) {
  660. case "response":
  661. if (value?.outerHTML === `<div><div>123</div></div>`) {
  662. res(true);
  663. } else {
  664. res(false);
  665. }
  666. break;
  667. }
  668. },
  669. {},
  670. {},
  671. {
  672. memo: true
  673. }
  674. );
  675. aeq(
  676. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  677. (res, prop, value) => {
  678. switch (prop) {
  679. case "response":
  680. if (value?.outerHTML === `<div><div>123</div></div>`) {
  681. res(true);
  682. } else {
  683. res(false);
  684. }
  685. break;
  686. }
  687. }
  688. );
  689. aeq(
  690. createTestObj2(`{{ "src":"${BASE_URL}/api/test", indicators: [
  691. {
  692. trigger: "pending",
  693. content: "<p>Loading...</p>"
  694. }
  695. ] }}`),
  696. (res, prop, value) => {
  697. switch (prop) {
  698. case "response":
  699. if (value?.outerHTML === `<div><p>Loading...</p></div>`) {
  700. res(true);
  701. } else {
  702. res(false);
  703. }
  704. break;
  705. }
  706. }
  707. );
  708. aeq(
  709. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  710. (res, prop, value) => {
  711. switch (prop) {
  712. case "response":
  713. if (value?.outerHTML === `<div><div>123</div></div>`) {
  714. res(true);
  715. } else {
  716. res(false);
  717. }
  718. break;
  719. }
  720. },
  721. {},
  722. {
  723. template: Buffer.from("<div>123</div>", "utf-8"),
  724. headers: {
  725. "Content-Type": "application/octet-stream"
  726. }
  727. },
  728. {
  729. allowedContentTypes: ["application/octet-stream"]
  730. }
  731. );
  732. aeq(
  733. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  734. (res, prop, value) => {
  735. switch (prop) {
  736. case "response":
  737. if (value?.outerHTML === `<div><div>123</div></div>`) {
  738. res(true);
  739. } else {
  740. res(false);
  741. }
  742. break;
  743. }
  744. },
  745. {},
  746. {
  747. template: Buffer.from("<div>123</div>", "utf-8"),
  748. headers: {
  749. "Content-Type": "application/octet-stream"
  750. }
  751. },
  752. {
  753. allowedContentTypes: ["text/html", "application/octet-stream"]
  754. }
  755. );
  756. aeq(
  757. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  758. (res, prop, value) => {
  759. switch (prop) {
  760. case "response":
  761. if (value?.outerHTML === `<div><div>123</div></div>`) {
  762. res(true);
  763. } else {
  764. res(false);
  765. }
  766. break;
  767. }
  768. },
  769. {},
  770. {
  771. template: Buffer.from("<div>123</div>", "utf-8"),
  772. headers: {
  773. "Content-Type": "application/octet-stream"
  774. }
  775. },
  776. {
  777. allowedContentTypes: []
  778. }
  779. );
  780. aeq(
  781. createTestObj2(
  782. `{{ "src":"${BASE_URL}/api/test" }}{{ "src":"${BASE_URL}/api/test" }}`
  783. ),
  784. (res, prop, value) => {
  785. switch (prop) {
  786. case "response":
  787. if (value?.outerHTML === `<div><div>123</div><div>123</div></div>`) {
  788. res(true);
  789. }
  790. break;
  791. }
  792. },
  793. {}
  794. );
  795. aeq(
  796. createTestObj2(`{{ "src":"${BASE_URL}/api/test" }}`),
  797. (res, prop, value) => {
  798. switch (prop) {
  799. case "response":
  800. if (value?.outerHTML === `<div><div>123</div></div>`) {
  801. res(true);
  802. } else {
  803. res(false);
  804. }
  805. break;
  806. }
  807. },
  808. {},
  809. {
  810. template: Buffer.from("<div>123</div>", "utf-8"),
  811. headers: {
  812. "Content-Type": "application/octet-stream"
  813. }
  814. },
  815. {
  816. allowedContentTypes: "*"
  817. }
  818. );
  819. aeq(
  820. createTestObj2(
  821. `{{ "src":"${BASE_URL}/api/test", allowedContentTypes: ["application/octet-stream"] }}`
  822. ),
  823. (res, prop, value) => {
  824. switch (prop) {
  825. case "response":
  826. if (value?.outerHTML === `<div><div>123</div></div>`) {
  827. res(true);
  828. } else {
  829. res(false);
  830. }
  831. break;
  832. }
  833. },
  834. {},
  835. {
  836. template: Buffer.from("<div>123</div>", "utf-8"),
  837. headers: {
  838. "Content-Type": "application/octet-stream"
  839. }
  840. },
  841. {
  842. allowedContentTypes: ["text/html"]
  843. }
  844. );
  845. aeq(
  846. createTestObj2(
  847. `{{ "src":"${BASE_URL}/api/test", allowedContentTypes: ["application/octet-stream"] }}`
  848. ),
  849. (res, prop, value) => {
  850. switch (prop) {
  851. case "response":
  852. if (value?.outerHTML === `<div><div>123</div></div>`) {
  853. res(true);
  854. } else {
  855. res(false);
  856. }
  857. break;
  858. }
  859. },
  860. {
  861. timeout: 1000
  862. },
  863. {
  864. template: Buffer.from("<div>123</div>", "utf-8"),
  865. headers: {
  866. "Content-Type": "application/octet-stream"
  867. }
  868. }
  869. );
  870. aeq(createTestObj2(`{${aeq0}}`), (res, prop, value) => {
  871. switch (prop) {
  872. case "response":
  873. if (value?.outerHTML === `<div><p>Loading...</p></div>`) {
  874. res(true);
  875. } else {
  876. res(false);
  877. }
  878. break;
  879. }
  880. });
  881. aeq(`{${aeq0}}`, (res, prop, value) => {
  882. switch (prop) {
  883. case "response":
  884. if (value?.outerHTML === `<template><div>123</div></template>`) {
  885. res(true);
  886. }
  887. break;
  888. }
  889. });
  890. aeq(
  891. `{${aeq4}}`,
  892. (res, prop, value) => {
  893. switch (prop) {
  894. case "response":
  895. if (value?.outerHTML === `<template><p>405</p></template>`) {
  896. res(true);
  897. }
  898. break;
  899. }
  900. },
  901. {},
  902. {
  903. code: 405
  904. }
  905. );
  906. aeq(
  907. `{${aeq5}}`,
  908. (res, prop, value) => {
  909. switch (prop) {
  910. case "response":
  911. if (value?.outerHTML === `<template><p>Error</p></template>`) {
  912. res(true);
  913. }
  914. break;
  915. }
  916. },
  917. {},
  918. {
  919. code: 405
  920. }
  921. );
  922. aeq(
  923. createTestObj2(`{${aeq0}}`),
  924. (res, prop, value) => {
  925. switch (prop) {
  926. case "response":
  927. if (value?.outerHTML === `<div><p>Loading...</p></div>`) {
  928. res(true);
  929. } else {
  930. res(false);
  931. }
  932. break;
  933. }
  934. },
  935. {
  936. mode: "cors",
  937. cache: "no-cache",
  938. integrity: "sha256",
  939. referrer: "about:client",
  940. credentials: "same-origin",
  941. redirect: "follow",
  942. window: "",
  943. referrerPolicy: "no-referrer",
  944. headers: {
  945. "Cache-Control": "no-cache"
  946. }
  947. }
  948. );
  949. aeqe(
  950. `<pre><button id="click">click</button>{${aeq1}}</pre>`,
  951. (res, prop, value) => {
  952. switch (prop) {
  953. case "response":
  954. if (
  955. value?.outerHTML ===
  956. `<pre><button id="click">click</button><div>123</div></pre>`
  957. ) {
  958. res(true);
  959. } else {
  960. res(false);
  961. }
  962. break;
  963. }
  964. }
  965. );
  966. aeqe(
  967. createTestObj3(`{${aeq1}}`),
  968. () => ({}),
  969. {},
  970. (res: any) => () => {
  971. return {
  972. get: (prop: any, value: any) => {
  973. switch (prop) {
  974. case "response":
  975. if (
  976. value?.outerHTML ===
  977. `<div><button id="click">click</button><div>123</div></div>`
  978. ) {
  979. res(true);
  980. } else {
  981. res(false);
  982. }
  983. break;
  984. }
  985. }
  986. };
  987. }
  988. );
  989. aeqe(
  990. createTestObj3(`{${aeqe0}}`),
  991. () => ({}),
  992. {},
  993. (res: any) => [
  994. {
  995. id: "1",
  996. value: {
  997. get: (prop: any, value: any) => {
  998. switch (prop) {
  999. case "response":
  1000. if (
  1001. value?.outerHTML ===
  1002. `<div><button id="click">click</button><div>123</div></div>`
  1003. ) {
  1004. res(true);
  1005. }
  1006. break;
  1007. }
  1008. }
  1009. }
  1010. }
  1011. ]
  1012. );
  1013. aeqe(createTestObj3(`{${aeq1}}{${aeq1}}`), (res, prop, value) => {
  1014. switch (prop) {
  1015. case "response":
  1016. if (
  1017. value?.outerHTML ===
  1018. `<div><button id="click">click</button><div>123</div><div>123</div></div>`
  1019. ) {
  1020. res(true);
  1021. }
  1022. break;
  1023. }
  1024. });
  1025. let memoItem: Element | undefined = undefined;
  1026. aeqe(
  1027. createTestObj3(`{${aeq1}}`),
  1028. (res, prop, value) => {
  1029. switch (prop) {
  1030. case "response":
  1031. if (
  1032. value?.outerHTML ===
  1033. `<div><button id="click">click</button><div>123</div></div>`
  1034. ) {
  1035. if (!memoItem) {
  1036. memoItem = value;
  1037. } else {
  1038. res(memoItem.childNodes[1] === value.childNodes[1]);
  1039. }
  1040. } else {
  1041. res(false);
  1042. }
  1043. break;
  1044. }
  1045. },
  1046. {
  1047. memo: true
  1048. },
  1049. {},
  1050. {},
  1051. 2
  1052. );
  1053. aeqe(
  1054. createTestObj3(`{${aeq8}}{${aeq8}}`),
  1055. (res, prop, value) => {
  1056. switch (prop) {
  1057. case "response":
  1058. if (
  1059. value?.outerHTML ===
  1060. `<div><button id="click">click</button><div>123</div><div>123</div></div>`
  1061. ) {
  1062. res(true);
  1063. }
  1064. break;
  1065. }
  1066. },
  1067. {},
  1068. {},
  1069. {},
  1070. 1
  1071. );
  1072. aeqe(
  1073. createTestObj3(`<pre>{${aeq8}}</pre>`),
  1074. (res, prop, value) => {
  1075. switch (prop) {
  1076. case "response":
  1077. if (
  1078. value?.outerHTML ===
  1079. `<div><button id="click">click</button><pre><pre>123</pre></pre></div>`
  1080. ) {
  1081. res(true);
  1082. }
  1083. break;
  1084. }
  1085. },
  1086. {},
  1087. {},
  1088. {
  1089. template: "<pre>123</pre>"
  1090. },
  1091. 1
  1092. );
  1093. let memoItem1: Element | undefined = undefined;
  1094. aeqe(
  1095. createTestObj3(`{${aeq1}}`),
  1096. (res, prop, value) => {
  1097. switch (prop) {
  1098. case "response":
  1099. if (
  1100. value?.outerHTML ===
  1101. `<div><button id="click">click</button><div>123</div></div>`
  1102. ) {
  1103. if (!memoItem1) {
  1104. memoItem1 = value;
  1105. } else {
  1106. // this is false
  1107. res(memoItem1.childNodes[1] === value.childNodes[1]);
  1108. }
  1109. } else {
  1110. res(false);
  1111. }
  1112. break;
  1113. }
  1114. },
  1115. {},
  1116. {},
  1117. {},
  1118. 2
  1119. );
  1120. let memoItem2: Element | undefined = undefined;
  1121. aeqe(
  1122. createTestObj3(`{${aeq2}}`),
  1123. (res, prop, value) => {
  1124. switch (prop) {
  1125. case "response":
  1126. if (
  1127. value?.outerHTML ===
  1128. `<div><button id="click">click</button><div>123</div></div>`
  1129. ) {
  1130. if (!memoItem2) {
  1131. memoItem2 = value;
  1132. } else {
  1133. res(memoItem2.childNodes[1] === value.childNodes[1]);
  1134. }
  1135. }
  1136. break;
  1137. }
  1138. },
  1139. {},
  1140. {},
  1141. {},
  1142. 2
  1143. );
  1144. let count = 0;
  1145. aeqe(
  1146. createTestObj3(`{${aeq1}}`),
  1147. (res, prop, value) => {
  1148. switch (prop) {
  1149. case "response":
  1150. if (
  1151. value?.outerHTML ===
  1152. `<div><button id="click">click</button><div>123</div></div>`
  1153. ) {
  1154. if (!memoItem2) {
  1155. if (!count) {
  1156. count++;
  1157. } else {
  1158. memoItem2 = value;
  1159. }
  1160. } else {
  1161. res(true);
  1162. }
  1163. }
  1164. break;
  1165. }
  1166. },
  1167. {},
  1168. {},
  1169. {},
  1170. 3
  1171. );
  1172. aeqe(
  1173. createTestObj3(`{${aeq2}}`),
  1174. (res, prop, value) => {
  1175. switch (prop) {
  1176. case "response":
  1177. if (
  1178. value?.outerHTML ===
  1179. `<div><button id="click">click</button><div>123</div></div>`
  1180. ) {
  1181. if (!memoItem2) {
  1182. memoItem2 = value;
  1183. } else {
  1184. res(memoItem2.childNodes[1] !== value.childNodes[1]);
  1185. }
  1186. }
  1187. break;
  1188. }
  1189. },
  1190. {
  1191. memo: true
  1192. },
  1193. {},
  1194. {},
  1195. 2
  1196. );
  1197. // status templateObject check
  1198. aeqe(
  1199. createTestObj3(`{${aeq1}}`),
  1200. (res, prop, value) => {
  1201. switch (prop) {
  1202. case "response":
  1203. if (
  1204. value?.outerHTML ===
  1205. `<div><button id="click">click</button><!--hmpl0--></div>`
  1206. ) {
  1207. res(true);
  1208. }
  1209. break;
  1210. }
  1211. },
  1212. {
  1213. memo: true
  1214. },
  1215. {},
  1216. {
  1217. isAfter: true,
  1218. afterCode: 200,
  1219. afterHeaders: {
  1220. "Content-Type": contentType1
  1221. },
  1222. times: 1
  1223. },
  1224. 2,
  1225. undefined,
  1226. undefined,
  1227. {
  1228. timeout: 300
  1229. }
  1230. );
  1231. aeqe(
  1232. createTestObj3(`{${aeq2}}`),
  1233. (res, prop, value) => {
  1234. switch (prop) {
  1235. case "response":
  1236. if (
  1237. value?.outerHTML ===
  1238. `<div><button id="click">click</button><div>123</div></div>`
  1239. ) {
  1240. if (!memoItem2) {
  1241. memoItem2 = value;
  1242. } else {
  1243. res(memoItem2.childNodes[1] !== value.childNodes[1]);
  1244. }
  1245. }
  1246. break;
  1247. }
  1248. },
  1249. {
  1250. memo: true
  1251. },
  1252. {},
  1253. {},
  1254. 2
  1255. );
  1256. aeqe(
  1257. createTestObj4(`{${aeq3}}`),
  1258. (res, prop, value) => {
  1259. switch (prop) {
  1260. case "response":
  1261. if (
  1262. value?.outerHTML ===
  1263. `<div><form onsubmit="function prevent(e){e.preventDefault();};return prevent(event);" id="form"></form><div>123</div></div>`
  1264. ) {
  1265. res(true);
  1266. } else {
  1267. res(false);
  1268. }
  1269. break;
  1270. }
  1271. },
  1272. {
  1273. autoBody: true
  1274. },
  1275. {},
  1276. {
  1277. route: "/api/getFormComponent",
  1278. method: "post"
  1279. },
  1280. 1,
  1281. (el) => {
  1282. return el?.getElementsByTagName("form")?.[0];
  1283. },
  1284. "submit"
  1285. );
  1286. aeqe(
  1287. `{${aeq0}}`,
  1288. (res, prop, value) => {
  1289. switch (prop) {
  1290. case "response":
  1291. if (value === undefined) {
  1292. res(true);
  1293. }
  1294. break;
  1295. }
  1296. },
  1297. {},
  1298. {},
  1299. {
  1300. code: 405
  1301. }
  1302. );
  1303. aeqe(
  1304. createTestObj3(`{${aeq0}}{${aeq0}}`),
  1305. (res, prop, value) => {
  1306. switch (prop) {
  1307. case "response":
  1308. if (
  1309. value?.outerHTML ===
  1310. `<div><button id="click">click</button><!--hmpl0--><!--hmpl1--></div>`
  1311. ) {
  1312. res(true);
  1313. }
  1314. break;
  1315. }
  1316. },
  1317. {},
  1318. {},
  1319. {
  1320. code: 405,
  1321. times: 1,
  1322. isAfter: true
  1323. },
  1324. 2
  1325. );
  1326. aeqe(
  1327. createTestObj3(`{${aeq1}}`),
  1328. (res, prop, value) => {
  1329. switch (prop) {
  1330. case "response":
  1331. if (
  1332. value?.outerHTML ===
  1333. `<div><button id="click">click</button><div>567</div></div>`
  1334. ) {
  1335. res(true);
  1336. }
  1337. break;
  1338. }
  1339. },
  1340. {
  1341. memo: true
  1342. },
  1343. {},
  1344. {
  1345. afterCode: 200,
  1346. afterTemplate: "<div>567</div>",
  1347. times: 1,
  1348. isAfter: true
  1349. },
  1350. 2
  1351. );
  1352. let memoItem3: Element | undefined;
  1353. aeqe(
  1354. createTestObj3(`{${aeq2}}`),
  1355. (res, prop, value) => {
  1356. switch (prop) {
  1357. case "response":
  1358. if (
  1359. value?.outerHTML ===
  1360. `<div><button id="click">click</button><div>123</div></div>`
  1361. ) {
  1362. if (!memoItem3) {
  1363. memoItem3 = value;
  1364. } else {
  1365. res(memoItem3.childNodes[1] === value.childNodes[1]);
  1366. }
  1367. }
  1368. break;
  1369. }
  1370. },
  1371. {
  1372. memo: true
  1373. },
  1374. {},
  1375. {},
  1376. 2,
  1377. undefined,
  1378. undefined,
  1379. {
  1380. timeout: 300
  1381. }
  1382. );
  1383. aeqe(
  1384. createTestObj3(`{${aeq2}}`),
  1385. (res, prop, value) => {
  1386. switch (prop) {
  1387. case "response":
  1388. if (
  1389. value?.outerHTML ===
  1390. `<div><button id="click">click</button><!--hmpl0--></div>`
  1391. ) {
  1392. res(true);
  1393. }
  1394. break;
  1395. }
  1396. },
  1397. {
  1398. memo: true
  1399. },
  1400. {},
  1401. {
  1402. afterCode: 405,
  1403. times: 1,
  1404. isAfter: true
  1405. },
  1406. 2
  1407. );
  1408. aeqe(
  1409. `{${aeq0}}`,
  1410. (res, prop, value) => {
  1411. switch (prop) {
  1412. case "response":
  1413. if (value === undefined) {
  1414. res(true);
  1415. }
  1416. break;
  1417. }
  1418. },
  1419. {},
  1420. {},
  1421. {
  1422. code: 405
  1423. }
  1424. );
  1425. afterEach(() => {
  1426. sinon.restore();
  1427. nock.cleanAll();
  1428. });
  1429. });