From 6e8ad9636f60f5cbbac92a97c481bba95a9808ee Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Wed, 12 Apr 2017 14:17:40 -0700 Subject: [PATCH] Fix network tests for node-libcurl (#141) --- app/__mocks__/node-libcurl.js | 117 ++++++ app/network/__tests__/network.test.js | 550 +++++++++++++------------- app/network/network.js | 11 +- package.json | 5 +- 4 files changed, 405 insertions(+), 278 deletions(-) create mode 100644 app/__mocks__/node-libcurl.js diff --git a/app/__mocks__/node-libcurl.js b/app/__mocks__/node-libcurl.js new file mode 100644 index 000000000..d10b7cfd1 --- /dev/null +++ b/app/__mocks__/node-libcurl.js @@ -0,0 +1,117 @@ +import {EventEmitter} from 'events'; + +class Curl extends EventEmitter { + constructor () { + super(); + this._options = {}; + } + + setOpt (name, value) { + if (!name) { + throw new Error(`Invalid option ${name} ${value}`); + } + + if (name === Curl.option.CAINFO) { + // Just ignore this because it's platform-specific + return; + } + + if (name === Curl.option.COOKIELIST) { + // This can be set multiple times + this._options[name] = this._options[name] || []; + this._options[name].push(value); + } else { + this._options[name] = value; + } + } + + getInfo (name) { + switch (name) { + case Curl.info.COOKIELIST: + return [`#HttpOnly_.insomnia.rest\tTRUE\t/url/path\tTRUE\t${Date.now() / 1000}\tfoo\tbar`]; + case Curl.info.EFFECTIVE_URL: + return this._options[Curl.option.URL]; + case Curl.info.TOTAL_TIME: + return 700; + case Curl.info.SIZE_DOWNLOAD: + return 800; + default: + throw new Error(`Invalid info ${name}`); + } + } + + perform () { + process.nextTick(() => { + const data = Buffer.from(JSON.stringify({ + options: this._options + })); + + this.emit('data', data); + + process.nextTick(() => { + this.emit('end', 'NOT_USED', 'NOT_USED', [{ + 'Content-Length': `${data.length}`, + 'Content-Type': 'application/json', + result: {code: 200, reason: 'OK'} + }]); + }); + }); + } + + close () { + } +} + +Curl.info = { + COOKIELIST: 'COOKIELIST', + EFFECTIVE_URL: 'EFFECTIVE_URL', + SIZE_DOWNLOAD: 'SIZE_DOWNLOAD', + TOTAL_TIME: 'TOTAL_TIME', + debug: { + DATA_IN: 'DATA_IN', + DATA_OUT: 'DATA_OUT', + SSL_DATA_IN: 'SSL_DATA_IN', + SSL_DATA_OUT: 'SSL_DATA_OUT', + TEXT: 'TEXT' + } +}; + +Curl.auth = { + ANY: 'ANY' +}; + +Curl.option = { + CAINFO: 'CAINFO', + COOKIEFILE: 'COOKIEFILE', + COOKIELIST: 'COOKIELIST', + CUSTOMREQUEST: 'CUSTOMREQUEST', + DEBUGFUNCTION: 'DEBUGFUNCTION', + ENCODING: 'ENCODING', + FOLLOWLOCATION: 'FOLLOWLOCATION', + HTTPAUTH: 'HTTPAUTH', + HTTPHEADER: 'HTTPHEADER', + HTTPPOST: 'HTTPPOST', + KEYPASSWD: 'KEYPASSWD', + NOPROGRESS: 'NOPROGRESS', + PASSWORD: 'PASSWORD', + POSTFIELDS: 'POSTFIELDS', + PROXY: 'PROXY', + PROXYAUTH: 'PROXYAUTH', + READDATA: 'READDATA', + SSLCERT: 'SSLCERT', + SSLCERTTYPE: 'SSLCERTTYPE', + SSLKEY: 'SSLKEY', + SSL_VERIFYHOST: 'SSL_VERIFYHOST', + SSL_VERIFYPEER: 'SSL_VERIFYPEER', + TIMEOUT_MS: 'TIMEOUT_MS', + UPLOAD: 'UPLOAD', + URL: 'URL', + USERAGENT: 'USERAGENT', + USERNAME: 'USERNAME', + VERBOSE: 'VERBOSE', + XFERINFOFUNCTION: 'XFERINFOFUNCTION' +}; + +module.exports = { + Curl: Curl +}; diff --git a/app/network/__tests__/network.test.js b/app/network/__tests__/network.test.js index 48ef847c1..9073b0572 100644 --- a/app/network/__tests__/network.test.js +++ b/app/network/__tests__/network.test.js @@ -1,273 +1,283 @@ -// import * as networkUtils from '../network'; -// import * as db from '../../common/database'; -// import nock from 'nock'; -// import {resolve as pathResolve, join as pathJoin} from 'path'; -// import {getRenderedRequest} from '../../common/render'; -// import * as models from '../../models'; -// import {CONTENT_TYPE_FORM_URLENCODED, getAppVersion, CONTENT_TYPE_FILE, CONTENT_TYPE_FORM_DATA, AUTH_BASIC} from '../../common/constants'; +import * as networkUtils from '../network'; +import * as db from '../../common/database'; +import {join as pathJoin, resolve as pathResolve} from 'path'; +import {getRenderedRequest} from '../../common/render'; +import * as models from '../../models'; +import {AUTH_BASIC, CONTENT_TYPE_FILE, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, getAppVersion} from '../../common/constants'; -describe('no-op', () => { - it('no-ops', () => { - expect(true).toBeTruthy(); +describe('actuallySend()', () => { + beforeEach(() => db.init(models.types(), {inMemoryOnly: true}, true)); + + it('sends a generic request', async () => { + const workspace = await models.workspace.create(); + const settings = await models.settings.create(); + const cookies = [{ + creation: new Date('2016-10-05T04:40:49.505Z'), + key: 'foo', + value: 'barrrrr', + expires: new Date('2096-10-12T04:40:49.000Z'), + domain: 'notlocalhost', + path: '/', + hostOnly: true, + lastAccessed: new Date('2096-10-05T04:40:49.505Z') + }, { + creation: new Date('2016-10-05T04:40:49.505Z'), + key: 'foo', + value: 'bar', + expires: new Date('2096-10-12T04:40:49.000Z'), + domain: 'localhost', + path: '/', + hostOnly: true, + lastAccessed: new Date('2096-10-05T04:40:49.505Z') + }]; + + await models.cookieJar.create({ + parentId: workspace._id, + cookies + }); + + const request = Object.assign(models.request.init(), { + _id: 'req_123', + parentId: workspace._id, + headers: [{name: 'Content-Type', value: 'application/json'}], + parameters: [{name: 'foo bar', value: 'hello&world'}], + method: 'POST', + body: { + mimeType: CONTENT_TYPE_FORM_URLENCODED, + params: [{name: 'foo', value: 'bar'}] + }, + url: 'http://localhost', + authentication: { + type: AUTH_BASIC, + username: 'user', + password: 'pass' + } + }); + + const renderedRequest = await getRenderedRequest(request); + const response = await networkUtils._actuallySend( + renderedRequest, + workspace, + settings + ); + + const body = JSON.parse(Buffer.from(response.body, 'base64')); + expect(body).toEqual({ + options: { + COOKIEFILE: '', + COOKIELIST: [ + 'notlocalhost\tTRUE\t/\tFALSE\t4000855249\tfoo\tbarrrrr', + 'localhost\tTRUE\t/\tFALSE\t4000855249\tfoo\tbar' + ], + CUSTOMREQUEST: 'POST', + ENCODING: '', + FOLLOWLOCATION: true, + HTTPHEADER: [ + 'Content-Type: application/json', + 'Expect: ', + 'Transfer-Encoding: ' + ], + NOPROGRESS: false, + USERNAME: 'user', + PASSWORD: 'pass', + POSTFIELDS: 'foo=bar', + PROXY: '', + TIMEOUT_MS: 0, + URL: 'http://localhost/?foo%20bar=hello%26world', + USERAGENT: `insomnia/${getAppVersion()}`, + VERBOSE: true + } + }); + }); + + it('skips sending and storing cookies with setting', async () => { + const workspace = await models.workspace.create(); + const settings = await models.settings.create(); + const cookies = [{ + creation: new Date('2016-10-05T04:40:49.505Z'), + key: 'foo', + value: 'barrrrr', + expires: new Date('2096-10-12T04:40:49.000Z'), + domain: 'notlocalhost', + path: '/', + hostOnly: true, + lastAccessed: new Date('2096-10-05T04:40:49.505Z') + }, { + creation: new Date('2016-10-05T04:40:49.505Z'), + key: 'foo', + value: 'barrrrr', + expires: new Date('2096-10-12T04:40:49.000Z'), + domain: 'localhost', + path: '/', + hostOnly: true, + lastAccessed: new Date('2096-10-05T04:40:49.505Z') + }]; + + await models.cookieJar.create({ + parentId: workspace._id, + cookies + }); + + const request = Object.assign(models.request.init(), { + _id: 'req_123', + parentId: workspace._id, + headers: [{name: 'Content-Type', value: 'application/json'}], + parameters: [{name: 'foo bar', value: 'hello&world'}], + method: 'POST', + body: { + mimeType: CONTENT_TYPE_FORM_URLENCODED, + params: [{name: 'foo', value: 'bar'}] + }, + url: 'http://localhost', + authentication: { + type: AUTH_BASIC, + username: 'user', + password: 'pass' + }, + settingStoreCookies: false, + settingSendCookies: false + }); + + const renderedRequest = await getRenderedRequest(request); + const response = await networkUtils._actuallySend( + renderedRequest, + workspace, + settings + ); + + const body = JSON.parse(Buffer.from(response.body, 'base64')); + expect(body).toEqual({ + options: { + COOKIEFILE: '', + CUSTOMREQUEST: 'POST', + ENCODING: '', + FOLLOWLOCATION: true, + HTTPHEADER: [ + 'Content-Type: application/json', + 'Expect: ', + 'Transfer-Encoding: ' + ], + NOPROGRESS: false, + USERNAME: 'user', + PASSWORD: 'pass', + POSTFIELDS: 'foo=bar', + PROXY: '', + TIMEOUT_MS: 0, + URL: 'http://localhost/?foo%20bar=hello%26world', + USERAGENT: `insomnia/${getAppVersion()}`, + VERBOSE: true + } + }); + }); + + it('sends a file', async () => { + const workspace = await models.workspace.create(); + const settings = await models.settings.create(); + await models.cookieJar.create({parentId: workspace._id}); + + const request = Object.assign(models.request.init(), { + _id: 'req_123', + parentId: workspace._id, + headers: [{name: 'Content-Type', value: 'application/octet-stream'}], + url: 'http://localhost', + method: 'POST', + body: { + mimeType: CONTENT_TYPE_FILE, + fileName: pathResolve(pathJoin(__dirname, './testfile.txt')) // Let's send ourselves + } + }); + + const renderedRequest = await getRenderedRequest(request); + const response = await networkUtils._actuallySend( + renderedRequest, + workspace, + settings + ); + + const body = JSON.parse(Buffer.from(response.body, 'base64')); + + // READDATA is an fd (random int), so fuzzy assert this one + expect(typeof body.options.READDATA).toBe('number'); + delete body.options.READDATA; + + expect(body).toEqual({ + options: { + COOKIEFILE: '', + CUSTOMREQUEST: 'POST', + ENCODING: '', + FOLLOWLOCATION: true, + HTTPHEADER: [ + 'Content-Type: application/octet-stream', + 'Content-Length: 13', + 'Expect: ', + 'Transfer-Encoding: ' + ], + NOPROGRESS: false, + PROXY: '', + TIMEOUT_MS: 0, + UPLOAD: 1, + URL: 'http://localhost/', + USERAGENT: `insomnia/${getAppVersion()}`, + VERBOSE: true + } + }); + }); + + it('sends multipart form data', async () => { + const workspace = await models.workspace.create(); + const settings = await models.settings.create(); + await models.cookieJar.create({parentId: workspace._id}); + const fileName = pathResolve(pathJoin(__dirname, './testfile.txt')); + + const request = Object.assign(models.request.init(), { + _id: 'req_123', + parentId: workspace._id, + headers: [{name: 'Content-Type', value: 'multipart/form-data'}], + url: 'http://localhost', + method: 'POST', + body: { + mimeType: CONTENT_TYPE_FORM_DATA, + params: [ + // Should ignore value and send the file since type is set to file + {name: 'foo', fileName: fileName, value: 'bar', type: 'file'}, + + // Some extra params + {name: 'a', value: 'AA'}, + {name: 'baz', value: 'qux', disabled: true} + ] + } + }); + + const renderedRequest = await getRenderedRequest(request); + const response = await networkUtils._actuallySend( + renderedRequest, + workspace, + settings + ); + + const body = JSON.parse(Buffer.from(response.body, 'base64')); + expect(body).toEqual({ + options: { + COOKIEFILE: '', + CUSTOMREQUEST: 'POST', + ENCODING: '', + FOLLOWLOCATION: true, + HTTPHEADER: [ + 'Content-Type: multipart/form-data', + 'Expect: ', + 'Transfer-Encoding: ' + ], + HTTPPOST: [ + {file: fileName, name: 'foo', type: 'text/plain'}, + {contents: 'AA', name: 'a'} + ], + NOPROGRESS: false, + PROXY: '', + TIMEOUT_MS: 0, + URL: 'http://localhost/', + USERAGENT: `insomnia/${getAppVersion()}`, + VERBOSE: true + } + }); }); }); - -// describe('actuallySend()', () => { -// beforeEach(() => db.init(models.types(), {inMemoryOnly: true}, true)); -// -// it('sends a generic request', async () => { -// let mock; -// -// const workspace = await models.workspace.create(); -// const settings = await models.settings.create(); -// const cookies = [{ -// creation: new Date('2016-10-05T04:40:49.505Z'), -// key: 'foo', -// value: 'barrrrr', -// expires: new Date('2096-10-12T04:40:49.000Z'), -// domain: 'notlocalhost', -// path: '/', -// hostOnly: true, -// lastAccessed: new Date('2096-10-05T04:40:49.505Z') -// }, { -// creation: new Date('2016-10-05T04:40:49.505Z'), -// key: 'foo', -// value: 'barrrrr', -// expires: new Date('2096-10-12T04:40:49.000Z'), -// domain: 'localhost', -// path: '/', -// hostOnly: true, -// lastAccessed: new Date('2096-10-05T04:40:49.505Z') -// }]; -// -// await models.cookieJar.create({ -// parentId: workspace._id, -// cookies -// }); -// -// mock = nock('http://localhost') -// .matchHeader('Content-Type', 'application/json') -// .matchHeader('Authorization', 'Basic dXNlcjpwYXNz') -// .matchHeader('Accept', '*/*') -// .matchHeader('User-Agent', `insomnia/${getAppVersion()}`) -// .matchHeader('Cookie', 'foo=barrrrr') -// .post('/', 'foo=bar') -// .query({'foo bar': 'hello&world'}) -// .reply(200, 'response body') -// .log(console.log); -// -// const request = Object.assign(models.request.init(), { -// _id: 'req_123', -// parentId: workspace._id, -// headers: [{name: 'Content-Type', value: 'application/json'}], -// parameters: [{name: 'foo bar', value: 'hello&world'}], -// method: 'POST', -// body: { -// mimeType: CONTENT_TYPE_FORM_URLENCODED, -// params: [{name: 'foo', value: 'bar'}] -// }, -// url: 'http://localhost', -// authentication: { -// type: AUTH_BASIC, -// username: 'user', -// password: 'pass' -// } -// }); -// -// const renderedRequest = await getRenderedRequest(request); -// const response = await networkUtils._actuallySend( -// renderedRequest, -// workspace, -// settings -// ); -// -// expect(mock.basePath).toBe('http://localhost:80'); -// expect(response.error).toBe(undefined); -// expect(response.url).toBe('http://localhost/?foo%20bar=hello%26world'); -// expect(response.body).toBe(new Buffer('response body').toString('base64')); -// expect(response.statusCode).toBe(200); -// }); -// -// it('skips sending and storing cookies with setting', async () => { -// let mock; -// -// const workspace = await models.workspace.create(); -// const settings = await models.settings.create(); -// const cookies = [{ -// creation: new Date('2016-10-05T04:40:49.505Z'), -// key: 'foo', -// value: 'barrrrr', -// expires: new Date('2096-10-12T04:40:49.000Z'), -// domain: 'notlocalhost', -// path: '/', -// hostOnly: true, -// lastAccessed: new Date('2096-10-05T04:40:49.505Z') -// }, { -// creation: new Date('2016-10-05T04:40:49.505Z'), -// key: 'foo', -// value: 'barrrrr', -// expires: new Date('2096-10-12T04:40:49.000Z'), -// domain: 'localhost', -// path: '/', -// hostOnly: true, -// lastAccessed: new Date('2096-10-05T04:40:49.505Z') -// }]; -// -// await models.cookieJar.create({ -// parentId: workspace._id, -// cookies -// }); -// -// mock = nock('http://localhost') -// .matchHeader('Content-Type', 'application/json') -// .matchHeader('Authorization', 'Basic dXNlcjpwYXNz') -// .matchHeader('Accept', '*/*') -// .matchHeader('User-Agent', `insomnia/${getAppVersion()}`) -// .post('/', 'foo=bar') -// .query({'foo bar': 'hello&world'}) -// .reply(200, 'response body', { -// 'Set-Cookie': 'foo=bar; expires=Tue, 27-Mar-38 22:54:51 GMT; path=/; HttpOnly' -// }) -// .log(console.log); -// -// const request = Object.assign(models.request.init(), { -// _id: 'req_123', -// parentId: workspace._id, -// headers: [{name: 'Content-Type', value: 'application/json'}], -// parameters: [{name: 'foo bar', value: 'hello&world'}], -// method: 'POST', -// body: { -// mimeType: CONTENT_TYPE_FORM_URLENCODED, -// params: [{name: 'foo', value: 'bar'}] -// }, -// url: 'http://localhost', -// authentication: { -// type: AUTH_BASIC, -// username: 'user', -// password: 'pass' -// }, -// settingStoreCookies: false, -// settingSendCookies: false -// }); -// -// const renderedRequest = await getRenderedRequest(request); -// const response = await networkUtils._actuallySend( -// renderedRequest, -// workspace, -// settings -// ); -// -// expect(mock.basePath).toBe('http://localhost:80'); -// expect(response.error).toBe(undefined); -// expect(response.url).toBe('http://localhost/?foo%20bar=hello%26world'); -// expect(response.body).toBe(new Buffer('response body').toString('base64')); -// expect(response.statusCode).toBe(200); -// }); -// -// it('sends a file', async () => { -// let mock; -// -// const workspace = await models.workspace.create(); -// const settings = await models.settings.create(); -// await models.cookieJar.create({parentId: workspace._id}); -// -// mock = nock('http://localhost') -// .matchHeader('Content-Type', 'application/octet-stream') -// .matchHeader('Accept', '*/*') -// .matchHeader('User-Agent', `insomnia/${getAppVersion()}`) -// .post('/', 'Hello World!') -// .reply(200, 'response body') -// .log(console.log); -// -// const request = Object.assign(models.request.init(), { -// _id: 'req_123', -// parentId: workspace._id, -// headers: [{name: 'Content-Type', value: 'application/octet-stream'}], -// url: 'http://localhost', -// method: 'POST', -// body: { -// mimeType: CONTENT_TYPE_FILE, -// fileName: pathResolve(pathJoin(__dirname, './testfile.txt')) // Let's send ourselves -// } -// }); -// -// const renderedRequest = await getRenderedRequest(request); -// const response = await networkUtils._actuallySend( -// renderedRequest, -// workspace, -// settings -// ); -// -// expect(mock.basePath).toBe('http://localhost:80'); -// expect(response.error).toBe(undefined); -// expect(response.url).toBe('http://localhost/'); -// expect(response.body).toBe(new Buffer('response body').toString('base64')); -// expect(response.statusCode).toBe(200); -// }); -// -// it('sends multipart form data', async () => { -// let mock; -// -// const workspace = await models.workspace.create(); -// const settings = await models.settings.create(); -// await models.cookieJar.create({parentId: workspace._id}); -// const fileName = pathResolve(pathJoin(__dirname, './testfile.txt')); -// let requestBody = 'n/a'; -// mock = nock('http://localhost') -// .matchHeader('Content-Type', /^multipart\/form-data/) -// .matchHeader('Accept', '*/*') -// .matchHeader('User-Agent', `insomnia/${getAppVersion()}`) -// .post('/', body => { -// requestBody = body; -// return true; -// }) -// .reply(200, 'response body') -// .log(console.log); -// -// const request = Object.assign(models.request.init(), { -// _id: 'req_123', -// parentId: workspace._id, -// headers: [{name: 'Content-Type', value: 'multipart/form-data'}], -// url: 'http://localhost', -// method: 'POST', -// body: { -// mimeType: CONTENT_TYPE_FORM_DATA, -// params: [ -// // Should ignore value and send the file since type is set to file -// {name: 'foo', fileName: fileName, value: 'bar', type: 'file'}, -// -// // Some extra params -// {name: 'a', value: 'AA'}, -// {name: 'baz', value: 'qux', disabled: true} -// ] -// } -// }); -// -// const renderedRequest = await getRenderedRequest(request); -// const response = await networkUtils._actuallySend( -// renderedRequest, -// workspace, -// settings -// ); -// -// expect(mock.basePath).toBe('http://localhost:80'); -// expect(response.error).toBe(undefined); -// expect(response.url).toBe('http://localhost/'); -// expect(response.body).toBe(new Buffer('response body').toString('base64')); -// expect(response.statusCode).toBe(200); -// -// const lines = requestBody.split(/\r\n/); -// expect(lines[0]).toMatch(/^----------------------------\d{24}/); -// expect(lines[1]).toBe('Content-Disposition: form-data; name="foo"; filename="testfile.txt"'); -// expect(lines[2]).toBe('Content-Type: text/plain'); -// expect(lines[3]).toBe(''); -// expect(lines[4]).toBe('Hello World!\n'); -// expect(lines[5]).toMatch(/^----------------------------\d{24}/); -// expect(lines[6]).toBe('Content-Disposition: form-data; name="a"'); -// expect(lines[7]).toBe(''); -// expect(lines[8]).toBe('AA'); -// expect(lines[9]).toMatch(/^----------------------------\d{24}--/); -// expect(lines[10]).toBe(''); -// expect(lines.length).toBe(11); -// }); -// }); diff --git a/app/network/network.js b/app/network/network.js index 52207c9f0..408d47fc5 100644 --- a/app/network/network.js +++ b/app/network/network.js @@ -188,9 +188,11 @@ export function _actuallySend (renderedRequest, workspace, settings) { setOpt(Curl.option.CAINFO, fullCAPath); } - // Set cookies + // Enable cookie handling (this is required) + setOpt(Curl.option.COOKIEFILE, ''); + + // Set cookies from jar if (renderedRequest.settingSendCookies) { - setOpt(Curl.option.COOKIEFILE, ''); // Enable cookies const cookies = renderedRequest.cookieJar.cookies || []; for (const cookie of cookies) { let expiresTimestamp = 0; @@ -298,7 +300,8 @@ export function _actuallySend (renderedRequest, workspace, settings) { } else if (renderedRequest.body.mimeType === CONTENT_TYPE_FORM_DATA) { const data = renderedRequest.body.params.map(param => { if (param.type === 'file' && param.fileName) { - return {name: param.name, file: param.fileName, type: mimes.lookup(param.fileName)}; + const type = mimes.lookup(param.fileName) || 'application/octet-stream'; + return {name: param.name, file: param.fileName, type}; } else { return {name: param.name, contents: param.value}; } @@ -411,8 +414,8 @@ export function _actuallySend (renderedRequest, workspace, settings) { const contentType = contentTypeHeader ? contentTypeHeader.value : ''; // Update Cookie Jar - const cookieStrings = curl.getInfo(Curl.info.COOKIELIST); if (renderedRequest.settingStoreCookies) { + const cookieStrings = curl.getInfo(Curl.info.COOKIELIST); const cookies = cookieStrings.map(str => { // 0 1 2 3 4 5 6 // [#HttpOnly_.hostname, includeSubdomains, path, secure, expiry, name, value] diff --git a/package.json b/package.json index 126e83831..62ea4af2f 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "build:copy": "cp -r ./app/package.json ./app/static ./app/icons/* ./build/", "build:install": "cd build && npm install", "build": "npm run build:clean && npm run build:renderer && npm run build:main && npm run build:copy && npm run build:install", - "rebuild": "electron-rebuild -f -w node-libcurl", "package:mac": "rm -rf dist/mac && node node_modules/electron-builder/out/cli/build-cli.js --publish=never --x64 --mac", "package:win": "rm -rf dist/win* && node node_modules/electron-builder/out/cli/build-cli.js --publish=never --x64 --win", "package:linux": "rm -rf dist/linux && rm -f dist/*.AppImage && rm -f dist/*.deb && node node_modules/electron-builder/out/cli/build-cli.js --publish=never --x64 --linux", @@ -34,8 +33,7 @@ "build-n-package": "npm run build && npm run package", "build-n-package:win": "npm run build && npm run package:win", "build-n-package:mac": "npm run build && npm run package:mac", - "build-n-package:linux": "npm run build && npm run package:linux", - "sentry": "bash scripts/sentry-release.sh" + "build-n-package:linux": "npm run build && npm run package:linux" }, "jest": { "setupFiles": [ @@ -172,7 +170,6 @@ "jest": "~19.0.2", "less": "~2.7.2", "less-loader": "~2.2.3", - "nock": "~9.0.2", "react-hot-loader": "~3.0.0-beta.6", "redux-mock-store": "~1.0.2", "style-loader": "~0.13.2",