build: enable JS semicolons (#22783)
This commit is contained in:
parent
24e21467b9
commit
5d657dece4
354 changed files with 21512 additions and 21510 deletions
|
@ -1,50 +1,50 @@
|
|||
import { expect } from 'chai'
|
||||
import * as cp from 'child_process'
|
||||
import * as http from 'http'
|
||||
import * as express from 'express'
|
||||
import * as fs from 'fs-extra'
|
||||
import * as os from 'os'
|
||||
import * as path from 'path'
|
||||
import { AddressInfo } from 'net'
|
||||
import { expect } from 'chai';
|
||||
import * as cp from 'child_process';
|
||||
import * as http from 'http';
|
||||
import * as express from 'express';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { AddressInfo } from 'net';
|
||||
|
||||
const features = process.electronBinding('features')
|
||||
const features = process.electronBinding('features');
|
||||
|
||||
const fixturesPath = path.resolve(__dirname, 'fixtures')
|
||||
const fixturesPath = path.resolve(__dirname, 'fixtures');
|
||||
|
||||
// We can only test the auto updater on darwin non-component builds
|
||||
const describeFn = (process.platform === 'darwin' && !process.mas && !features.isComponentBuild() ? describe : describe.skip)
|
||||
const describeFn = (process.platform === 'darwin' && !process.mas && !features.isComponentBuild() ? describe : describe.skip);
|
||||
|
||||
describeFn('autoUpdater behavior', function () {
|
||||
this.timeout(120000)
|
||||
this.timeout(120000);
|
||||
|
||||
let identity = ''
|
||||
let identity = '';
|
||||
|
||||
beforeEach(function () {
|
||||
const result = cp.spawnSync(path.resolve(__dirname, '../script/codesign/get-trusted-identity.sh'))
|
||||
const result = cp.spawnSync(path.resolve(__dirname, '../script/codesign/get-trusted-identity.sh'));
|
||||
if (result.status !== 0 || result.stdout.toString().trim().length === 0) {
|
||||
// Per https://circleci.com/docs/2.0/env-vars:
|
||||
// CIRCLE_PR_NUMBER is only present on forked PRs
|
||||
if (process.env.CI && !process.env.CIRCLE_PR_NUMBER) {
|
||||
throw new Error('No valid signing identity available to run autoUpdater specs')
|
||||
throw new Error('No valid signing identity available to run autoUpdater specs');
|
||||
}
|
||||
this.skip()
|
||||
this.skip();
|
||||
} else {
|
||||
identity = result.stdout.toString().trim()
|
||||
identity = result.stdout.toString().trim();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it('should have a valid code signing identity', () => {
|
||||
expect(identity).to.be.a('string').with.lengthOf.at.least(1)
|
||||
})
|
||||
expect(identity).to.be.a('string').with.lengthOf.at.least(1);
|
||||
});
|
||||
|
||||
const copyApp = async (newDir: string, fixture = 'initial') => {
|
||||
const appBundlePath = path.resolve(process.execPath, '../../..')
|
||||
const newPath = path.resolve(newDir, 'Electron.app')
|
||||
cp.spawnSync('cp', ['-R', appBundlePath, path.dirname(newPath)])
|
||||
const appDir = path.resolve(newPath, 'Contents/Resources/app')
|
||||
await fs.mkdirp(appDir)
|
||||
await fs.copy(path.resolve(fixturesPath, 'auto-update', fixture), appDir)
|
||||
const plistPath = path.resolve(newPath, 'Contents', 'Info.plist')
|
||||
const appBundlePath = path.resolve(process.execPath, '../../..');
|
||||
const newPath = path.resolve(newDir, 'Electron.app');
|
||||
cp.spawnSync('cp', ['-R', appBundlePath, path.dirname(newPath)]);
|
||||
const appDir = path.resolve(newPath, 'Contents/Resources/app');
|
||||
await fs.mkdirp(appDir);
|
||||
await fs.copy(path.resolve(fixturesPath, 'auto-update', fixture), appDir);
|
||||
const plistPath = path.resolve(newPath, 'Contents', 'Info.plist');
|
||||
await fs.writeFile(
|
||||
plistPath,
|
||||
(await fs.readFile(plistPath, 'utf8')).replace('<key>BuildMachineOSBuild</key>', `<key>NSAppTransportSecurity</key>
|
||||
|
@ -62,202 +62,202 @@ describeFn('autoUpdater behavior', function () {
|
|||
</dict>
|
||||
</dict>
|
||||
</dict><key>BuildMachineOSBuild</key>`)
|
||||
)
|
||||
return newPath
|
||||
}
|
||||
);
|
||||
return newPath;
|
||||
};
|
||||
|
||||
const spawn = (cmd: string, args: string[], opts: any = {}) => {
|
||||
let out = ''
|
||||
const child = cp.spawn(cmd, args, opts)
|
||||
let out = '';
|
||||
const child = cp.spawn(cmd, args, opts);
|
||||
child.stdout.on('data', (chunk: Buffer) => {
|
||||
out += chunk.toString()
|
||||
})
|
||||
out += chunk.toString();
|
||||
});
|
||||
child.stderr.on('data', (chunk: Buffer) => {
|
||||
out += chunk.toString()
|
||||
})
|
||||
out += chunk.toString();
|
||||
});
|
||||
return new Promise<{ code: number, out: string }>((resolve) => {
|
||||
child.on('exit', (code, signal) => {
|
||||
expect(signal).to.equal(null)
|
||||
expect(signal).to.equal(null);
|
||||
resolve({
|
||||
code: code!,
|
||||
out
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const signApp = (appPath: string) => {
|
||||
return spawn('codesign', ['-s', identity, '--deep', '--force', appPath])
|
||||
}
|
||||
return spawn('codesign', ['-s', identity, '--deep', '--force', appPath]);
|
||||
};
|
||||
|
||||
const launchApp = (appPath: string, args: string[] = []) => {
|
||||
return spawn(path.resolve(appPath, 'Contents/MacOS/Electron'), args)
|
||||
}
|
||||
return spawn(path.resolve(appPath, 'Contents/MacOS/Electron'), args);
|
||||
};
|
||||
|
||||
const withTempDirectory = async (fn: (dir: string) => Promise<void>) => {
|
||||
const dir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-update-spec-'))
|
||||
const dir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-update-spec-'));
|
||||
try {
|
||||
await fn(dir)
|
||||
await fn(dir);
|
||||
} finally {
|
||||
cp.spawnSync('rm', ['-r', dir])
|
||||
cp.spawnSync('rm', ['-r', dir]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const logOnError = (what: any, fn: () => void) => {
|
||||
try {
|
||||
fn()
|
||||
fn();
|
||||
} catch (err) {
|
||||
console.error(what)
|
||||
throw err
|
||||
console.error(what);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
it('should fail to set the feed URL when the app is not signed', async () => {
|
||||
await withTempDirectory(async (dir) => {
|
||||
const appPath = await copyApp(dir)
|
||||
const launchResult = await launchApp(appPath, ['http://myupdate'])
|
||||
expect(launchResult.code).to.equal(1)
|
||||
expect(launchResult.out).to.include('Could not get code signature for running application')
|
||||
})
|
||||
})
|
||||
const appPath = await copyApp(dir);
|
||||
const launchResult = await launchApp(appPath, ['http://myupdate']);
|
||||
expect(launchResult.code).to.equal(1);
|
||||
expect(launchResult.out).to.include('Could not get code signature for running application');
|
||||
});
|
||||
});
|
||||
|
||||
it('should cleanly set the feed URL when the app is signed', async () => {
|
||||
await withTempDirectory(async (dir) => {
|
||||
const appPath = await copyApp(dir)
|
||||
await signApp(appPath)
|
||||
const launchResult = await launchApp(appPath, ['http://myupdate'])
|
||||
expect(launchResult.code).to.equal(0)
|
||||
expect(launchResult.out).to.include('Feed URL Set: http://myupdate')
|
||||
})
|
||||
})
|
||||
const appPath = await copyApp(dir);
|
||||
await signApp(appPath);
|
||||
const launchResult = await launchApp(appPath, ['http://myupdate']);
|
||||
expect(launchResult.code).to.equal(0);
|
||||
expect(launchResult.out).to.include('Feed URL Set: http://myupdate');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with update server', () => {
|
||||
let port = 0
|
||||
let server: express.Application = null as any
|
||||
let httpServer: http.Server = null as any
|
||||
let requests: express.Request[] = []
|
||||
let port = 0;
|
||||
let server: express.Application = null as any;
|
||||
let httpServer: http.Server = null as any;
|
||||
let requests: express.Request[] = [];
|
||||
|
||||
beforeEach((done) => {
|
||||
requests = []
|
||||
server = express()
|
||||
requests = [];
|
||||
server = express();
|
||||
server.use((req, res, next) => {
|
||||
requests.push(req)
|
||||
next()
|
||||
})
|
||||
requests.push(req);
|
||||
next();
|
||||
});
|
||||
httpServer = server.listen(0, '127.0.0.1', () => {
|
||||
port = (httpServer.address() as AddressInfo).port
|
||||
done()
|
||||
})
|
||||
})
|
||||
port = (httpServer.address() as AddressInfo).port;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach((done) => {
|
||||
if (httpServer) {
|
||||
httpServer.close(() => {
|
||||
httpServer = null as any
|
||||
server = null as any
|
||||
done()
|
||||
})
|
||||
httpServer = null as any;
|
||||
server = null as any;
|
||||
done();
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it('should hit the update endpoint when checkForUpdates is called', async () => {
|
||||
await withTempDirectory(async (dir) => {
|
||||
const appPath = await copyApp(dir, 'check')
|
||||
await signApp(appPath)
|
||||
const appPath = await copyApp(dir, 'check');
|
||||
await signApp(appPath);
|
||||
server.get('/update-check', (req, res) => {
|
||||
res.status(204).send()
|
||||
})
|
||||
const launchResult = await launchApp(appPath, [`http://localhost:${port}/update-check`])
|
||||
res.status(204).send();
|
||||
});
|
||||
const launchResult = await launchApp(appPath, [`http://localhost:${port}/update-check`]);
|
||||
logOnError(launchResult, () => {
|
||||
expect(launchResult.code).to.equal(0)
|
||||
expect(requests).to.have.lengthOf(1)
|
||||
expect(requests[0]).to.have.property('url', '/update-check')
|
||||
expect(requests[0].header('user-agent')).to.include('Electron/')
|
||||
})
|
||||
})
|
||||
})
|
||||
expect(launchResult.code).to.equal(0);
|
||||
expect(requests).to.have.lengthOf(1);
|
||||
expect(requests[0]).to.have.property('url', '/update-check');
|
||||
expect(requests[0].header('user-agent')).to.include('Electron/');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should hit the download endpoint when an update is available and error if the file is bad', async () => {
|
||||
await withTempDirectory(async (dir) => {
|
||||
const appPath = await copyApp(dir, 'update')
|
||||
await signApp(appPath)
|
||||
const appPath = await copyApp(dir, 'update');
|
||||
await signApp(appPath);
|
||||
server.get('/update-file', (req, res) => {
|
||||
res.status(500).send('This is not a file')
|
||||
})
|
||||
res.status(500).send('This is not a file');
|
||||
});
|
||||
server.get('/update-check', (req, res) => {
|
||||
res.json({
|
||||
url: `http://localhost:${port}/update-file`,
|
||||
name: 'My Release Name',
|
||||
notes: 'Theses are some release notes innit',
|
||||
pub_date: (new Date()).toString()
|
||||
})
|
||||
})
|
||||
const launchResult = await launchApp(appPath, [`http://localhost:${port}/update-check`])
|
||||
});
|
||||
});
|
||||
const launchResult = await launchApp(appPath, [`http://localhost:${port}/update-check`]);
|
||||
logOnError(launchResult, () => {
|
||||
expect(launchResult).to.have.property('code', 1)
|
||||
expect(launchResult.out).to.include('Update download failed. The server sent an invalid response.')
|
||||
expect(requests).to.have.lengthOf(2)
|
||||
expect(requests[0]).to.have.property('url', '/update-check')
|
||||
expect(requests[1]).to.have.property('url', '/update-file')
|
||||
expect(requests[0].header('user-agent')).to.include('Electron/')
|
||||
expect(requests[1].header('user-agent')).to.include('Electron/')
|
||||
})
|
||||
})
|
||||
})
|
||||
expect(launchResult).to.have.property('code', 1);
|
||||
expect(launchResult.out).to.include('Update download failed. The server sent an invalid response.');
|
||||
expect(requests).to.have.lengthOf(2);
|
||||
expect(requests[0]).to.have.property('url', '/update-check');
|
||||
expect(requests[1]).to.have.property('url', '/update-file');
|
||||
expect(requests[0].header('user-agent')).to.include('Electron/');
|
||||
expect(requests[1].header('user-agent')).to.include('Electron/');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should hit the download endpoint when an update is available and update successfully when the zip is provided', async () => {
|
||||
await withTempDirectory(async (dir) => {
|
||||
const appPath = await copyApp(dir, 'update')
|
||||
await signApp(appPath)
|
||||
const appPath = await copyApp(dir, 'update');
|
||||
await signApp(appPath);
|
||||
|
||||
// Prepare update
|
||||
await withTempDirectory(async (dir2) => {
|
||||
const secondAppPath = await copyApp(dir2, 'update')
|
||||
const appPJPath = path.resolve(secondAppPath, 'Contents', 'Resources', 'app', 'package.json')
|
||||
const secondAppPath = await copyApp(dir2, 'update');
|
||||
const appPJPath = path.resolve(secondAppPath, 'Contents', 'Resources', 'app', 'package.json');
|
||||
await fs.writeFile(
|
||||
appPJPath,
|
||||
(await fs.readFile(appPJPath, 'utf8')).replace('1.0.0', '2.0.0')
|
||||
)
|
||||
await signApp(secondAppPath)
|
||||
const updateZipPath = path.resolve(dir2, 'update.zip')
|
||||
);
|
||||
await signApp(secondAppPath);
|
||||
const updateZipPath = path.resolve(dir2, 'update.zip');
|
||||
await spawn('zip', ['-r', '--symlinks', updateZipPath, './'], {
|
||||
cwd: dir2
|
||||
})
|
||||
});
|
||||
|
||||
server.get('/update-file', (req, res) => {
|
||||
res.download(updateZipPath)
|
||||
})
|
||||
res.download(updateZipPath);
|
||||
});
|
||||
server.get('/update-check', (req, res) => {
|
||||
res.json({
|
||||
url: `http://localhost:${port}/update-file`,
|
||||
name: 'My Release Name',
|
||||
notes: 'Theses are some release notes innit',
|
||||
pub_date: (new Date()).toString()
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
const relaunchPromise = new Promise((resolve) => {
|
||||
server.get('/update-check/updated/:version', (req, res) => {
|
||||
res.status(204).send()
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
const launchResult = await launchApp(appPath, [`http://localhost:${port}/update-check`])
|
||||
res.status(204).send();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
const launchResult = await launchApp(appPath, [`http://localhost:${port}/update-check`]);
|
||||
logOnError(launchResult, () => {
|
||||
expect(launchResult).to.have.property('code', 0)
|
||||
expect(launchResult.out).to.include('Update Downloaded')
|
||||
expect(requests).to.have.lengthOf(2)
|
||||
expect(requests[0]).to.have.property('url', '/update-check')
|
||||
expect(requests[1]).to.have.property('url', '/update-file')
|
||||
expect(requests[0].header('user-agent')).to.include('Electron/')
|
||||
expect(requests[1].header('user-agent')).to.include('Electron/')
|
||||
})
|
||||
expect(launchResult).to.have.property('code', 0);
|
||||
expect(launchResult.out).to.include('Update Downloaded');
|
||||
expect(requests).to.have.lengthOf(2);
|
||||
expect(requests[0]).to.have.property('url', '/update-check');
|
||||
expect(requests[1]).to.have.property('url', '/update-file');
|
||||
expect(requests[0].header('user-agent')).to.include('Electron/');
|
||||
expect(requests[1].header('user-agent')).to.include('Electron/');
|
||||
});
|
||||
|
||||
await relaunchPromise
|
||||
expect(requests).to.have.lengthOf(3)
|
||||
expect(requests[2]).to.have.property('url', '/update-check/updated/2.0.0')
|
||||
expect(requests[2].header('user-agent')).to.include('Electron/')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
await relaunchPromise;
|
||||
expect(requests).to.have.lengthOf(3);
|
||||
expect(requests[2]).to.have.property('url', '/update-check/updated/2.0.0');
|
||||
expect(requests[2].header('user-agent')).to.include('Electron/');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue