index.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. const Notification = require('../../lib/notification');
  2. const sinon = require('sinon');
  3. describe('Notification', function () {
  4. let note;
  5. beforeEach(function () {
  6. note = new Notification();
  7. });
  8. describe('constructor', function () {
  9. it('accepts initialization values', function () {
  10. const properties = { priority: 5, topic: 'io.apn.node', payload: { foo: 'bar' }, badge: 5 };
  11. note = new Notification(properties);
  12. expect(note.payload).to.deep.equal({ foo: 'bar' });
  13. expect(note.priority).to.equal(5);
  14. expect(note.topic).to.equal('io.apn.node');
  15. expect(compiledOutput()).to.have.nested.deep.property('aps.badge', 5);
  16. });
  17. });
  18. describe('rawPayload', function () {
  19. it('is used as the JSON output', function () {
  20. const payload = { some: 'payload' };
  21. note = new Notification({ rawPayload: payload });
  22. expect(note.rawPayload).to.deep.equal({ some: 'payload' });
  23. expect(compiledOutput()).to.deep.equal({ some: 'payload' });
  24. });
  25. it('does not get clobbered by aps accessors', function () {
  26. const payload = { some: 'payload', aps: { alert: 'Foo' } };
  27. note = new Notification({ rawPayload: payload });
  28. note.alertBody = 'Bar';
  29. expect(note.rawPayload).to.deep.equal({ some: 'payload', aps: { alert: 'Foo' } });
  30. expect(compiledOutput()).to.deep.equal({ some: 'payload', aps: { alert: 'Foo' } });
  31. });
  32. it('takes precedence over the `mdm` property', function () {
  33. const payload = { some: 'payload' };
  34. note = new Notification({ rawPayload: payload });
  35. note.mdm = 'abcd';
  36. expect(note.rawPayload).to.deep.equal({ some: 'payload' });
  37. expect(compiledOutput()).to.deep.equal({ some: 'payload' });
  38. });
  39. context('when passed in the notification constructor', function () {
  40. beforeEach(function () {
  41. note = new Notification({
  42. rawPayload: { foo: 'bar', baz: 1, aps: { badge: 1, alert: 'Hi there!' } },
  43. });
  44. });
  45. it('contains all original payload properties', function () {
  46. expect(compiledOutput()).to.have.property('foo', 'bar');
  47. expect(compiledOutput()).to.have.property('baz', 1);
  48. });
  49. it('contains the correct aps properties', function () {
  50. expect(compiledOutput()).to.have.nested.deep.property('aps.badge', 1);
  51. expect(compiledOutput()).to.have.nested.deep.property('aps.alert', 'Hi there!');
  52. });
  53. });
  54. });
  55. describe('payload', function () {
  56. describe('when no aps properties are set', function () {
  57. it('contains all original payload properties', function () {
  58. note.payload = { foo: 'bar', baz: 1 };
  59. expect(compiledOutput()).to.eql({ foo: 'bar', baz: 1 });
  60. });
  61. });
  62. describe('when aps properties are given by setters', function () {
  63. it('should not mutate the originally given paylaod object', function () {
  64. const payload = { foo: 'bar', baz: 1 };
  65. note.payload = payload;
  66. note.badge = 1;
  67. note.sound = 'ping.aiff';
  68. note.toJSON();
  69. expect(payload).to.deep.equal({ foo: 'bar', baz: 1 });
  70. });
  71. });
  72. describe('when aps payload is present', function () {
  73. beforeEach(function () {
  74. note.payload = { foo: 'bar', baz: 1, aps: { badge: 1, alert: 'Hi there!' } };
  75. });
  76. it('contains all original payload properties', function () {
  77. expect(compiledOutput()).to.have.property('foo', 'bar');
  78. expect(compiledOutput()).to.have.property('baz', 1);
  79. });
  80. it('does not contain the aps properties', function () {
  81. expect(compiledOutput()).to.not.have.property('aps');
  82. });
  83. });
  84. });
  85. describe('length', function () {
  86. it('returns the correct payload length', function () {
  87. note.alert = 'length';
  88. expect(note.length()).to.equal(26);
  89. });
  90. });
  91. describe('headers', function () {
  92. it('contains no properties by default', function () {
  93. expect(note.headers()).to.deep.equal({});
  94. });
  95. context('priority is non-default', function () {
  96. it('contains the apns-priority header', function () {
  97. note.priority = 5;
  98. expect(note.headers()).to.have.property('apns-priority', 5);
  99. });
  100. });
  101. context('id is set', function () {
  102. it('contains the apns-id header', function () {
  103. note.id = '123e4567-e89b-12d3-a456-42665544000';
  104. expect(note.headers()).to.have.property('apns-id', '123e4567-e89b-12d3-a456-42665544000');
  105. });
  106. });
  107. context('expiry is greater than zero', function () {
  108. it('contains the apns-expiration header', function () {
  109. note.expiry = 1000;
  110. expect(note.headers()).to.have.property('apns-expiration', 1000);
  111. });
  112. });
  113. context('expiry is zero', function () {
  114. it('contains the apns-expiration header', function () {
  115. note.expiry = 0;
  116. expect(note.headers()).to.have.property('apns-expiration', 0);
  117. });
  118. });
  119. context('expiry is negative', function () {
  120. it('not contains the apns-expiration header', function () {
  121. note.expiry = -1;
  122. expect(note.headers()).to.not.have.property('apns-expiration');
  123. });
  124. });
  125. context('topic is set', function () {
  126. it('contains the apns-topic header', function () {
  127. note.topic = 'io.apn.node';
  128. expect(note.headers()).to.have.property('apns-topic', 'io.apn.node');
  129. });
  130. });
  131. context('collapseId is set', function () {
  132. it('contains the apns-collapse-id header', function () {
  133. note.collapseId = 'io.apn.collapse';
  134. expect(note.headers()).to.have.property('apns-collapse-id', 'io.apn.collapse');
  135. });
  136. });
  137. context('pushType is set', function () {
  138. it('contains the apns-push-type header', function () {
  139. note.pushType = 'alert';
  140. expect(note.headers()).to.have.property('apns-push-type', 'alert');
  141. });
  142. });
  143. });
  144. describe('compile', function () {
  145. let stub;
  146. beforeEach(function () {
  147. stub = sinon.stub(note, 'toJSON');
  148. });
  149. it('compiles the JSON payload', function () {
  150. stub.returns('payload');
  151. expect(note.compile()).to.equal('"payload"');
  152. });
  153. it('returns the JSON payload', function () {
  154. stub.returns({});
  155. expect(note.compile()).to.equal('{}');
  156. });
  157. it('memoizes the JSON payload', function () {
  158. stub.returns('payload1');
  159. note.compile();
  160. stub.returns('payload2');
  161. expect(note.compile()).to.equal('"payload1"');
  162. });
  163. it('re-compiles the JSON payload when `note.compiled` = false', function () {
  164. stub.returns('payload1');
  165. note.compile();
  166. stub.returns('payload2');
  167. note.compiled = false;
  168. expect(note.compile()).to.equal('"payload2"');
  169. });
  170. });
  171. function compiledOutput() {
  172. return JSON.parse(note.compile());
  173. }
  174. });