Skip to content

Commit

Permalink
feat: (strf-8608) replace "request" with "node-fetch"
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxGenash committed Sep 14, 2020
1 parent e097e36 commit e758b01
Show file tree
Hide file tree
Showing 7 changed files with 286 additions and 306 deletions.
183 changes: 84 additions & 99 deletions lib/stencil-download.utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const request = require("request");
const fetch = require('node-fetch');
const yauzl = require('yauzl');
const fs = require('fs');
const tmp = require('tmp');
Expand All @@ -13,122 +13,107 @@ utils.downloadThemeFiles = (options, callback) => {
callback(err);
}

(
new Promise(
(resolve, reject) =>
request(options.downloadUrl)
.pipe(fs.createWriteStream(tempThemePath))
.on('finish', () => resolve(tempThemePath))
.on('error', reject),
)
)
.then(tempThemePath =>
new Promise(
(resolve, reject) => {
let foundMatch = false;

console.log('ok'.green + ' -- Theme files downloaded');
console.log('ok'.green + ' -- Extracting theme files');

yauzl.open(tempThemePath, {lazyEntries: true}, (error, zipFile) => {

if (error) {
return reject(error);
Promise.resolve()
.then(() => fetch(options.downloadUrl))
.then(response => new Promise((resolve, reject) => {
if (!response.ok) {
reject(`Unable to download theme files from ${options.downloadUrl}: ${response.statusText}`);
}

response.body.pipe(fs.createWriteStream(tempThemePath))
.on('finish', () => resolve(tempThemePath))
.on('error', reject);
}))
.then(tempThemePath => new Promise((resolve, reject) => {
let foundMatch = false;

console.log('ok'.green + ' -- Theme files downloaded');
console.log('ok'.green + ' -- Extracting theme files');

yauzl.open(tempThemePath, {lazyEntries: true}, (error, zipFile) => {
if (error) {
return reject(error);
}

zipFile.on('entry', entry => {
zipFile.openReadStream(entry, (readStreamError, readStream) => {
if (readStreamError) {
return reject(readStreamError);
}

zipFile.on('entry', entry => {
let configFileData = '';

zipFile.openReadStream(entry, (readStreamError, readStream) => {
if (readStreamError) {
return reject(readStreamError);
if (options.file && options.file.length) {
if (options.file !== entry.fileName) {
zipFile.readEntry();
return;
}
foundMatch = true;
} else if (options.exclude && options.exclude.length) {
// Do not process any file or directory within the exclude option
for (const excludeItem of options.exclude) {
if (entry.fileName.startsWith(excludeItem)) {
zipFile.readEntry();
return;
}
}
}

let configFileData = '';
// Create a directory if the parent directory does not exists
const parsedPath = path.parse(entry.fileName);

if (options.file && options.file.length) {
if (parsedPath.dir && !fs.existsSync(parsedPath.dir)) {
fs.mkdirSync(parsedPath.dir, {recursive: true});
}

if (options.file !== entry.fileName) {
zipFile.readEntry();
return;
}
foundMatch = true;

} else if (options.exclude && options.exclude.length) {

/**
* Do not process any file or directory within the exclude option
*/
for (let i = 0; i < options.exclude.length; i++) {
if ((entry.fileName).startsWith(options.exclude[i])) {
zipFile.readEntry();
return;
}
}
}
// If file is a directory, then move to next
if (/\/$/.test(entry.fileName)) {
zipFile.readEntry();
return;
}

/**
* Create a directory if the parent directory does not exists
*/
const parsedPath = path.parse(entry.fileName);
readStream.on('end', () => {
if (entry.fileName.endsWith('.json')) {
configFileData = JSON.stringify(JSON.parse(configFileData), null, 2);
}

if (parsedPath.dir && !fs.existsSync(parsedPath.dir)) {
fs.mkdirSync(parsedPath.dir, {recursive: true});
fs.writeFile(entry.fileName, configFileData, {flag: 'w+'}, error => {
if (error) {
reject(error);
}

/**
* If file is a directory, then move to next
*/
if (/\/$/.test(entry.fileName)) {
// Close read if file requested is found
if (options.file && options.file.length) {
console.log('ok'.green + ' -- Theme files extracted');
zipFile.close();
resolve(options);
} else {
zipFile.readEntry();
return;
}

readStream.on('end', () => {
if (entry.fileName.endsWith('.json')) {
configFileData = JSON.stringify(JSON.parse(configFileData), null, 2);
}

fs.writeFile(entry.fileName, configFileData, {flag: 'w+'}, error => {
if (error) {
reject(error);
}

/**
* Close read if file requested is found
*/
if (options.file && options.file.length) {
console.log('ok'.green + ' -- Theme files extracted');
zipFile.close();
resolve(options);
} else {
zipFile.readEntry();
}
});
});

readStream.on('data', chunk => {
configFileData += chunk;
});
});
});

zipFile.readEntry();

zipFile.once('end', function () {
if (!foundMatch && (options.file && options.file.length)) {
console.log('Warning'.yellow + ` -- ${options.file} not found!`);
reject(`${options.file} not found`);
return;
}

console.log('ok'.green + ' -- Theme files extracted');
zipFile.close();
resolve(options);
readStream.on('data', chunk => {
configFileData += chunk;
});
});
},
),
)
});

zipFile.readEntry();

zipFile.once('end', function () {
if (!foundMatch && (options.file && options.file.length)) {
console.log('Warning'.yellow + ` -- ${options.file} not found!`);
reject(`${options.file} not found`);
return;
}

console.log('ok'.green + ' -- Theme files extracted');
zipFile.close();
resolve(options);
});
});
}))
.then(() => {
cleanupCallback();
callback(null, options);
Expand Down
48 changes: 24 additions & 24 deletions lib/stencil-download.utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ const fs = require('fs');
const Path = require('path');
const { promisify } = require('util');
const yauzl = require('yauzl');
const request = require("request");
const fetch = require('node-fetch');
const tmp = require('tmp');

const { downloadThemeFiles } = require('./stencil-download.utils');

jest.mock('node-fetch');

describe('ThemeDownloader', function () {
let archiveMockUrl = Path.join(process.cwd(), 'test', '_mocks', 'themes', 'valid', 'mock-theme.zip');
let themeCallback;
Expand All @@ -24,31 +26,38 @@ describe('ThemeDownloader', function () {

jest.spyOn(console, 'log').mockImplementation(jest.fn());

jest.spyOn(request, 'Request').mockImplementation(requestStub);
fetch.mockImplementation(async() => ({
ok: true,
body: {
pipe: function responseBodyStreamStub () {
return {
pipe: () => {
return this;
},
on: (event, optionCallback) => {
if (event === 'finish') {
optionCallback();
}
return this;
},
};
},
},
}));

fsWriteSub = jest.spyOn(fs, 'writeFile').mockImplementation(writeFileStub);

function writeFileStub(name, config, options, callback) {
callback(false);
}

function requestStub(option) {
this.pipe = () => {
return this;
};
this.on = (event, optionCallback) => {
if (event === 'finish') {
optionCallback(option.uri);
}
return this;
};
}

fsCreateWriteStreamStub = jest.spyOn(fs, 'createWriteStream').mockImplementation(tempPath => {
fs.writeFileSync(tempPath, fs.readFileSync(options.downloadUrl));
});
});

afterEach(() => {
jest.resetAllMocks();
jest.restoreAllMocks();
});

Expand All @@ -58,10 +67,6 @@ describe('ThemeDownloader', function () {
zipOpenSpy(archiveMockUrl, {lazyEntries: true}, themeCallback);
});

afterEach(() => {
jest.restoreAllMocks();
});

it('should verify that the tmp.file() is called', async () => {
const tmpFileSpy = jest.spyOn(tmp, 'file');

Expand All @@ -83,7 +88,7 @@ describe('ThemeDownloader', function () {
zipOpenSpy.mock.calls[0][2]();
await promise;

expect(request.Request).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledTimes(1);
});

it('should verify createWriteStream is also called within the request', async () => {
Expand All @@ -110,11 +115,6 @@ describe('ThemeDownloader', function () {
});

describe("Verify After zip opens", () => {
afterEach(() => {
options = { downloadUrl: archiveMockUrl };
jest.restoreAllMocks();
});

it('should write the two files inside the zip archive', async () => {
await promisify(downloadThemeFiles)(options);

Expand Down
Loading

0 comments on commit e758b01

Please sign in to comment.