api-notification-dbus-spec.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // For these tests we use a fake DBus daemon to verify libnotify interaction
  2. // with the session bus. This requires python-dbusmock to be installed and
  3. // running at $DBUS_SESSION_BUS_ADDRESS.
  4. //
  5. // script/test.py spawns dbusmock, which sets DBUS_SESSION_BUS_ADDRESS.
  6. //
  7. // See https://pypi.python.org/pypi/python-dbusmock to read about dbusmock.
  8. const assert = require('assert')
  9. const dbus = require('dbus-native')
  10. const Promise = require('bluebird')
  11. const {remote} = require('electron')
  12. const {app} = remote.require('electron')
  13. const skip = process.platform !== 'linux' ||
  14. process.arch === 'ia32' ||
  15. !process.env.DBUS_SESSION_BUS_ADDRESS;
  16. (skip ? describe.skip : describe)('Notification module (dbus)', () => {
  17. let mock, Notification, getCalls, reset
  18. const realAppName = app.getName()
  19. const realAppVersion = app.getVersion()
  20. const appName = 'api-notification-dbus-spec'
  21. const serviceName = 'org.freedesktop.Notifications'
  22. before(async () => {
  23. // init app
  24. app.setName(appName)
  25. app.setDesktopName(appName + '.desktop')
  26. // init dbus
  27. const path = '/org/freedesktop/Notifications'
  28. const iface = 'org.freedesktop.DBus.Mock'
  29. const bus = dbus.sessionBus()
  30. console.log('session bus: ' + process.env.DBUS_SESSION_BUS_ADDRESS)
  31. const service = bus.getService(serviceName)
  32. const getInterface = Promise.promisify(service.getInterface, {context: service})
  33. mock = await getInterface(path, iface)
  34. getCalls = Promise.promisify(mock.GetCalls, {context: mock})
  35. reset = Promise.promisify(mock.Reset, {context: mock})
  36. })
  37. after(async () => {
  38. // cleanup dbus
  39. await reset()
  40. // cleanup app
  41. app.setName(realAppName)
  42. app.setVersion(realAppVersion)
  43. })
  44. describe('Notification module using ' + serviceName, () => {
  45. function onMethodCalled (done) {
  46. function cb (name) {
  47. console.log('onMethodCalled: ' + name)
  48. if (name === 'Notify') {
  49. mock.removeListener('MethodCalled', cb)
  50. console.log('done')
  51. done()
  52. }
  53. }
  54. return cb
  55. }
  56. function unmarshalDBusNotifyHints (dbusHints) {
  57. let o = {}
  58. for (let hint of dbusHints) {
  59. let key = hint[0]
  60. let value = hint[1][1][0]
  61. o[key] = value
  62. }
  63. return o
  64. }
  65. function unmarshalDBusNotifyArgs (dbusArgs) {
  66. return {
  67. app_name: dbusArgs[0][1][0],
  68. replaces_id: dbusArgs[1][1][0],
  69. app_icon: dbusArgs[2][1][0],
  70. title: dbusArgs[3][1][0],
  71. body: dbusArgs[4][1][0],
  72. actions: dbusArgs[5][1][0],
  73. hints: unmarshalDBusNotifyHints(dbusArgs[6][1][0])
  74. }
  75. }
  76. before((done) => {
  77. mock.on('MethodCalled', onMethodCalled(done))
  78. // lazy load Notification after we listen to MethodCalled mock signal
  79. Notification = require('electron').remote.Notification
  80. const n = new Notification({
  81. title: 'title',
  82. subtitle: 'subtitle',
  83. body: 'body',
  84. replyPlaceholder: 'replyPlaceholder',
  85. sound: 'sound',
  86. closeButtonText: 'closeButtonText'
  87. })
  88. n.show()
  89. })
  90. it('should call ' + serviceName + ' to show notifications', async () => {
  91. const calls = await getCalls()
  92. assert(calls.length >= 1)
  93. let lastCall = calls[calls.length - 1]
  94. let methodName = lastCall[1]
  95. assert.equal(methodName, 'Notify')
  96. let args = unmarshalDBusNotifyArgs(lastCall[2])
  97. assert.deepEqual(args, {
  98. app_name: appName,
  99. replaces_id: 0,
  100. app_icon: '',
  101. title: 'title',
  102. body: 'body',
  103. actions: [],
  104. hints: {
  105. 'append': 'true',
  106. 'desktop-entry': appName
  107. }
  108. })
  109. })
  110. })
  111. })