diff --git a/CHANGELOG.md b/CHANGELOG.md index d60cf744..1828078f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ | Version | Description | |---------|-------------| +| | Adds a signal to update the achievements indicator when a notification has been fired. | | | 2.0.12 | | | | Adjust results screen achievements button position for iPhone 5. | | | | Fix button area padding for iPhone 5 | | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a9f56c2f..b55989e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,17 +10,17 @@ Issues should include: 3. What you did to reproduce the issue 4. Device/Browser details -Ideally screenshots would also be helpful. +Ideally screenshots would also be helpful. ### Pull Requests -We do not accept direct commits to the code base. +We do not accept direct commits to the code base. Any code contributions must: 1. Be submitted via Pull Requests. 2. Include unit tests for any code amended. -3. Include summary of what was changed and why in the Pull Request. +3. Include summary of what was changed and why in the Pull Request. 4. Pass the Pull Request Build. 5. NOT include version number changes diff --git a/jest.config.js b/jest.config.js index 6da6ef45..2043baee 100644 --- a/jest.config.js +++ b/jest.config.js @@ -7,18 +7,30 @@ module.exports = { collectCoverageFrom: ["src/**/*.js", "!src/components/test-harness/**/*.js", "!src/output/**/*.js"], coverageThreshold: { global: { - statements: 94.34, - branches: 87.74, - lines: 95.25, - functions: 90.8, + statements: 97.71, + branches: 90.66, + lines: 97.98, + functions: 96.39, }, "src/core/layout/gel-button.js": { + statements: 9.09, + branches: 0, + lines: 10.26, + functions: 0, + }, + "src/core/layout/debug-button.js": { statements: 0, branches: 0, lines: 0, functions: 0, }, - "src/core/layout/debug-button.js": { + "src/core/startup.js": { + statements: 67.74, + branches: 68.42, + lines: 71.19, + functions: 41.18, + }, + "src/main.js": { statements: 0, branches: 0, lines: 0, diff --git a/src/components/loadscreen.js b/src/components/loadscreen.js index 67bc4482..1467050b 100644 --- a/src/components/loadscreen.js +++ b/src/components/loadscreen.js @@ -14,6 +14,8 @@ import { createLoadBar } from "./loadbar.js"; import * as Scaler from "../core/scaler.js"; import * as GameSound from "../core/game-sound.js"; import { gmi } from "../core/gmi/gmi.js"; +import { achievementsChannel } from "../core/layout/gel-defaults.js"; +import * as signal from "../core/signal-bus.js"; const MASTER_PACK_KEY = "MasterAssetPack"; const GEL_PACK_KEY = "GelAssetPack"; @@ -50,7 +52,10 @@ export class Loadscreen extends Screen { GameSound.setButtonClickSound(this.game, "loadscreen.buttonClick"); if (this.context.config.theme.game && this.context.config.theme.game.achievements === true) { - gmi.achievements.init(this.game.cache.getJSON("achievementsData")); + const achievementsCallBack = () => { + signal.bus.publish({ channel: achievementsChannel, name: "achievement-notification-close" }); + }; + gmi.achievements.init(this.game.cache.getJSON("achievementsData"), achievementsCallBack); } gmi.sendStatsEvent("gameloaded", "true"); gmi.gameLoaded(); diff --git a/src/components/results.js b/src/components/results.js index 5f947c99..16ecfc1d 100644 --- a/src/components/results.js +++ b/src/components/results.js @@ -3,7 +3,7 @@ * @author BBC Children's D+E * @license Apache-2.0 */ -import { buttonsChannel } from "../core/layout/gel-defaults.js"; +import { buttonsChannel, achievementsChannel } from "../core/layout/gel-defaults.js"; import { Screen } from "../core/screen.js"; import * as signal from "../core/signal-bus.js"; import { createTestHarnessDisplay } from "./test-harness/layout-harness.js"; @@ -59,5 +59,13 @@ export class Results extends Screen { this.navigation.game(this.transientData); }, }); + + signal.bus.subscribe({ + name: "achievement-notification-close", + channel: achievementsChannel, + callback: () => { + this.scene.getLayouts()[0].buttons.achievements.setIndicator(); + }, + }); } } diff --git a/src/core/layout/gel-defaults.js b/src/core/layout/gel-defaults.js index 390f2cb8..fe251559 100644 --- a/src/core/layout/gel-defaults.js +++ b/src/core/layout/gel-defaults.js @@ -16,6 +16,8 @@ const pushLevelId = (game, params) => { }; export const buttonsChannel = "gel-buttons"; +export const achievementsChannel = "achievements"; + export const config = { exit: { group: "topLeft", diff --git a/test/components/loadscreen.test.js b/test/components/loadscreen.test.js index 3bee5475..7fc6f77b 100644 --- a/test/components/loadscreen.test.js +++ b/test/components/loadscreen.test.js @@ -11,6 +11,8 @@ import * as LoadBar from "../../src/components/loadbar"; import * as AssetLoader from "../../src/core/asset-loader"; import * as Scaler from "../../src/core/scaler.js"; import * as GameSound from "../../src/core/game-sound"; +import { achievementsChannel } from "../../src/core/layout/gel-defaults.js"; +import * as signal from "../../src/core/signal-bus.js"; describe("Load Screen", () => { let loadScreen; @@ -41,7 +43,7 @@ describe("Load Screen", () => { sound: { mute: false }, scale: { getParentBounds: jest.fn(), setGameSize: jest.fn() }, cache: { - getJSON: jest.fn(), + getJSON: jest.fn().mockImplementation(() => "game JSON data"), }, }; @@ -211,7 +213,7 @@ describe("Load Screen", () => { loadScreen.preload(); assetLoaderCallbackSpy.mock.calls[0][0](); - expect(mockGmi.achievements.init).toHaveBeenCalled(); + expect(mockGmi.achievements.init.mock.calls[0][0]).toBe("game JSON data"); }); test("does not call achievements init when achievements config flag is falsy", () => { @@ -221,5 +223,19 @@ describe("Load Screen", () => { expect(mockGmi.achievements.init).not.toHaveBeenCalled(); }); + + test("publishes a signal when a notification has fired", () => { + jest.spyOn(signal.bus, "publish"); + mockContext.config.theme.game.achievements = true; + loadScreen.context = mockContext; + loadScreen.preload(); + assetLoaderCallbackSpy.mock.calls[0][0](); + mockGmi.achievements.init.mock.calls[0][1](); + + expect(signal.bus.publish).toHaveBeenCalledWith({ + channel: achievementsChannel, + name: "achievement-notification-close", + }); + }); }); }); diff --git a/test/components/results.test.js b/test/components/results.test.js index e372c534..d82056a4 100644 --- a/test/components/results.test.js +++ b/test/components/results.test.js @@ -8,12 +8,14 @@ import { createMockGmi } from "../mock/gmi"; import { Results } from "../../src/components/results"; import * as layoutHarness from "../../src/components/test-harness/layout-harness.js"; import * as signal from "../../src/core/signal-bus.js"; +import { buttonsChannel, achievementsChannel } from "../../src/core/layout/gel-defaults.js"; describe("Results Screen", () => { let resultsScreen; let mockGame; let mockContext; let mockGmi; + let mockAchievementButton; beforeEach(() => { jest.spyOn(layoutHarness, "createTestHarnessDisplay").mockImplementation(() => {}); @@ -44,10 +46,13 @@ describe("Results Screen", () => { mockGmi = { sendStatsEvent: jest.fn() }; createMockGmi(mockGmi); + mockAchievementButton = { buttons: { achievements: { setIndicator: jest.fn() } } }; + resultsScreen = new Results(); resultsScreen.scene = { addToBackground: jest.fn(), addLayout: jest.fn(), + getLayouts: jest.fn().mockImplementation(() => [mockAchievementButton]), }; resultsScreen.game = mockGame; resultsScreen.context = mockContext; @@ -147,6 +152,7 @@ describe("Results Screen", () => { describe("the continue button", () => { test("adds a signal subscription", () => { expect(signal.bus.subscribe.mock.calls[0][0].name).toBe("continue"); + expect(signal.bus.subscribe.mock.calls[0][0].channel).toBe(buttonsChannel); }); test("navigates to the next screen when clicked", () => { @@ -158,6 +164,7 @@ describe("Results Screen", () => { describe("the restart button", () => { test("adds a signal subscription", () => { expect(signal.bus.subscribe.mock.calls[1][0].name).toBe("restart"); + expect(signal.bus.subscribe.mock.calls[1][0].channel).toBe(buttonsChannel); }); test("restarts the game and passes saved data through", () => { @@ -165,5 +172,18 @@ describe("Results Screen", () => { expect(resultsScreen.navigation.game).toHaveBeenCalledWith({ characterSelected: 1, results: 22 }); }); }); + + describe("achievement notification closed", () => { + test("adds a signal subscription", () => { + expect(signal.bus.subscribe.mock.calls[2][0].name).toBe("achievement-notification-close"); + expect(signal.bus.subscribe.mock.calls[2][0].channel).toBe(achievementsChannel); + }); + + test("updates the seen/unseen notification indicator on the achievements button", () => { + signal.bus.subscribe.mock.calls[2][0].callback(); + const { setIndicator } = mockAchievementButton.buttons.achievements; + expect(setIndicator).toHaveBeenCalled(); + }); + }); }); });