ASRouterTargeting.test.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import {ASRouterTargeting, CachedTargetingGetter} from "lib/ASRouterTargeting.jsm";
  2. import {OnboardingMessageProvider} from "lib/OnboardingMessageProvider.jsm";
  3. // Note that tests for the ASRouterTargeting environment can be found in
  4. // test/functional/mochitest/browser_asrouter_targeting.js
  5. describe("#CachedTargetingGetter", () => {
  6. const sixHours = 6 * 60 * 60 * 1000;
  7. let sandbox;
  8. let clock;
  9. let frecentStub;
  10. let topsitesCache;
  11. beforeEach(() => {
  12. sandbox = sinon.createSandbox();
  13. clock = sinon.useFakeTimers();
  14. frecentStub = sandbox.stub(global.NewTabUtils.activityStreamProvider, "getTopFrecentSites");
  15. sandbox.stub(global.Cu, "reportError");
  16. topsitesCache = new CachedTargetingGetter("getTopFrecentSites");
  17. });
  18. afterEach(() => {
  19. sandbox.restore();
  20. clock.restore();
  21. });
  22. it("should only make a request every 6 hours", async () => {
  23. frecentStub.resolves();
  24. clock.tick(sixHours);
  25. await topsitesCache.get();
  26. await topsitesCache.get();
  27. assert.calledOnce(global.NewTabUtils.activityStreamProvider.getTopFrecentSites);
  28. clock.tick(sixHours);
  29. await topsitesCache.get();
  30. assert.calledTwice(global.NewTabUtils.activityStreamProvider.getTopFrecentSites);
  31. });
  32. it("should report errors", async () => {
  33. frecentStub.rejects(new Error("fake error"));
  34. clock.tick(sixHours);
  35. // assert.throws expect a function as the first parameter, try/catch is a
  36. // workaround
  37. try {
  38. await topsitesCache.get();
  39. assert.isTrue(false);
  40. } catch (e) {
  41. assert.calledOnce(global.Cu.reportError);
  42. }
  43. });
  44. it("should check targeted message before message without targeting", async () => {
  45. const messages = (await OnboardingMessageProvider.getUntranslatedMessages());
  46. const stub = sandbox.stub(ASRouterTargeting, "checkMessageTargeting").resolves();
  47. const context = {attributionData: {campaign: "non-fx-button", source: "addons.mozilla.org"}};
  48. await ASRouterTargeting.findMatchingMessage({messages, trigger: {id: "firstRun"}, context});
  49. assert.equal(stub.callCount, 6);
  50. const calls = stub.getCalls().map(call => call.args[0]);
  51. const lastCall = calls[calls.length - 1];
  52. assert.equal(lastCall.id, "FXA_1");
  53. });
  54. it("should return FxA message (is fallback)", async () => {
  55. const messages = (await OnboardingMessageProvider.getUntranslatedMessages())
  56. .filter(m => m.id !== "RETURN_TO_AMO_1");
  57. const context = {attributionData: {campaign: "non-fx-button", source: "addons.mozilla.org"}};
  58. const result = await ASRouterTargeting.findMatchingMessage({messages, trigger: {id: "firstRun"}, context});
  59. assert.isDefined(result);
  60. assert.equal(result.id, "FXA_1");
  61. });
  62. describe("combineContexts", () => {
  63. it("should combine the properties of the two objects", () => {
  64. const joined = ASRouterTargeting.combineContexts({
  65. get foo() { return "foo"; },
  66. }, {
  67. get bar() { return "bar"; },
  68. });
  69. assert.propertyVal(joined, "foo", "foo");
  70. assert.propertyVal(joined, "bar", "bar");
  71. });
  72. it("should warn when properties overlap", () => {
  73. ASRouterTargeting.combineContexts({
  74. get foo() { return "foo"; },
  75. }, {
  76. get foo() { return "bar"; },
  77. });
  78. assert.calledOnce(global.Cu.reportError);
  79. });
  80. });
  81. });