service-core/test/application.test.mjs

281 lines
9.2 KiB
JavaScript

import { setTimeout, setImmediate } from 'timers/promises'
import { Eltro as t, assert, stub } from 'eltro'
import fs from 'fs/promises'
import lowdb from '../core/db.mjs'
import Application from '../core/application.mjs'
import Util from '../core/util.mjs'
const util = new Util(import.meta.url)
var logger = {
info: stub(),
warn: stub(),
error: stub(),
}
function createProvider() {
return {
getLatestVersion: stub(),
downloadVersion: stub(),
}
}
t.describe('constructor()', function() {
let db
t.beforeEach(function() {
return lowdb({ test: { } }, logger, null).then(function(res) {
db = res
})
})
t.test('should auto-create application', function() {
assert.notOk(db.data.core.test)
new Application(util, db, {}, 'test')
assert.ok(db.data.core.test)
assert.ok(db.data.core.test.versions)
assert.strictEqual(db.data.core.test.active, null)
assert.strictEqual(db.data.core.test.latestInstalled, null)
assert.strictEqual(db.data.core.test.latestVersion, null)
})
t.test('should keep config and other of itself', function() {
const assertTest = { a: 1 }
const assertName = 'test'
db.config = {
test: assertTest,
app: { b: 2},
manage: { c: 3 },
}
let app = new Application(util, db, {}, assertName)
assert.strictEqual(app.config, assertTest)
assert.strictEqual(app.db, db)
assert.strictEqual(app.util, util)
assert.strictEqual(app.name, assertName)
})
t.test('should keep provider', function() {
const assertProvider = { a: 1 }
let app = new Application(util, db, assertProvider, 'test')
assert.strictEqual(app.provider, assertProvider)
})
})
t.timeout(250).describe('#startAutoupdater()', function() {
let db
t.beforeEach(function() {
return lowdb({ test: { }, testapp: { } }, logger, null).then(function(res) {
db = res
})
})
t.test('should call setInterval correctly', function() {
const assertTimeMinutes = 1440
const stubInterval = stub()
const stubUnref = stub()
stubInterval.returns({ unref: stubUnref })
db.config.test.updateEvery = assertTimeMinutes
let app = new Application(util, db, {}, '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(util, db, {}, '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(util, db, {}, 'test', { setInterval: stubInterval })
app.update = stubUpdate
app.startAutoupdater()
assert.strictEqual(typeof(stubInterval.firstCall[0]), 'function')
assert.notStrictEqual(stubInterval.firstCall, stubUpdate)
stubInterval.firstCall[0]()
while (db.data.core.test.updater === '') {
await setTimeout(10)
}
assert.match(db.data.core.test.updater, /auto/i)
assert.match(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(util, db, {}, 'test', { setInterval: stubInterval })
app.update = function() {
return Promise.reject(new Error(assertErrorMessage))
}
app.startAutoupdater()
assert.strictEqual(db.data.core.test.updater, '')
stubInterval.firstCall[0]()
while (db.data.core.test.updater === '') {
await setTimeout(10)
}
assert.match(db.data.core.test.updater, /auto/i)
assert.match(db.data.core.test.updater, /update/i)
assert.match(db.data.core.test.updater, new RegExp(assertErrorMessage))
})
})
t.timeout(250).describe('#update()', function() {
let db
let app
let provider
t.beforeEach(function() {
return lowdb({ test: { } }, logger, null).then(function(res) {
db = res
provider = createProvider()
app = new Application(util, db, provider, 'testapp')
})
})
t.afterEach(function() {
return fs.rm('./test/testapp/123456789', { force: true, recursive: true })
})
t.test('multiple calls should be safe', async function() {
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)
db.data.core.testapp.updater = ''
let err = await assert.isRejected(app.update())
assert.strictEqual(err, assertError)
assert.strictEqual(app.updating, false)
assert.match(db.data.core.testapp.updater, /check/i)
assert.match(db.data.core.testapp.updater, /version/i)
assert.match(db.data.core.testapp.updater, new RegExp(new Date().toISOString().split('T')[0]))
})
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')
await assert.isRejected(fs.stat('./test/testapp/123456789'))
provider.getLatestVersion.resolves(assertVersion)
provider.downloadVersion.rejects(assertError)
db.data.core.testapp.updater = ''
let err = await assert.isRejected(app.update())
assert.strictEqual(err, assertError)
assert.strictEqual(app.updating, false)
assert.match(db.data.core.testapp.updater, /found/i)
assert.match(db.data.core.testapp.updater, new RegExp(assertVersion.version))
assert.match(db.data.core.testapp.updater, /downloading/i)
assert.match(db.data.core.testapp.updater, new RegExp(assertLink))
assert.match(db.data.core.testapp.updater, new RegExp(assertTarget.replace(/\\/g, '\\\\')))
assert.strictEqual(provider.downloadVersion.firstCall[0], assertVersion)
assert.strictEqual(provider.downloadVersion.firstCall[1], assertTarget)
await fs.stat('./test/testapp/123456789')
})
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')
await assert.isRejected(fs.stat('./test/testapp/123456789'))
provider.getLatestVersion.resolves(assertVersion)
provider.downloadVersion.rejects(assertError)
db.data.core.testapp.updater = ''
let err = await assert.isRejected(app.update())
assert.strictEqual(err, assertError)
assert.strictEqual(app.updating, false)
assert.match(db.data.core.testapp.updater, /found/i)
assert.match(db.data.core.testapp.updater, new RegExp(assertVersion.version))
assert.match(db.data.core.testapp.updater, /downloading/i)
assert.match(db.data.core.testapp.updater, new RegExp(assertLink))
assert.match(db.data.core.testapp.updater, new RegExp(assertTarget.replace(/\\/g, '\\\\')))
assert.strictEqual(provider.downloadVersion.firstCall[0], assertVersion)
assert.strictEqual(provider.downloadVersion.firstCall[1], assertTarget)
await fs.stat('./test/testapp/123456789')
})
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)
db.data.core.testapp.updater = ''
db.data.core.testapp.latestInstalled = assertVersion.version
await app.update()
assert.notOk(provider.downloadVersion.called)
assert.match(db.data.core.testapp.updater, /already/i)
assert.match(db.data.core.testapp.updater, /nothing/i)
})
})