tests: fix memory leaks (#2389)
This commit is contained in:
@@ -1,41 +1,46 @@
|
||||
/* eslint-disable no-unused-expressions */
|
||||
/* eslint-disable no-undef */
|
||||
import * as Factory from './lib/factory.js'
|
||||
import * as Utils from './lib/Utils.js'
|
||||
|
||||
chai.use(chaiAsPromised)
|
||||
const expect = chai.expect
|
||||
|
||||
describe('actions service', () => {
|
||||
const errorProcessingActionMessage = 'An issue occurred while processing this action. Please try again.'
|
||||
|
||||
before(async function () {
|
||||
let application
|
||||
let itemManager
|
||||
let actionsManager
|
||||
let email
|
||||
let password
|
||||
let authParams
|
||||
let fakeServer
|
||||
let actionsExtension
|
||||
let extensionItemUuid
|
||||
|
||||
beforeEach(async function () {
|
||||
this.timeout(20000)
|
||||
|
||||
localStorage.clear()
|
||||
|
||||
this.application = await Factory.createInitAppWithFakeCrypto()
|
||||
this.itemManager = this.application.items
|
||||
this.actionsManager = this.application.actions
|
||||
this.email = UuidGenerator.GenerateUuid()
|
||||
this.password = UuidGenerator.GenerateUuid()
|
||||
application = await Factory.createInitAppWithFakeCrypto()
|
||||
itemManager = application.items
|
||||
actionsManager = application.actions
|
||||
email = UuidGenerator.GenerateUuid()
|
||||
password = UuidGenerator.GenerateUuid()
|
||||
|
||||
await Factory.registerUserToApplication({
|
||||
application: this.application,
|
||||
email: this.email,
|
||||
password: this.password,
|
||||
application: application,
|
||||
email: email,
|
||||
password: password,
|
||||
})
|
||||
|
||||
const rootKey = await this.application.encryption.createRootKey(
|
||||
this.email,
|
||||
this.password,
|
||||
KeyParamsOrigination.Registration,
|
||||
)
|
||||
this.authParams = rootKey.keyParams.content
|
||||
const rootKey = await application.encryption.createRootKey(email, password, KeyParamsOrigination.Registration)
|
||||
authParams = rootKey.keyParams.content
|
||||
|
||||
this.fakeServer = sinon.fakeServer.create()
|
||||
this.fakeServer.respondImmediately = true
|
||||
fakeServer = sinon.fakeServer.create()
|
||||
fakeServer.respondImmediately = true
|
||||
|
||||
this.actionsExtension = {
|
||||
actionsExtension = {
|
||||
identifier: 'org.standardnotes.testing',
|
||||
name: 'Test extension',
|
||||
content_type: 'Extension',
|
||||
@@ -81,9 +86,9 @@ describe('actions service', () => {
|
||||
],
|
||||
}
|
||||
|
||||
this.fakeServer.respondWith('GET', /http:\/\/my-extension.sn.org\/get_actions\/(.*)/, (request, params) => {
|
||||
fakeServer.respondWith('GET', /http:\/\/my-extension.sn.org\/get_actions\/(.*)/, (request, params) => {
|
||||
const urlParams = new URLSearchParams(params)
|
||||
const extension = Copy(this.actionsExtension)
|
||||
const extension = Copy(actionsExtension)
|
||||
|
||||
if (urlParams.has('item_uuid')) {
|
||||
extension.actions.push({
|
||||
@@ -117,31 +122,31 @@ describe('actions service', () => {
|
||||
})
|
||||
|
||||
const encryptedPayload = CreateEncryptedServerSyncPushPayload(
|
||||
await this.application.encryption.encryptSplitSingle({
|
||||
await application.encryption.encryptSplitSingle({
|
||||
usesItemsKeyWithKeyLookup: {
|
||||
items: [payload],
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
this.fakeServer.respondWith('GET', /http:\/\/my-extension.sn.org\/action_[1,2]\/(.*)/, (request) => {
|
||||
fakeServer.respondWith('GET', /http:\/\/my-extension.sn.org\/action_[1,2]\/(.*)/, (request) => {
|
||||
request.respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify({
|
||||
item: encryptedPayload,
|
||||
auth_params: this.authParams,
|
||||
auth_params: authParams,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
this.fakeServer.respondWith('GET', 'http://my-extension.sn.org/action_3/', [
|
||||
fakeServer.respondWith('GET', 'http://my-extension.sn.org/action_3/', [
|
||||
200,
|
||||
{ 'Content-Type': 'text/html; charset=utf-8' },
|
||||
'<h2>Action #3</h2>',
|
||||
])
|
||||
|
||||
this.fakeServer.respondWith('POST', /http:\/\/my-extension.sn.org\/action_[4,6]\/(.*)/, (request) => {
|
||||
fakeServer.respondWith('POST', /http:\/\/my-extension.sn.org\/action_[4,6]\/(.*)/, (request) => {
|
||||
const requestBody = JSON.parse(request.requestBody)
|
||||
|
||||
const response = {
|
||||
@@ -152,7 +157,7 @@ describe('actions service', () => {
|
||||
request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(response))
|
||||
})
|
||||
|
||||
this.fakeServer.respondWith('GET', 'http://my-extension.sn.org/action_5/', (request) => {
|
||||
fakeServer.respondWith('GET', 'http://my-extension.sn.org/action_5/', (request) => {
|
||||
const encryptedPayloadClone = Copy(encryptedPayload)
|
||||
|
||||
encryptedPayloadClone.items_key_id = undefined
|
||||
@@ -163,53 +168,56 @@ describe('actions service', () => {
|
||||
|
||||
const payload = {
|
||||
item: encryptedPayloadClone,
|
||||
auth_params: this.authParams,
|
||||
auth_params: authParams,
|
||||
}
|
||||
|
||||
request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(payload))
|
||||
})
|
||||
|
||||
// Extension item
|
||||
const extensionItem = await this.application.mutator.createItem(
|
||||
ContentType.TYPES.ActionsExtension,
|
||||
this.actionsExtension,
|
||||
)
|
||||
this.extensionItemUuid = extensionItem.uuid
|
||||
const extensionItem = await application.mutator.createItem(ContentType.TYPES.ActionsExtension, actionsExtension)
|
||||
extensionItemUuid = extensionItem.uuid
|
||||
})
|
||||
|
||||
after(async function () {
|
||||
this.fakeServer.restore()
|
||||
await Factory.safeDeinit(this.application)
|
||||
this.application = null
|
||||
afterEach(async function () {
|
||||
fakeServer.restore()
|
||||
|
||||
await Factory.safeDeinit(application)
|
||||
|
||||
application = undefined
|
||||
itemManager = undefined
|
||||
actionsManager = undefined
|
||||
fakeServer = undefined
|
||||
|
||||
localStorage.clear()
|
||||
})
|
||||
|
||||
it('should get extension items', async function () {
|
||||
await this.application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
await application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
title: 'A simple note',
|
||||
text: 'Standard Notes rocks! lml.',
|
||||
})
|
||||
const extensions = this.actionsManager.getExtensions()
|
||||
const extensions = actionsManager.getExtensions()
|
||||
expect(extensions.length).to.eq(1)
|
||||
})
|
||||
|
||||
it('should get extensions in context of item', async function () {
|
||||
const noteItem = await this.application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
title: 'Another note',
|
||||
text: 'Whiskey In The Jar',
|
||||
})
|
||||
|
||||
const noteItemExtensions = this.actionsManager.extensionsInContextOfItem(noteItem)
|
||||
const noteItemExtensions = actionsManager.extensionsInContextOfItem(noteItem)
|
||||
expect(noteItemExtensions.length).to.eq(1)
|
||||
expect(noteItemExtensions[0].supported_types).to.include(noteItem.content_type)
|
||||
})
|
||||
|
||||
it('should get actions based on item context', async function () {
|
||||
const tagItem = await this.application.mutator.createItem(ContentType.TYPES.Tag, {
|
||||
const tagItem = await application.mutator.createItem(ContentType.TYPES.Tag, {
|
||||
title: 'Music',
|
||||
})
|
||||
|
||||
const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
|
||||
const extensionItem = await itemManager.findItem(extensionItemUuid)
|
||||
const tagActions = extensionItem.actionsWithContextForItem(tagItem)
|
||||
|
||||
expect(tagActions.length).to.eq(1)
|
||||
@@ -217,15 +225,15 @@ describe('actions service', () => {
|
||||
})
|
||||
|
||||
it('should load extension in context of item', async function () {
|
||||
const noteItem = await this.application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
title: 'Yet another note',
|
||||
text: 'And all things will end ♫',
|
||||
})
|
||||
|
||||
const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
|
||||
const extensionItem = await itemManager.findItem(extensionItemUuid)
|
||||
expect(extensionItem.actions.length).to.be.eq(5)
|
||||
|
||||
const extensionWithItem = await this.actionsManager.loadExtensionInContextOfItem(extensionItem, noteItem)
|
||||
const extensionWithItem = await actionsManager.loadExtensionInContextOfItem(extensionItem, noteItem)
|
||||
expect(extensionWithItem.actions.length).to.be.eq(7)
|
||||
expect(extensionWithItem.actions.map((action) => action.label)).to.include.members([
|
||||
/**
|
||||
@@ -237,7 +245,7 @@ describe('actions service', () => {
|
||||
])
|
||||
|
||||
// Actions that are relevant for an item should not be stored.
|
||||
const updatedExtensionItem = await this.itemManager.findItem(this.extensionItemUuid)
|
||||
const updatedExtensionItem = await itemManager.findItem(extensionItemUuid)
|
||||
const expectedActions = extensionItem.actions.map((action) => {
|
||||
const { id, ...rest } = action
|
||||
return rest
|
||||
@@ -248,18 +256,22 @@ describe('actions service', () => {
|
||||
describe('render action', async function () {
|
||||
const sandbox = sinon.createSandbox()
|
||||
|
||||
before(async function () {
|
||||
this.noteItem = await this.application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
let noteItem
|
||||
let renderAction
|
||||
let alertServiceAlert
|
||||
let windowAlert
|
||||
let httpServiceGetAbsolute
|
||||
|
||||
beforeEach(async function () {
|
||||
noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
title: 'Hey',
|
||||
text: 'Welcome To Paradise',
|
||||
})
|
||||
const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
|
||||
this.renderAction = extensionItem.actions.filter((action) => action.verb === 'render')[0]
|
||||
})
|
||||
const extensionItem = await itemManager.findItem(extensionItemUuid)
|
||||
|
||||
beforeEach(async function () {
|
||||
this.alertServiceAlert = sandbox.spy(this.actionsManager.alertService, 'alert')
|
||||
this.windowAlert = sandbox.stub(window, 'alert').callsFake((message) => message)
|
||||
renderAction = extensionItem.actions.filter((action) => action.verb === 'render')[0]
|
||||
alertServiceAlert = sandbox.spy(actionsManager.alertService, 'alert')
|
||||
windowAlert = sandbox.stub(window, 'alert').callsFake((message) => message)
|
||||
})
|
||||
|
||||
afterEach(async function () {
|
||||
@@ -267,35 +279,35 @@ describe('actions service', () => {
|
||||
})
|
||||
|
||||
it('should show an alert if the request fails', async function () {
|
||||
this.httpServiceGetAbsolute = sandbox
|
||||
.stub(this.actionsManager.httpService, 'getAbsolute')
|
||||
httpServiceGetAbsolute = sandbox
|
||||
.stub(actionsManager.httpService, 'getAbsolute')
|
||||
.callsFake((url) => Promise.reject(new Error('Dummy error.')))
|
||||
|
||||
const actionResponse = await this.actionsManager.runAction(this.renderAction, this.noteItem)
|
||||
const actionResponse = await actionsManager.runAction(renderAction, noteItem)
|
||||
|
||||
sinon.assert.calledOnceWithExactly(this.httpServiceGetAbsolute, this.renderAction.url)
|
||||
sinon.assert.calledOnceWithExactly(this.alertServiceAlert, errorProcessingActionMessage)
|
||||
sinon.assert.calledOnceWithExactly(httpServiceGetAbsolute, renderAction.url)
|
||||
sinon.assert.calledOnceWithExactly(alertServiceAlert, errorProcessingActionMessage)
|
||||
expect(actionResponse.error.message).to.eq(errorProcessingActionMessage)
|
||||
})
|
||||
|
||||
it('should return a response if payload is valid', async function () {
|
||||
const actionResponse = await this.actionsManager.runAction(this.renderAction, this.noteItem)
|
||||
const actionResponse = await actionsManager.runAction(renderAction, noteItem)
|
||||
|
||||
expect(actionResponse).to.have.property('item')
|
||||
expect(actionResponse.item.payload.content.title).to.eq('Testing')
|
||||
})
|
||||
|
||||
it('should return undefined if payload is invalid', async function () {
|
||||
sandbox.stub(this.actionsManager, 'payloadByDecryptingResponse').returns(null)
|
||||
sandbox.stub(actionsManager, 'payloadByDecryptingResponse').returns(null)
|
||||
|
||||
const actionResponse = await this.actionsManager.runAction(this.renderAction, this.noteItem)
|
||||
const actionResponse = await actionsManager.runAction(renderAction, noteItem)
|
||||
expect(actionResponse).to.be.undefined
|
||||
})
|
||||
|
||||
it('should return decrypted payload if password is valid', async function () {
|
||||
const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
|
||||
this.renderAction = extensionItem.actions.filter((action) => action.verb === 'render')[0]
|
||||
const actionResponse = await this.actionsManager.runAction(this.renderAction, this.noteItem)
|
||||
const extensionItem = await itemManager.findItem(extensionItemUuid)
|
||||
renderAction = extensionItem.actions.filter((action) => action.verb === 'render')[0]
|
||||
const actionResponse = await actionsManager.runAction(renderAction, noteItem)
|
||||
|
||||
expect(actionResponse.item).to.be.ok
|
||||
expect(actionResponse.item.title).to.be.equal('Testing')
|
||||
@@ -305,24 +317,24 @@ describe('actions service', () => {
|
||||
describe('show action', async function () {
|
||||
const sandbox = sinon.createSandbox()
|
||||
|
||||
before(async function () {
|
||||
const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
|
||||
this.showAction = extensionItem.actions[2]
|
||||
})
|
||||
let showAction
|
||||
let deviceInterfaceOpenUrl
|
||||
|
||||
beforeEach(async function () {
|
||||
this.actionsManager.device.openUrl = (url) => url
|
||||
this.deviceInterfaceOpenUrl = sandbox.spy(this.actionsManager.device, 'openUrl')
|
||||
const extensionItem = await itemManager.findItem(extensionItemUuid)
|
||||
showAction = extensionItem.actions[2]
|
||||
actionsManager.device.openUrl = (url) => url
|
||||
deviceInterfaceOpenUrl = sandbox.spy(actionsManager.device, 'openUrl')
|
||||
})
|
||||
|
||||
this.afterEach(async function () {
|
||||
afterEach(async function () {
|
||||
sandbox.restore()
|
||||
})
|
||||
|
||||
it('should open the action url', async function () {
|
||||
const response = await this.actionsManager.runAction(this.showAction)
|
||||
const response = await actionsManager.runAction(showAction)
|
||||
|
||||
sandbox.assert.calledOnceWithExactly(this.deviceInterfaceOpenUrl, this.showAction.url)
|
||||
sandbox.assert.calledOnceWithExactly(deviceInterfaceOpenUrl, showAction.url)
|
||||
expect(response).to.eql({})
|
||||
})
|
||||
})
|
||||
@@ -330,28 +342,32 @@ describe('actions service', () => {
|
||||
describe('post action', async function () {
|
||||
const sandbox = sinon.createSandbox()
|
||||
|
||||
before(async function () {
|
||||
this.noteItem = await this.application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
let noteItem
|
||||
let extensionItem
|
||||
let decryptedPostAction
|
||||
let encryptedPostAction
|
||||
let alertServiceAlert
|
||||
let httpServicePostAbsolute
|
||||
|
||||
beforeEach(async function () {
|
||||
noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
|
||||
title: 'Excuse Me',
|
||||
text: 'Time To Be King 8)',
|
||||
})
|
||||
this.extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
|
||||
this.extensionItem = await this.actionsManager.loadExtensionInContextOfItem(this.extensionItem, this.noteItem)
|
||||
extensionItem = await itemManager.findItem(extensionItemUuid)
|
||||
extensionItem = await actionsManager.loadExtensionInContextOfItem(extensionItem, noteItem)
|
||||
|
||||
this.decryptedPostAction = this.extensionItem.actions.filter(
|
||||
decryptedPostAction = extensionItem.actions.filter(
|
||||
(action) => action.access_type === 'decrypted' && action.verb === 'post',
|
||||
)[0]
|
||||
|
||||
this.encryptedPostAction = this.extensionItem.actions.filter(
|
||||
encryptedPostAction = extensionItem.actions.filter(
|
||||
(action) => action.access_type === 'encrypted' && action.verb === 'post',
|
||||
)[0]
|
||||
})
|
||||
|
||||
beforeEach(async function () {
|
||||
this.alertServiceAlert = sandbox.spy(this.actionsManager.alertService, 'alert')
|
||||
this.windowAlert = sandbox.stub(window, 'alert').callsFake((message) => message)
|
||||
this.httpServicePostAbsolute = sandbox.stub(this.actionsManager.httpService, 'postAbsolute')
|
||||
this.httpServicePostAbsolute.callsFake((url, params) => Promise.resolve(params))
|
||||
alertServiceAlert = sandbox.spy(actionsManager.alertService, 'alert')
|
||||
sandbox.stub(window, 'alert').callsFake((message) => message)
|
||||
httpServicePostAbsolute = sandbox.stub(actionsManager.httpService, 'postAbsolute')
|
||||
httpServicePostAbsolute.callsFake((url, params) => Promise.resolve(params))
|
||||
})
|
||||
|
||||
afterEach(async function () {
|
||||
@@ -359,52 +375,50 @@ describe('actions service', () => {
|
||||
})
|
||||
|
||||
it('should include generic encrypted payload within request body', async function () {
|
||||
const response = await this.actionsManager.runAction(this.encryptedPostAction, this.noteItem)
|
||||
const response = await actionsManager.runAction(encryptedPostAction, noteItem)
|
||||
|
||||
expect(response.items[0].enc_item_key).to.satisfy((string) => {
|
||||
return string.startsWith(this.application.encryption.getLatestVersion())
|
||||
return string.startsWith(application.encryption.getLatestVersion())
|
||||
})
|
||||
expect(response.items[0].uuid).to.eq(this.noteItem.uuid)
|
||||
expect(response.items[0].uuid).to.eq(noteItem.uuid)
|
||||
expect(response.items[0].auth_hash).to.not.be.ok
|
||||
expect(response.items[0].content_type).to.be.ok
|
||||
expect(response.items[0].created_at).to.be.ok
|
||||
expect(response.items[0].content).to.satisfy((string) => {
|
||||
return string.startsWith(this.application.encryption.getLatestVersion())
|
||||
return string.startsWith(application.encryption.getLatestVersion())
|
||||
})
|
||||
})
|
||||
|
||||
it('should include generic decrypted payload within request body', async function () {
|
||||
const response = await this.actionsManager.runAction(this.decryptedPostAction, this.noteItem)
|
||||
const response = await actionsManager.runAction(decryptedPostAction, noteItem)
|
||||
|
||||
expect(response.items[0].uuid).to.eq(this.noteItem.uuid)
|
||||
expect(response.items[0].uuid).to.eq(noteItem.uuid)
|
||||
expect(response.items[0].enc_item_key).to.not.be.ok
|
||||
expect(response.items[0].auth_hash).to.not.be.ok
|
||||
expect(response.items[0].content_type).to.be.ok
|
||||
expect(response.items[0].created_at).to.be.ok
|
||||
expect(response.items[0].content.title).to.eq(this.noteItem.title)
|
||||
expect(response.items[0].content.text).to.eq(this.noteItem.text)
|
||||
expect(response.items[0].content.title).to.eq(noteItem.title)
|
||||
expect(response.items[0].content.text).to.eq(noteItem.text)
|
||||
})
|
||||
|
||||
it('should post to the action url', async function () {
|
||||
this.httpServicePostAbsolute.restore()
|
||||
const response = await this.actionsManager.runAction(this.decryptedPostAction, this.noteItem)
|
||||
httpServicePostAbsolute.restore()
|
||||
const response = await actionsManager.runAction(decryptedPostAction, noteItem)
|
||||
|
||||
expect(response).to.be.ok
|
||||
expect(response.uuid).to.eq(this.noteItem.uuid)
|
||||
expect(response.uuid).to.eq(noteItem.uuid)
|
||||
expect(response.result).to.eq('Action POSTed successfully.')
|
||||
})
|
||||
|
||||
it('should alert if an error occurred while processing the action', async function () {
|
||||
this.httpServicePostAbsolute.restore()
|
||||
httpServicePostAbsolute.restore()
|
||||
const dummyError = new Error('Dummy error.')
|
||||
|
||||
sandbox
|
||||
.stub(this.actionsManager.httpService, 'postAbsolute')
|
||||
.callsFake((url, params) => Promise.reject(dummyError))
|
||||
sandbox.stub(actionsManager.httpService, 'postAbsolute').callsFake((url, params) => Promise.reject(dummyError))
|
||||
|
||||
const response = await this.actionsManager.runAction(this.decryptedPostAction, this.noteItem)
|
||||
const response = await actionsManager.runAction(decryptedPostAction, noteItem)
|
||||
|
||||
sinon.assert.calledOnceWithExactly(this.alertServiceAlert, errorProcessingActionMessage)
|
||||
sinon.assert.calledOnceWithExactly(alertServiceAlert, errorProcessingActionMessage)
|
||||
expect(response).to.be.eq(dummyError)
|
||||
})
|
||||
})
|
||||
@@ -412,15 +426,17 @@ describe('actions service', () => {
|
||||
describe('nested action', async function () {
|
||||
const sandbox = sinon.createSandbox()
|
||||
|
||||
before(async function () {
|
||||
const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
|
||||
this.nestedAction = extensionItem.actions.filter((action) => action.verb === 'nested')[0]
|
||||
})
|
||||
let nestedAction
|
||||
let actionsManagerRunAction
|
||||
let httpServiceRunHttp
|
||||
let actionResponse
|
||||
|
||||
beforeEach(async function () {
|
||||
this.actionsManagerRunAction = sandbox.spy(this.actionsManager, 'runAction')
|
||||
this.httpServiceRunHttp = sandbox.spy(this.actionsManager.httpService, 'runHttp')
|
||||
this.actionResponse = await this.actionsManager.runAction(this.nestedAction)
|
||||
const extensionItem = await itemManager.findItem(extensionItemUuid)
|
||||
nestedAction = extensionItem.actions.filter((action) => action.verb === 'nested')[0]
|
||||
actionsManagerRunAction = sandbox.spy(actionsManager, 'runAction')
|
||||
httpServiceRunHttp = sandbox.spy(actionsManager.httpService, 'runHttp')
|
||||
actionResponse = await actionsManager.runAction(nestedAction)
|
||||
})
|
||||
|
||||
afterEach(async function () {
|
||||
@@ -428,15 +444,15 @@ describe('actions service', () => {
|
||||
})
|
||||
|
||||
it('should return undefined', async function () {
|
||||
expect(this.actionResponse).to.be.undefined
|
||||
expect(actionResponse).to.be.undefined
|
||||
})
|
||||
|
||||
it('should call runAction once', async function () {
|
||||
sandbox.assert.calledOnce(this.actionsManagerRunAction)
|
||||
sandbox.assert.calledOnce(actionsManagerRunAction)
|
||||
})
|
||||
|
||||
it('should not make any http requests', async function () {
|
||||
sandbox.assert.notCalled(this.httpServiceRunHttp)
|
||||
sandbox.assert.notCalled(httpServiceRunHttp)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user