820 lines
31 KiB
JavaScript
820 lines
31 KiB
JavaScript
import { setTimeout, setImmediate } from 'timers/promises'
|
|
import { Eltro as t, assert, stub } from 'eltro'
|
|
import fs from 'fs/promises'
|
|
import Application from '../core/application.mjs'
|
|
import Util from '../core/util.mjs'
|
|
import StaticProvider from '../core/providers/static.mjs'
|
|
import { createFakeContext } from './helpers.mjs'
|
|
|
|
const util = new Util(import.meta.url)
|
|
|
|
const logger = {
|
|
info: stub(),
|
|
warn: stub(),
|
|
error: stub(),
|
|
}
|
|
function createProvider() {
|
|
return {
|
|
getLatestVersion: stub(),
|
|
downloadVersion: stub(),
|
|
}
|
|
}
|
|
|
|
t.describe('constructor()', function() {
|
|
let ctx
|
|
|
|
t.beforeEach(function() {
|
|
return createFakeContext()
|
|
.then(function(res) { ctx = res })
|
|
})
|
|
|
|
t.test('should auto-create application', function() {
|
|
assert.notOk(ctx.db.data.core.test)
|
|
|
|
new Application(ctx, {}, 'test')
|
|
|
|
assert.ok(ctx.db.data.core.test)
|
|
assert.ok(ctx.db.data.core.test.versions)
|
|
assert.strictEqual(ctx.db.data.core.test.active, '')
|
|
assert.strictEqual(ctx.db.data.core.test.latestInstalled, '')
|
|
assert.strictEqual(ctx.db.data.core.test.latestVersion, '')
|
|
})
|
|
|
|
t.test('should keep config and other of itself', function() {
|
|
const assertTest = { a: 1 }
|
|
const assertName = 'test'
|
|
ctx.db.config = {
|
|
test: assertTest,
|
|
app: { b: 2},
|
|
manage: { c: 3 },
|
|
}
|
|
|
|
let app = new Application(ctx, {}, assertName)
|
|
assert.notStrictEqual(app.config, assertTest)
|
|
assert.strictEqual(app.config.a, assertTest.a)
|
|
assert.strictEqual(app.config.updateEvery, 180)
|
|
assert.strictEqual(app.config.startWaitUntilFail, 60 * 1000)
|
|
assert.strictEqual(app.config.heartbeatTimeout, 3 * 1000)
|
|
assert.strictEqual(app.config.heartbeatAttempts, 5)
|
|
assert.strictEqual(app.config.heartbeatAttemptsWait, 2 * 1000)
|
|
assert.strictEqual(app.config.heartbeatPath, '/')
|
|
assert.strictEqual(app.ctx.db, ctx.db)
|
|
assert.strictEqual(app.ctx.app, app)
|
|
assert.strictEqual(app.ctx.util, ctx.util)
|
|
assert.strictEqual(app.name, assertName)
|
|
assert.strictEqual(app.fresh, true)
|
|
assert.strictEqual(app.running, false)
|
|
assert.ok(app.http)
|
|
assert.ok(app.http.sockets)
|
|
assert.strictEqual(typeof(app.http.createServer), 'function')
|
|
assert.strictEqual(typeof(app.http.closeServer), 'function')
|
|
})
|
|
|
|
t.test('should create http instance correctly', function() {
|
|
ctx.db.config = {
|
|
testapp: { a: 1, https: true },
|
|
app: { b: 2},
|
|
manage: { c: 3 },
|
|
}
|
|
|
|
let app = new Application(ctx, {}, 'testapp')
|
|
assert.ok(app.http)
|
|
assert.ok(app.http.ishttps)
|
|
})
|
|
|
|
t.test('should keep provider', function() {
|
|
const assertProvider = { a: 1 }
|
|
let app = new Application(ctx, assertProvider, 'test')
|
|
assert.strictEqual(app.provider, assertProvider)
|
|
})
|
|
})
|
|
|
|
t.timeout(250).describe('#startAutoupdater()', function() {
|
|
let ctx
|
|
|
|
t.beforeEach(function() {
|
|
return createFakeContext()
|
|
.then(function(res) { ctx = res })
|
|
})
|
|
|
|
t.test('should do nothing if provider is static', async function() {
|
|
const stubInterval = stub()
|
|
stubInterval.throws(new Error('should not be seen'))
|
|
let provider = new StaticProvider()
|
|
let app = new Application(ctx, provider, 'teststatic', { setInterval: stubInterval })
|
|
|
|
app.startAutoupdater()
|
|
})
|
|
|
|
t.test('should call setInterval correctly', function() {
|
|
const assertTimeMinutes = 1440
|
|
const stubInterval = stub()
|
|
const stubUnref = stub()
|
|
stubInterval.returns({ unref: stubUnref })
|
|
|
|
ctx.db.config.test = {
|
|
updateEvery: assertTimeMinutes,
|
|
}
|
|
|
|
let app = new Application(ctx, {}, 'test', { setInterval: stubInterval })
|
|
|
|
assert.strictEqual(stubInterval.called, false)
|
|
assert.strictEqual(stubUnref.called, false)
|
|
|
|
app.startAutoupdater()
|
|
|
|
assert.strictEqual(stubInterval.called, true)
|
|
assert.strictEqual(stubUnref.called, true)
|
|
assert.strictEqual(typeof(stubInterval.firstCall[0]), 'function')
|
|
assert.strictEqual(stubInterval.firstCall[1], assertTimeMinutes * 60 * 1000)
|
|
})
|
|
|
|
t.test('should support default value if updateEvery is not defined', function() {
|
|
const stubInterval = stub()
|
|
stubInterval.returns({ unref: function() {} })
|
|
|
|
let app = new Application(ctx, {}, 'test', { setInterval: stubInterval })
|
|
|
|
assert.strictEqual(stubInterval.called, false)
|
|
|
|
app.startAutoupdater()
|
|
|
|
assert.strictEqual(stubInterval.called, true)
|
|
assert.strictEqual(typeof(stubInterval.firstCall[0]), 'function')
|
|
assert.strictEqual(stubInterval.firstCall[1], 3 * 60 * 60 * 1000)
|
|
})
|
|
|
|
t.test('should call update as promise correctly', async function() {
|
|
const stubUpdate = stub()
|
|
const stubInterval = stub()
|
|
stubInterval.returns({ unref: function() {} })
|
|
|
|
stubUpdate.returnWith(function() {
|
|
return Promise.resolve()
|
|
})
|
|
|
|
let app = new Application(ctx, {}, 'test', { setInterval: stubInterval })
|
|
app.update = stubUpdate
|
|
app.startAutoupdater()
|
|
|
|
assert.strictEqual(typeof(stubInterval.firstCall[0]), 'function')
|
|
assert.notStrictEqual(stubInterval.firstCall, stubUpdate)
|
|
|
|
stubInterval.firstCall[0]()
|
|
|
|
while (ctx.db.data.core.test.updater === '') {
|
|
await setTimeout(10)
|
|
}
|
|
|
|
assert.match(ctx.db.data.core.test.updater, /auto/i)
|
|
assert.match(ctx.db.data.core.test.updater, /update/i)
|
|
})
|
|
|
|
t.test('should add any errors to last in db update check on errors when updating', async function() {
|
|
const stubInterval = stub()
|
|
const assertErrorMessage = 'Ai Do'
|
|
stubInterval.returns({ unref: function() {} })
|
|
|
|
let app = new Application(ctx, {}, 'test', { setInterval: stubInterval })
|
|
app.update = function() {
|
|
return Promise.reject(new Error(assertErrorMessage))
|
|
}
|
|
app.startAutoupdater()
|
|
|
|
assert.strictEqual(ctx.db.data.core.test.updater, '')
|
|
|
|
stubInterval.firstCall[0]()
|
|
|
|
while (ctx.db.data.core.test.updater === '') {
|
|
await setTimeout(10)
|
|
}
|
|
|
|
assert.match(ctx.db.data.core.test.updater, /auto/i)
|
|
assert.match(ctx.db.data.core.test.updater, /update/i)
|
|
assert.match(ctx.db.data.core.test.updater, new RegExp(assertErrorMessage))
|
|
})
|
|
})
|
|
|
|
t.timeout(250).describe('#closeServer()', function() {
|
|
let app
|
|
let stubCloseServer
|
|
|
|
t.beforeEach(function() {
|
|
return createFakeContext()
|
|
.then(function(res) {
|
|
let provider = createProvider()
|
|
app = new Application(res, provider, 'testapp')
|
|
app.http.closeServer = stubCloseServer = stub().resolves()
|
|
})
|
|
})
|
|
|
|
t.test('should call closeServer correctly', async function() {
|
|
const assertError = new Error('Moonlight Fiesta')
|
|
stubCloseServer.rejects(assertError)
|
|
|
|
let err = await assert.isRejected(app.closeServer())
|
|
|
|
assert.strictEqual(err, assertError)
|
|
})
|
|
|
|
t.test('otherwise should work fine', async function() {
|
|
await app.closeServer()
|
|
})
|
|
})
|
|
|
|
t.timeout(250).describe('#update()', function() {
|
|
let ctx
|
|
let app
|
|
let provider
|
|
let stubExtract
|
|
let stubRunCommand
|
|
let stubWrite
|
|
let stubFsMkdir
|
|
let stubFsRm
|
|
let stubFsStat
|
|
|
|
t.beforeEach(function() {
|
|
return createFakeContext()
|
|
.then(function(res) {
|
|
ctx = res
|
|
ctx.util.extractFile = stubExtract = stub().resolves()
|
|
ctx.util.runCommand = stubRunCommand = stub().resolves()
|
|
ctx.db.write = stubWrite = stub().resolves()
|
|
|
|
provider = createProvider()
|
|
app = new Application(ctx, provider, 'testapp', {
|
|
fs: {
|
|
mkdir: stubFsMkdir = stub(),
|
|
rm: stubFsRm = stub(),
|
|
stat: stubFsStat = stub(),
|
|
},
|
|
})
|
|
stubFsMkdir.resolves()
|
|
stubFsRm.resolves()
|
|
stubFsStat.resolves({})
|
|
provider.downloadVersion.resolves()
|
|
provider.getLatestVersion.resolves({ version: '123456789', link: 'httplinkhere', filename: 'test.7z' })
|
|
})
|
|
})
|
|
|
|
t.afterEach(function() {
|
|
return fs.rm('./test/testapp/123456789', { force: true, recursive: true })
|
|
})
|
|
|
|
t.test('should do nothing if provider is static', async function() {
|
|
provider = new StaticProvider()
|
|
app = new Application(ctx, provider, 'teststatic')
|
|
|
|
stubWrite.reset()
|
|
|
|
await app.update()
|
|
|
|
assert.match(ctx.db.data.core.teststatic.updater, /static/i)
|
|
assert.match(ctx.db.data.core.teststatic.updater, /nothing/i)
|
|
let old = ctx.db.data.core.teststatic.updater
|
|
assert.ok(stubWrite.called)
|
|
assert.strictEqual(stubWrite.callCount, 1)
|
|
|
|
await app.update()
|
|
assert.strictEqual(ctx.db.data.core.teststatic.updater, old)
|
|
assert.strictEqual(stubWrite.callCount, 1)
|
|
|
|
ctx.db.data.core.teststatic.updater = 'asdf'
|
|
|
|
await app.update()
|
|
assert.strictEqual(ctx.db.data.core.teststatic.updater, old)
|
|
assert.strictEqual(stubWrite.callCount, 2)
|
|
|
|
await app.update()
|
|
assert.strictEqual(ctx.db.data.core.teststatic.updater, old)
|
|
assert.strictEqual(stubWrite.callCount, 2)
|
|
})
|
|
|
|
t.test('multiple calls should be safe', async function() {
|
|
ctx.db.data.core.testapp.updater = ''
|
|
|
|
provider.getLatestVersion.returnWith(function() {
|
|
return new Promise(function() {})
|
|
})
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
|
|
app.update()
|
|
await setImmediate()
|
|
|
|
assert.strictEqual(app.updating, true)
|
|
assert.strictEqual(provider.getLatestVersion.callCount, 1)
|
|
|
|
app.update()
|
|
await setImmediate()
|
|
|
|
assert.strictEqual(provider.getLatestVersion.callCount, 1)
|
|
})
|
|
|
|
t.test('should check for latest version', async function() {
|
|
const assertError = new Error('Ore wa Subete wo Shihaisuru')
|
|
provider.getLatestVersion.rejects(assertError)
|
|
ctx.db.data.core.testapp.updater = ''
|
|
|
|
let err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
|
|
assert.ok(stubWrite.called)
|
|
assert.ok(stubWrite.callCount >= 1)
|
|
assert.match(ctx.db.data.core.testapp.updater, /check/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /version/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(new Date().toISOString().split('T')[0]))
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertError.message))
|
|
})
|
|
|
|
t.test('should call provider download latest correctly if new 7zip version', async function() {
|
|
const assertError = new Error('Without a fight')
|
|
const assertLink = 'All of you'
|
|
const assertVersion = { version: '123456789', link: assertLink, filename: 'test.7z' }
|
|
const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z')
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 0)
|
|
|
|
provider.getLatestVersion.resolves(assertVersion)
|
|
provider.downloadVersion.rejects(assertError)
|
|
ctx.db.data.core.testapp.updater = ''
|
|
|
|
let err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
assert.match(ctx.db.data.core.testapp.updater, /found/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertVersion.version))
|
|
assert.match(ctx.db.data.core.testapp.updater, /downloading/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertLink))
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertTarget.replace(/\\/g, '\\\\')))
|
|
assert.strictEqual(provider.downloadVersion.firstCall[0], assertVersion)
|
|
assert.strictEqual(provider.downloadVersion.firstCall[1], assertTarget)
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertError.message))
|
|
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], assertVersion)
|
|
assert.ok(assertVersion.log)
|
|
assert.match(assertVersion.log, /\. \n/)
|
|
assert.match(assertVersion.log, new RegExp(assertError.message))
|
|
assert.ok(assertVersion.log.endsWith('\n'))
|
|
assert.strictEqual(assertVersion.failtodownload, 1)
|
|
|
|
assert.ok(stubWrite.called)
|
|
assert.ok(stubWrite.callCount >= 2)
|
|
assert.ok(stubFsMkdir.called)
|
|
assert.match(stubFsMkdir.firstCall[0], /123456789/)
|
|
assert.ok(stubFsMkdir.firstCall[1]?.recursive)
|
|
|
|
// Test if subsequent calls increment counter
|
|
|
|
err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], assertVersion)
|
|
assert.strictEqual(assertVersion.failtodownload, 2)
|
|
})
|
|
|
|
t.test('should call provider download latest correctly if new 7zip version', async function() {
|
|
const assertError = new Error('Without a fight')
|
|
const assertLink = 'All of you'
|
|
const assertVersion = { version: '123456789', link: assertLink, filename: 'test.7z' }
|
|
const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z')
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 0)
|
|
|
|
provider.getLatestVersion.resolves(assertVersion)
|
|
provider.downloadVersion.rejects(assertError)
|
|
ctx.db.data.core.testapp.updater = ''
|
|
|
|
let err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
assert.match(ctx.db.data.core.testapp.updater, /found/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertVersion.version))
|
|
assert.match(ctx.db.data.core.testapp.updater, /downloading/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertLink))
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertTarget.replace(/\\/g, '\\\\')))
|
|
assert.strictEqual(provider.downloadVersion.firstCall[0], assertVersion)
|
|
assert.strictEqual(provider.downloadVersion.firstCall[1], assertTarget)
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertError.message))
|
|
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], assertVersion)
|
|
assert.ok(assertVersion.log)
|
|
assert.match(assertVersion.log, /\. \n/)
|
|
assert.match(assertVersion.log, new RegExp(assertError.message))
|
|
assert.ok(assertVersion.log.endsWith('\n'))
|
|
assert.strictEqual(assertVersion.failtodownload, 1)
|
|
|
|
assert.ok(stubFsRm.called)
|
|
assert.match(stubFsRm.firstCall[0], /123456789/)
|
|
assert.ok(stubFsRm.firstCall[1]?.recursive)
|
|
assert.ok(stubFsRm.firstCall[1]?.force)
|
|
|
|
// Test if subsequent calls increment counter
|
|
|
|
err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], assertVersion)
|
|
assert.strictEqual(assertVersion.failtodownload, 2)
|
|
})
|
|
|
|
t.test('should call extract on util correctly', async function() {
|
|
const assertExtractText = 'Reverdations of Success'
|
|
const assertError = new Error('Dai Gekisen')
|
|
const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z')
|
|
const assertFolder = util.getPathFromRoot('./testapp/123456789')
|
|
|
|
stubExtract.returnWith(function(target, stream) {
|
|
stream(assertExtractText)
|
|
return Promise.reject(assertError)
|
|
})
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 0)
|
|
|
|
let err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(stubExtract.firstCall[0], assertTarget)
|
|
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp('extracting[^.]+file\.7z', 'i'))
|
|
assert.match(ctx.db.data.core.testapp.updater, new RegExp(assertError.message))
|
|
|
|
assert.ok(stubFsRm.called)
|
|
assert.strictEqual(stubFsRm.firstCall[0], assertFolder)
|
|
assert.ok(stubFsRm.firstCall[1]?.recursive)
|
|
assert.ok(stubFsRm.firstCall[1]?.force)
|
|
|
|
assert.ok(stubWrite.called)
|
|
assert.ok(stubWrite.callCount >= 3)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
let version = ctx.db.data.core.testapp.versions[0]
|
|
assert.ok(version.log)
|
|
assert.match(version.log, /\. \n/)
|
|
assert.match(version.log, new RegExp('extracting[^.]+file\.7z', 'i'))
|
|
assert.match(version.log, new RegExp(assertError.message))
|
|
assert.match(version.log, new RegExp(assertExtractText))
|
|
assert.ok(version.log.endsWith('\n'))
|
|
assert.strictEqual(version.failtodownload, 1)
|
|
|
|
// Test if subsequent calls increment counter
|
|
|
|
err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], version)
|
|
assert.strictEqual(version.failtodownload, 2)
|
|
})
|
|
|
|
t.test('should call fs remove the archieve file', async function() {
|
|
const assertError = new Error('Tiny Kizuna')
|
|
const assertTarget = util.getPathFromRoot('./testapp/123456789/file.7z')
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 0)
|
|
stubFsRm.rejects(assertError)
|
|
|
|
await app.update()
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.ok(stubFsRm.called)
|
|
assert.strictEqual(stubFsRm.callCount, 1)
|
|
assert.strictEqual(stubFsRm.firstCall[0], assertTarget)
|
|
assert.ok(stubFsRm.firstCall[1]?.force)
|
|
})
|
|
|
|
t.test('should not call npm install if stat fails to find index.mjs', async function() {
|
|
const assertError = new Error('File not found')
|
|
const assertTarget = util.getPathFromRoot('./testapp/123456789/index.mjs')
|
|
stubRunCommand.rejects(new Error('should not be seen'))
|
|
stubFsStat.rejects(assertError)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 0)
|
|
|
|
let err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.ok(stubExtract.called)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(stubFsStat.firstCall[0], assertTarget)
|
|
assert.match(ctx.db.data.core.testapp.updater, /index\.mjs/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /missing/i)
|
|
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
let version = ctx.db.data.core.testapp.versions[0]
|
|
assert.ok(version.log)
|
|
assert.match(version.log, /index\.mjs/i)
|
|
assert.match(version.log, /missing/i)
|
|
assert.ok(version.log.endsWith('\n'))
|
|
assert.strictEqual(version.failtodownload, 1)
|
|
|
|
// Test if subsequent calls increment counter
|
|
|
|
err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], version)
|
|
assert.strictEqual(version.failtodownload, 2)
|
|
})
|
|
|
|
t.test('should not call npm install if package.json is missing but shuld pass', async function() {
|
|
const assertError = new Error('File not found')
|
|
const assertTarget = util.getPathFromRoot('./testapp/123456789/package.json')
|
|
stubRunCommand.rejects(new Error('should not be seen'))
|
|
stubFsStat.returnWith(function(path) {
|
|
if (path.endsWith('package.json')) {
|
|
return Promise.reject(assertError)
|
|
}
|
|
return Promise.resolve({})
|
|
})
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 0)
|
|
|
|
await app.update()
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
|
|
assert.strictEqual(stubFsStat.callCount, 2)
|
|
assert.strictEqual(stubFsStat.secondCall[0], assertTarget)
|
|
assert.ok(stubExtract.called)
|
|
assert.notOk(stubRunCommand.called)
|
|
assert.match(ctx.db.data.core.testapp.updater, /package\.json/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /contain/i)
|
|
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
let version = ctx.db.data.core.testapp.versions[0]
|
|
assert.ok(version.log)
|
|
assert.match(version.log, /package\.json/i)
|
|
assert.match(version.log, /contain/i)
|
|
assert.ok(version.log.endsWith('\n'))
|
|
assert.ok(ctx.db.data.core.testapp.latestInstalled)
|
|
assert.match(version.log, /finished/i)
|
|
assert.match(version.log, /updating/i)
|
|
|
|
// Test if subsequent calls do nothing
|
|
|
|
provider.downloadVersion.reset()
|
|
|
|
await app.update()
|
|
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.notOk(provider.downloadVersion.called)
|
|
assert.match(ctx.db.data.core.testapp.updater, /already/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /nothing/i)
|
|
})
|
|
|
|
t.test('should otherwise call npm install correctly', async function() {
|
|
const assertExtractText = 'Egao no Hikair ni Tsutsumarete'
|
|
const assertNpmText = 'Dadadadash'
|
|
const assertVersion = { version: '123456789', link: 'somelinkhere', filename: 'test.7z' }
|
|
const assertError = new Error('Nagisa')
|
|
const assertTarget = util.getPathFromRoot('./testapp/123456789')
|
|
const assertTargetCheck = util.getPathFromRoot('./testapp/123456789/')
|
|
provider.getLatestVersion.resolves(assertVersion)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 0)
|
|
|
|
stubExtract.returnWith(function(target, stream) {
|
|
stream(assertExtractText)
|
|
return Promise.resolve()
|
|
})
|
|
stubRunCommand.returnWith(function(command, options, folder, stream) {
|
|
stream(assertNpmText)
|
|
return Promise.reject(assertError)
|
|
})
|
|
|
|
let err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(stubRunCommand.firstCall[0], 'npm.cmd')
|
|
assert.ok(stubRunCommand.firstCall[1])
|
|
assert.strictEqual(stubRunCommand.firstCall[1][0], 'install')
|
|
assert.ok(stubRunCommand.firstCall[1].includes('--production'), 'should have --production')
|
|
assert.ok(stubRunCommand.firstCall[1].includes('--no-optional'), 'should have --no-optional')
|
|
assert.ok(stubRunCommand.firstCall[1].includes('--no-package-lock'), 'should have --no-package-lock')
|
|
assert.ok(stubRunCommand.firstCall[1].includes('--no-audit'), 'should have --no-audit')
|
|
assert.strictEqual(stubRunCommand.firstCall[2], assertTarget)
|
|
|
|
for (let i = 0; i < stubFsRm.callCount; i++) {
|
|
assert.notStrictEqual(stubFsRm.getCall(i)[0], assertTarget)
|
|
assert.notStrictEqual(stubFsRm.getCall(i)[0], assertTargetCheck)
|
|
}
|
|
|
|
assert.ok(stubWrite.called)
|
|
assert.ok(stubWrite.callCount >= 4)
|
|
assert.match(ctx.db.data.core.testapp.updater, /npm/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /install/i)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], assertVersion)
|
|
assert.ok(assertVersion.log)
|
|
assert.match(assertVersion.log, /\. \n/)
|
|
assert.match(assertVersion.log, new RegExp(assertExtractText))
|
|
assert.match(assertVersion.log, new RegExp(assertNpmText))
|
|
assert.match(assertVersion.log, new RegExp(assertError.message))
|
|
assert.match(assertVersion.log, /npm/i)
|
|
assert.match(assertVersion.log, /install/i)
|
|
assert.ok(assertVersion.log.endsWith('\n'))
|
|
assert.strictEqual(assertVersion.failtoinstall, 1)
|
|
|
|
// Test if subsequent calls increment counter
|
|
|
|
err = await assert.isRejected(app.update())
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], assertVersion)
|
|
assert.strictEqual(assertVersion.failtoinstall, 2)
|
|
})
|
|
|
|
t.test('should update latest installed correctly', async function() {
|
|
const assertVersion = { version: '123456789', link: 'httplinkhere', filename: 'test.7z' }
|
|
provider.getLatestVersion.resolves(assertVersion)
|
|
assert.notStrictEqual(ctx.db.data.core.testapp.latestInstalled, assertVersion.version)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 0)
|
|
|
|
await app.update()
|
|
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(ctx.db.data.core.testapp.latestInstalled, assertVersion.version)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], assertVersion)
|
|
assert.ok(assertVersion.log)
|
|
assert.ok(stubWrite.callCount >= 4)
|
|
assert.strictEqual(assertVersion.installed, true)
|
|
assert.strictEqual(assertVersion.stable, 0)
|
|
assert.match(assertVersion.log, /found/i)
|
|
assert.match(assertVersion.log, new RegExp(assertVersion.version))
|
|
assert.match(assertVersion.log, /downloading/i)
|
|
assert.match(assertVersion.log, new RegExp('extracting[^.]+file\.7z', 'i'))
|
|
assert.match(assertVersion.log, /finished/i)
|
|
assert.match(assertVersion.log, /updating/i)
|
|
})
|
|
|
|
t.test('should update existing version if found', async function() {
|
|
const assertNewLink = 'THE last pain'
|
|
const assertNewFilename = 'The place of hope.7z'
|
|
const assertStable = 100
|
|
const oldLog = 'The Smell of Sea\n'
|
|
const assertVersion = { version: '123456789', link: 'httplinkhere', filename: 'test.7z', log: oldLog, stable: assertStable }
|
|
|
|
assertVersion.id = assertVersion.version
|
|
ctx.db.upsert(ctx.db.data.core.testapp.versions, assertVersion)
|
|
|
|
provider.getLatestVersion.resolves({ version: assertVersion.version, link: assertNewLink, filename: assertNewFilename })
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
|
|
await app.update()
|
|
|
|
assert.ok(assertVersion.log)
|
|
assert.ok(stubWrite.callCount >= 4)
|
|
assert.strictEqual(app.updating, false)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions.length, 1)
|
|
assert.strictEqual(ctx.db.data.core.testapp.versions[0], assertVersion)
|
|
assert.strictEqual(assertVersion.stable, assertStable)
|
|
assert.ok(assertVersion.log)
|
|
assert.ok(assertVersion.log.startsWith(oldLog))
|
|
assert.strictEqual(assertVersion.installed, true)
|
|
assert.match(assertVersion.log, /found/i)
|
|
assert.match(assertVersion.log, new RegExp(assertVersion.version))
|
|
assert.match(assertVersion.log, /downloading/i)
|
|
assert.match(assertVersion.log, new RegExp('extracting[^.]+file\.7z', 'i'))
|
|
assert.match(assertVersion.log, /finished/i)
|
|
assert.match(assertVersion.log, /updating/i)
|
|
})
|
|
|
|
t.test('should do nothing if latestInstalled matches version', async function() {
|
|
const assertError = new Error('should not be seen')
|
|
const assertVersion = { version: '999.888.777.666', filename: 'test.7z' }
|
|
provider.getLatestVersion.resolves(assertVersion)
|
|
provider.downloadVersion.rejects(assertError)
|
|
ctx.db.data.core.testapp.updater = ''
|
|
ctx.db.data.core.testapp.latestInstalled = assertVersion.version
|
|
|
|
await app.update()
|
|
|
|
assert.ok(stubWrite.callCount >= 1)
|
|
assert.strictEqual(app.updating, false)
|
|
assert.notOk(provider.downloadVersion.called)
|
|
assert.match(ctx.db.data.core.testapp.updater, /already/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /nothing/i)
|
|
})
|
|
|
|
t.test('should do nothing if installed version is found', async function() {
|
|
const assertError = new Error('should not be seen')
|
|
const assertVersion = { version: '999.888.777.666', filename: 'test.7z' }
|
|
provider.getLatestVersion.resolves(assertVersion)
|
|
provider.downloadVersion.rejects(assertError)
|
|
ctx.db.data.core.testapp.updater = ''
|
|
|
|
ctx.db.upsert(ctx.db.data.core.testapp.versions, { id: '111.111.111.111', installed: true })
|
|
ctx.db.upsert(ctx.db.data.core.testapp.versions, { id: '222.222.222.222', installed: true })
|
|
ctx.db.upsert(ctx.db.data.core.testapp.versions, { id: '999.888.777.666', installed: true })
|
|
ctx.db.upsert(ctx.db.data.core.testapp.versions, { id: '333.333.333.333', installed: true })
|
|
|
|
await app.update()
|
|
|
|
assert.ok(stubWrite.callCount >= 1)
|
|
assert.strictEqual(app.updating, false)
|
|
assert.notOk(provider.downloadVersion.called)
|
|
assert.match(ctx.db.data.core.testapp.updater, /already/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /nothing/i)
|
|
})
|
|
|
|
t.test('should do nothing it exists and failtodownload is higher than 3', async function() {
|
|
const assertError = new Error('should not be seen')
|
|
const assertVersion = { version: '999.888.777.666', filename: 'test.7z' }
|
|
provider.getLatestVersion.resolves(assertVersion)
|
|
provider.downloadVersion.rejects(assertError)
|
|
ctx.db.data.core.testapp.updater = ''
|
|
ctx.db.upsert(ctx.db.data.core.testapp.versions, { id: '999.888.777.666', version: '999.888.777.666', link: 'httplinkhere', filename: 'test.7z', failtodownload: 4 })
|
|
|
|
await app.update()
|
|
|
|
assert.ok(stubWrite.callCount >= 1)
|
|
assert.strictEqual(app.updating, false)
|
|
assert.notOk(provider.downloadVersion.called)
|
|
assert.match(ctx.db.data.core.testapp.updater, /many/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /fail/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /skip/i)
|
|
})
|
|
|
|
t.test('should do nothing it exists and failtoinstall is higher than 3', async function() {
|
|
const assertError = new Error('should not be seen')
|
|
const assertVersion = { version: '999.888.777.666', filename: 'test.7z' }
|
|
provider.getLatestVersion.resolves(assertVersion)
|
|
provider.downloadVersion.rejects(assertError)
|
|
ctx.db.data.core.testapp.updater = ''
|
|
ctx.db.upsert(ctx.db.data.core.testapp.versions, { id: '999.888.777.666', version: '999.888.777.666', link: 'httplinkhere', filename: 'test.7z', failtoinstall: 4 })
|
|
|
|
await app.update()
|
|
|
|
assert.ok(stubWrite.callCount >= 1)
|
|
assert.strictEqual(app.updating, false)
|
|
assert.notOk(provider.downloadVersion.called)
|
|
assert.match(ctx.db.data.core.testapp.updater, /many/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /fail/i)
|
|
assert.match(ctx.db.data.core.testapp.updater, /skip/i)
|
|
})
|
|
})
|
|
|
|
t.timeout(250).describe('#registerModule()', function() {
|
|
const assertAppName = 'testappregister'
|
|
let ctx
|
|
let app
|
|
|
|
t.beforeEach(function() {
|
|
return createFakeContext()
|
|
.then(function(res) {
|
|
ctx = res
|
|
let provider = new StaticProvider()
|
|
app = new Application(ctx, provider, assertAppName)
|
|
})
|
|
})
|
|
|
|
t.test('should fail if not an object with start', function() {
|
|
let tests = [
|
|
[1, 'number'],
|
|
[0, 'empty number'],
|
|
['text', 'string'],
|
|
['', 'empty string'],
|
|
[{}, 'empty object'],
|
|
[[], 'array'],
|
|
[{ a: 1 }, 'non-empty object'],
|
|
]
|
|
|
|
tests.forEach(function(check) {
|
|
assert.throws(function() {
|
|
app.registerModule(check[0])
|
|
}, function(err) {
|
|
assert.match(err.message, /registerModule/i)
|
|
assert.match(err.message, /function/i)
|
|
assert.match(err.message, /start/i)
|
|
assert.match(err.message, new RegExp(assertAppName, 'i'))
|
|
return true
|
|
}, `should fail if called with ${check[1]}`)
|
|
})
|
|
})
|
|
|
|
t.test('should otherwise succeed if object has function start', function() {
|
|
const assertFunction = function() {}
|
|
const assertModule = { start: assertFunction }
|
|
|
|
app.registerModule(assertModule)
|
|
|
|
assert.strictEqual(app.module, assertModule)
|
|
|
|
app.registerModule(assertFunction)
|
|
|
|
assert.notStrictEqual(app.module, assertModule)
|
|
assert.deepStrictEqual(app.module, assertModule)
|
|
})
|
|
})
|