// Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. 'use strict'; const assert = require('assert'); const fs = require('fs'); const path = require('path'); const io = require('../../io'); const devmode = require('../../lib/devmode'); const zip = require('../../io/zip'); const {InvalidArgumentError} = require('../../lib/error'); const SAMPLE_XPI_PATH = path.join(__dirname, '../../lib/test/data/firefox/sample.xpi'); describe('io/zip', function() { describe('unzip', function() { it('creates destination dir if necessary', function() { return io.tmpDir() .then(dir => zip.unzip(SAMPLE_XPI_PATH, dir)) .then(dir => { assertExists(path.join(dir, 'chrome.manifest')); assertExists(path.join(dir, 'content/overlay.js')); assertExists(path.join(dir, 'content/overlay.xul')); assertExists(path.join(dir, 'install.rdf')); }); }); }); describe('Zip', function() { let dir; beforeEach(function() { return io.tmpDir().then(d => dir = d); }); it('can convert an archive to a buffer', function() { let z = new zip.Zip; return io.mkdirp(path.join(dir, 'a/b/c/d/e')).then(() => { return Promise.all([ io.write(path.join(dir, 'foo'), 'a file'), io.write(path.join(dir, 'a/b/c/carrot'), 'an orange carrot'), io.write(path.join(dir, 'a/b/c/d/e/elephant'), 'e is for elephant') ]); }) .then(() => z.addDir(dir)) .then(() => Promise.all([io.tmpDir(), z.toBuffer()])) .then(([outDir, buf]) => { let output = path.join(outDir, 'out.zip'); return io.write(output, buf) .then(() => io.tmpDir()) .then(d => zip.unzip(output, d)) .then(d => { assertContents(path.join(d, 'foo'), 'a file'); assertContents(path.join(d, 'a/b/c/carrot'), 'an orange carrot'); assertContents( path.join(d, 'a/b/c/d/e/elephant'), 'e is for elephant'); }); }); }); describe('getFile', function() { it('returns archive file contents as a buffer', function() { let foo = path.join(dir, 'foo'); fs.writeFileSync(foo, 'hello, world!'); let z = new zip.Zip; return z.addFile(foo).then(() => { assert.ok(z.has('foo')); return z.getFile('foo'); }).then( buffer => assert.equal(buffer.toString('utf8'), 'hello, world!')); }); it('returns an error if file is not in archive', function() { let z = new zip.Zip; assert.ok(!z.has('some-file')); return z.getFile('some-file') .then(() => assert.fail('should have failed'), e => assert.strictEqual(e.constructor, InvalidArgumentError)); }); it( 'returns a rejected promise if the requested path is a directory', function() { let file = path.join(dir, 'aFile'); fs.writeFileSync(file, 'hello, world!'); let z = new zip.Zip; return z.addDir(dir, 'foo') .then(() => z.getFile('foo')) .then( () => assert.fail('should have failed'), e => assert.strictEqual( e.constructor, InvalidArgumentError)) .then(() => z.getFile('foo/aFile')) .then(b => assert.equal(b.toString('utf8'), 'hello, world!')); }); }); }); function assertExists(p) { assert.ok(fs.existsSync(p), `expected ${p} to exist`); } function assertContents(p, c) { assert.strictEqual( fs.readFileSync(p, 'utf8'), c, `unexpected file contents for ${p}`); } });