1+ const fs = require ( 'fs' ) ;
2+ const path = require ( 'path' ) ;
3+ const expect = require ( 'chai' ) . expect ;
4+ const track = require ( 'temp' ) . track ( ) ;
5+ const unpack = require ( '../utils' ) . unpack ;
6+ const testMe = require ( '../utils' ) ;
7+ const sinon = require ( 'sinon' ) ;
8+ 9+ describe ( 'utils' , ( ) => {
10+ 11+ describe ( 'adjustArchiveStructure' , ( ) => {
12+ 13+ let consoleStub ;
14+ 15+ beforeEach ( ( ) => {
16+ consoleStub = sinon . stub ( console , 'log' ) . value ( ( ) => { } ) ;
17+ } ) ;
18+ 19+ afterEach ( ( ) => {
20+ consoleStub . reset ( ) ;
21+ track . cleanupSync ( ) ;
22+ } ) ;
23+ 24+ it ( 'should reject when not a zip file' , async ( ) => {
25+ try {
26+ const invalid = path . join ( __dirname , 'resources' , 'not-a-zip.dmg' ) ;
27+ await testMe . adjustArchiveStructure ( invalid , track . mkdirSync ( ) ) ;
28+ throw new Error ( 'Expected a rejection' ) ;
29+ } catch ( e ) {
30+ expect ( e ) . to . be . an . instanceOf ( Error ) ;
31+ expect ( e . message ) . to . be . equal ( 'Expected a ZIP file.' ) ;
32+ }
33+ } ) ;
34+ 35+ it ( 'should reject when target directory does not exist' , async ( ) => {
36+ try {
37+ const zip = path . join ( __dirname , 'resources' , 'zip-with-base-folder.zip' ) ;
38+ await testMe . adjustArchiveStructure ( zip , path . join ( __dirname , 'some' , 'missing' , 'path' ) ) ;
39+ throw new Error ( 'Expected a rejection' ) ;
40+ } catch ( e ) {
41+ expect ( e ) . to . be . an . instanceOf ( Error ) ;
42+ expect ( e . message . endsWith ( 'does not exist.' ) ) . to . be . true ;
43+ }
44+ } ) ;
45+ 46+ it ( 'should reject when target is a file' , async ( ) => {
47+ try {
48+ const zip = path . join ( __dirname , 'resources' , 'zip-with-base-folder.zip' ) ;
49+ await testMe . adjustArchiveStructure ( zip , path . join ( __filename ) ) ;
50+ throw new Error ( 'Expected a rejection' ) ;
51+ } catch ( e ) {
52+ expect ( e ) . to . be . an . instanceOf ( Error ) ;
53+ expect ( e . message . endsWith ( 'is not a directory.' ) ) . to . be . true ;
54+ }
55+ } ) ;
56+ 57+ it ( 'should be a NOOP when the zip already has the desired base folder' , async ( ) => {
58+ const zip = path . join ( __dirname , 'resources' , 'zip-with-base-folder.zip' ) ;
59+ const actual = await testMe . adjustArchiveStructure ( zip , track . mkdirSync ( ) ) ;
60+ expect ( actual ) . to . be . equal ( zip ) ;
61+ } ) ;
62+ 63+ it ( 'should handle whitespace in file path gracefully' , async ( ) => {
64+ const zip = path . join ( __dirname , 'resources' , 'zip with whitespace.zip' ) ;
65+ const out = track . mkdirSync ( ) ;
66+ const actual = await testMe . adjustArchiveStructure ( zip , out , true ) ;
67+ expect ( actual ) . to . be . equal ( path . join ( out , 'zip with whitespace.zip' ) ) ;
68+ console . log ( actual ) ;
69+ expect ( fs . existsSync ( actual ) ) . to . be . true ;
70+ 71+ const verifyOut = track . mkdirSync ( ) ;
72+ await unpack ( actual , verifyOut ) ;
73+ 74+ const root = path . join ( verifyOut , 'zip with whitespace' ) ;
75+ expect ( fs . existsSync ( root ) ) . to . be . true ;
76+ expect ( fs . lstatSync ( root ) . isDirectory ( ) ) . to . be . true ;
77+ const subs = fs . readdirSync ( root ) ;
78+ expect ( subs ) . to . have . lengthOf ( 3 ) ;
79+ expect ( subs . sort ( ) ) . to . be . deep . equal ( [ 'a.txt' , 'b.txt' , 'foo' ] ) ;
80+ } ) ;
81+ 82+ it ( 'should keep the symlinks after ZIP adjustments' , async function ( ) {
83+ if ( process . platform === 'win32' ) {
84+ this . skip ( ) ;
85+ }
86+ const zip = path . join ( __dirname , 'resources' , 'zip-with-symlink.zip' ) ;
87+ const out = track . mkdirSync ( ) ;
88+ const actual = await testMe . adjustArchiveStructure ( zip , out , true ) ;
89+ expect ( actual ) . to . be . equal ( path . join ( out , 'zip-with-symlink.zip' ) ) ;
90+ console . log ( actual ) ;
91+ expect ( fs . existsSync ( actual ) ) . to . be . true ;
92+ 93+ const verifyOut = track . mkdirSync ( ) ;
94+ await unpack ( actual , verifyOut ) ;
95+ expect ( fs . lstatSync ( path . join ( verifyOut , 'zip-with-symlink' , 'folder' , 'symlinked-sub' ) ) . isSymbolicLink ( ) ) . to . be . true ;
96+ } ) ;
97+ 98+ it ( 'should adjust the archive structure if base folder is not present' , async ( ) => {
99+ const zip = path . join ( __dirname , 'resources' , 'zip-without-symlink.zip' ) ;
100+ const out = track . mkdirSync ( ) ;
101+ const actual = await testMe . adjustArchiveStructure ( zip , out , true ) ;
102+ expect ( actual ) . to . be . equal ( path . join ( out , 'zip-without-symlink.zip' ) ) ;
103+ console . log ( actual ) ;
104+ expect ( fs . existsSync ( actual ) ) . to . be . true ;
105+ 106+ const verifyOut = track . mkdirSync ( ) ;
107+ await unpack ( actual , verifyOut ) ;
108+ 109+ const root = path . join ( verifyOut , 'zip-without-symlink' ) ;
110+ expect ( fs . existsSync ( root ) ) . to . be . true ;
111+ expect ( fs . lstatSync ( root ) . isDirectory ( ) ) . to . be . true ;
112+ const subs = fs . readdirSync ( root ) ;
113+ expect ( subs ) . to . have . lengthOf ( 3 ) ;
114+ expect ( subs . sort ( ) ) . to . be . deep . equal ( [ 'a.txt' , 'b.txt' , 'foo' ] ) ;
115+ } ) ;
116+ 117+ } ) ;
118+ 119+ } ) ;
0 commit comments