fix(unzip): handle sb2 files zipped with a folder

Uses a pattern to find the sprite or project json in a zipped folder or flat list of files.

Added tests for
* loading a sprite or project with a nested folder
* loading a file without a json

Fixes 
This commit is contained in:
chrisgarrity 2019-02-01 11:33:40 +01:00
parent 18579217e8
commit 750e866444
8 changed files with 55 additions and 7 deletions

View file

@ -23,10 +23,18 @@ module.exports = function (input, isGZip, isSprite, callback) {
}
return JSZip.loadAsync(input)
.then(function (zip) {
return zip.file(isSprite ? 'sprite.json' : 'project.json').async('string')
.then(function (project) {
return callback(null, [project, zip]);
});
// look for json in the list of files, or in a subdirectory
// assumes there is only one sprite or project json in the zipfile
const file = isSprite ?
zip.file(/^([^/]*\/)?sprite\.json$/)[0] :
zip.file(/^([^/]*\/)?project\.json$/)[0];
if (file) {
return file.async('string')
.then(function (project) {
return callback(null, [project, zip]);
});
}
return callback(msg + 'missing project or sprite json');
})
.catch(function (err) {
return callback(msg + JSON.stringify(err));

View file

@ -33,14 +33,16 @@ module.exports = {
sb: fs.readFileSync(path.resolve(__dirname, './data/_example.sb')),
sb2: fs.readFileSync(path.resolve(__dirname, './data/_example.sb2')),
json: fs.readFileSync(path.resolve(__dirname, './data/_example.json')),
gzipJson: fs.readFileSync(path.resolve(__dirname, './data/_example.json.gz'))
gzipJson: fs.readFileSync(path.resolve(__dirname, './data/_example.json.gz')),
invalidEmpty: fs.readFileSync(path.resolve(__dirname, './data/invalid/_invalidEmpty.sb2'))
},
sprites: {
default_cat_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_default_cat.sprite2')),
default_cat_sprite2_json: fs.readFileSync(path.resolve(__dirname, './data/_default_cat.sprite2json')),
example_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_example_sprite.sprite2')),
example_sprite2_json: fs.readFileSync(path.resolve(__dirname, './data/_example_sprite.sprite2json')),
bananas_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas.sprite2'))
bananas_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas.sprite2')),
bananas_nested_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas_nested.sprite2'))
},
sb3_comments: {
comments: fs.readFileSync(path.resolve(__dirname, './data/_comments.sb3')),

Binary file not shown.

BIN
test/fixtures/data/_nestedFolder.sb2 vendored Normal file

Binary file not shown.

Binary file not shown.

View file

@ -62,3 +62,13 @@ test('gzipped json', function (t) {
t.end();
});
});
test('invalid empty project archive', function (t) {
var msg = 'Failed to unzip and extract project.json, with error: ';
parser(data.example.invalidEmpty, false, function (err, result) {
t.type(err, 'string');
t.equal(err.startsWith(msg), true);
t.type(result, 'undefined');
t.end();
});
});

View file

@ -42,6 +42,19 @@ test('banana sprite2, no sounds', function (t) {
});
});
test('nested banana sprite2', function (t) {
parser(data.sprites.bananas_nested_sprite2, true, function (err, result) {
t.equal(err, null);
t.equal(Array.isArray(result), true);
var res = result[0];
var possibleZip = result[1];
t.type(res, 'object');
t.equal(res.projectVersion, 2);
t.equal(possibleZip instanceof JSZip, true);
t.end();
});
});
test('default cat sprite2 json', function (t) {
parser(data.sprites.default_cat_sprite2_json, true, function (err, result) {
t.equal(err, null);

View file

@ -11,7 +11,8 @@ var fixtures = {
zipFakeProjectJSON:
path.resolve(__dirname, '../fixtures/data/_zipFakeProjectJson.zip'),
zipNoProjectJSON:
path.resolve(__dirname, '../fixtures/data/_zipNoProjectJson.zip')
path.resolve(__dirname, '../fixtures/data/_zipNoProjectJson.zip'),
sb2Nested: path.resolve(__dirname, '../fixtures/data/_nestedFolder.sb2')
};
for (var i in fixtures) {
@ -63,6 +64,20 @@ test('gzipped JSON', function (t) {
});
});
test('sb2 with nested folder', function (t) {
var buffer = new Buffer(fixtures.sb2Nested);
unzip(buffer, false, false, function (err, res) {
t.equal(err, null);
t.equal(Array.isArray(res), true);
t.type(res[0], 'string');
t.doesNotThrow(function () {
JSON.parse(res[0]);
});
t.equal(res[1] instanceof JSZip, true);
t.end();
});
});
test('zip without project json', function (t) {
var buffer = new Buffer(fixtures.zipNoProjectJSON);
unzip(buffer, false, false, function (err, res) {