1+ // SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
2+ // SPDX-License-Identifier: AGPL-3.0-or-later
3+
4+ import { mkdtemp , mkdir , rm , writeFile } from 'node:fs/promises'
5+ import path from 'node:path'
6+ import { tmpdir } from 'node:os'
7+
8+ import { afterEach , describe , expect , it } from 'vitest'
9+
10+ import {
11+ extractRuntimeVersion ,
12+ extractWorkerVersion ,
13+ validatePdfjsDist ,
14+ } from '../../scripts/validate-pdfjs-dist.mjs'
15+
16+ const tempDirs : string [ ] = [ ]
17+
18+ async function createFixtureRoot ( { runtimeVersion, workerVersion, lockVersion } : {
19+ runtimeVersion : string
20+ workerVersion : string
21+ lockVersion : string
22+ } ) {
23+ const rootDir = await mkdtemp ( path . join ( tmpdir ( ) , 'pdf-elements-dist-' ) )
24+ tempDirs . push ( rootDir )
25+
26+ const distDir = path . join ( rootDir , 'dist' )
27+ await mkdir ( distDir , { recursive : true } )
28+
29+ await writeFile (
30+ path . join ( distDir , 'pdf-fixture.mjs' ) ,
31+ `const runtime = { apiVersion: "${ runtimeVersion } " }\nexport default runtime\n` ,
32+ 'utf8'
33+ )
34+
35+ const encodedWorker = Buffer . from ( `const workerVersion = "${ workerVersion } "\n` , 'utf8' ) . toString ( 'base64' )
36+ await writeFile (
37+ path . join ( distDir , 'pdf.worker.min-fixture.mjs' ) ,
38+ `var worker = "data:text/javascript;base64,${ encodedWorker } "\nexport { worker as default }\n` ,
39+ 'utf8'
40+ )
41+
42+ await writeFile (
43+ path . join ( rootDir , 'package-lock.json' ) ,
44+ JSON . stringify ( {
45+ packages : {
46+ 'node_modules/pdfjs-dist' : {
47+ version : lockVersion ,
48+ } ,
49+ } ,
50+ } ) ,
51+ 'utf8'
52+ )
53+
54+ return rootDir
55+ }
56+
57+ afterEach ( async ( ) => {
58+ await Promise . all ( tempDirs . splice ( 0 ) . map ( ( dirPath ) => rm ( dirPath , { recursive : true , force : true } ) ) )
59+ } )
60+
61+ describe ( 'validate-pdfjs-dist' , ( ) => {
62+ it ( 'extracts the runtime apiVersion from the bundled PDF chunk' , ( ) => {
63+ expect ( extractRuntimeVersion ( 'const runtime = { apiVersion: "5.4.624" }' ) ) . toBe ( '5.4.624' )
64+ } )
65+
66+ it ( 'extracts the worker version from the emitted data URL wrapper' , ( ) => {
67+ const encodedWorker = Buffer . from ( 'const workerVersion = "5.4.624"' , 'utf8' ) . toString ( 'base64' )
68+
69+ expect ( extractWorkerVersion ( `var worker = "data:text/javascript;base64,${ encodedWorker } "` ) ) . toBe ( '5.4.624' )
70+ } )
71+
72+ it ( 'accepts a dist tree whose runtime, worker and lockfile stay aligned' , async ( ) => {
73+ const rootDir = await createFixtureRoot ( {
74+ runtimeVersion : '5.4.624' ,
75+ workerVersion : '5.4.624' ,
76+ lockVersion : '5.4.624' ,
77+ } )
78+
79+ await expect ( validatePdfjsDist ( { rootDir } ) ) . resolves . toMatchObject ( {
80+ runtimeVersion : '5.4.624' ,
81+ workerVersion : '5.4.624' ,
82+ resolvedPdfjsVersion : '5.4.624' ,
83+ } )
84+ } )
85+
86+ it ( 'rejects a dist tree when the worker version drifts from the runtime version' , async ( ) => {
87+ const rootDir = await createFixtureRoot ( {
88+ runtimeVersion : '5.6.205' ,
89+ workerVersion : '5.5.207' ,
90+ lockVersion : '5.5.207' ,
91+ } )
92+
93+ await expect ( validatePdfjsDist ( { rootDir } ) ) . rejects . toThrow ( / P D F \. j s d i s t m i s m a t c h / )
94+ } )
95+
96+ it ( 'rejects a dist tree when the runtime version drifts from the lockfile' , async ( ) => {
97+ const rootDir = await createFixtureRoot ( {
98+ runtimeVersion : '5.6.205' ,
99+ workerVersion : '5.6.205' ,
100+ lockVersion : '5.5.207' ,
101+ } )
102+
103+ await expect ( validatePdfjsDist ( { rootDir } ) ) . rejects . toThrow ( / P D F \. j s d i s t d r i f t / )
104+ } )
105+ } )
0 commit comments