electron/spec-main/api-notification-dbus-spec.ts

125 lines
3.7 KiB
TypeScript
Raw Normal View History

// For these tests we use a fake DBus daemon to verify libnotify interaction
// with the session bus. This requires python-dbusmock to be installed and
// running at $DBUS_SESSION_BUS_ADDRESS.
//
// script/spec-runner.js spawns dbusmock, which sets DBUS_SESSION_BUS_ADDRESS.
//
// See https://pypi.python.org/pypi/python-dbusmock to read about dbusmock.
2019-08-28 20:54:50 +00:00
import { expect } from 'chai'
import * as dbus from 'dbus-native'
import { app } from 'electron'
import { ifdescribe } from './spec-helpers'
import { promisify } from 'util';
const skip = process.platform !== 'linux' ||
process.arch === 'ia32' ||
process.arch.indexOf('arm') === 0 ||
2019-08-28 20:54:50 +00:00
!process.env.DBUS_SESSION_BUS_ADDRESS
2019-08-28 20:54:50 +00:00
ifdescribe(!skip)('Notification module (dbus)', () => {
let mock: any, Notification, getCalls: any, reset: any
const realAppName = app.name
const realAppVersion = app.getVersion()
const appName = 'api-notification-dbus-spec'
const serviceName = 'org.freedesktop.Notifications'
before(async () => {
// init app
app.name = appName
2018-06-28 22:40:30 +00:00
app.setDesktopName(`${appName}.desktop`)
// init dbus
const path = '/org/freedesktop/Notifications'
const iface = 'org.freedesktop.DBus.Mock'
const bus = dbus.sessionBus()
2018-06-28 22:40:30 +00:00
console.log(`session bus: ${process.env.DBUS_SESSION_BUS_ADDRESS}`)
const service = bus.getService(serviceName)
2019-08-28 20:54:50 +00:00
const getInterface = promisify(service.getInterface.bind(service))
mock = await getInterface(path, iface)
2019-08-28 20:54:50 +00:00
getCalls = promisify(mock.GetCalls.bind(mock))
reset = promisify(mock.Reset.bind(mock))
})
after(async () => {
// cleanup dbus
await reset()
// cleanup app
app.setName(realAppName)
app.setVersion(realAppVersion)
})
2018-06-28 22:40:30 +00:00
describe(`Notification module using ${serviceName}`, () => {
2019-08-28 20:54:50 +00:00
function onMethodCalled (done: () => void) {
function cb (name: string) {
2018-06-28 22:40:30 +00:00
console.log(`onMethodCalled: ${name}`)
if (name === 'Notify') {
mock.removeListener('MethodCalled', cb)
console.log('done')
done()
}
}
return cb
}
2019-08-28 20:54:50 +00:00
function unmarshalDBusNotifyHints (dbusHints: any) {
const o: Record<string, any> = {}
for (const hint of dbusHints) {
const key = hint[0]
const value = hint[1][1][0]
o[key] = value
}
return o
}
2019-08-28 20:54:50 +00:00
function unmarshalDBusNotifyArgs (dbusArgs: any) {
return {
app_name: dbusArgs[0][1][0],
replaces_id: dbusArgs[1][1][0],
app_icon: dbusArgs[2][1][0],
title: dbusArgs[3][1][0],
body: dbusArgs[4][1][0],
actions: dbusArgs[5][1][0],
hints: unmarshalDBusNotifyHints(dbusArgs[6][1][0])
}
}
2018-06-28 22:40:30 +00:00
before(done => {
mock.on('MethodCalled', onMethodCalled(done))
// lazy load Notification after we listen to MethodCalled mock signal
2019-08-28 20:54:50 +00:00
Notification = require('electron').Notification
const n = new Notification({
title: 'title',
subtitle: 'subtitle',
body: 'body',
replyPlaceholder: 'replyPlaceholder',
sound: 'sound',
closeButtonText: 'closeButtonText'
})
n.show()
})
2018-06-28 22:40:30 +00:00
it(`should call ${serviceName} to show notifications`, async () => {
const calls = await getCalls()
2018-07-10 21:20:03 +00:00
expect(calls).to.be.an('array').of.lengthOf.at.least(1)
const lastCall = calls[calls.length - 1]
const methodName = lastCall[1]
2018-06-28 22:40:30 +00:00
expect(methodName).to.equal('Notify')
2018-07-10 21:20:03 +00:00
const args = unmarshalDBusNotifyArgs(lastCall[2])
2018-06-28 22:40:30 +00:00
expect(args).to.deep.equal({
app_name: appName,
replaces_id: 0,
app_icon: '',
title: 'title',
body: 'body',
actions: [],
hints: {
'append': 'true',
'desktop-entry': appName
}
})
})
})
})