Skip to content

Commit db96ff4

Browse files
committed
Properly sync status between background and foreground
1 parent f81b222 commit db96ff4

File tree

7 files changed

+96
-33
lines changed

7 files changed

+96
-33
lines changed

__mocks__/webextension-polyfill.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ export const storage: DeepPartial<Storage.Static> = {
3030
storedValues = {};
3131
return Promise.resolve;
3232
}),
33+
onChanged: {
34+
addListener: jest.fn(),
35+
},
3336
},
3437
};
3538

src/background.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import ErrorHandler from "./utils/ErrorHandler";
77

88
async function init() {
99
const badgeNumberManager = await BadgeNumberManager.init();
10-
badgeNumberManager.startStorageChangeListener();
10+
badgeNumberManager.startListeners();
1111
const ntfyNotificationManager =
1212
await NtfyNotificationManager.init(badgeNumberManager);
1313
const browserNotificationManager = new BrowserNotificationManager();

src/popup.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const Popup = () => {
2020
useEffect(() => {
2121
BadgeNumberManager.init()
2222
.then((badgeManager) => {
23-
badgeManager.startStorageChangeListener();
23+
badgeManager.startListeners();
2424
setBadgeNumberManager(badgeManager);
2525

2626
return NtfyNotificationManager.init(badgeManager);
@@ -73,5 +73,5 @@ const root = createRoot(rootElement);
7373
root.render(
7474
<React.StrictMode>
7575
<Popup />
76-
</React.StrictMode>,
76+
</React.StrictMode>
7777
);

src/utils/BadgeNumberManager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ export default class BadgeNumberManager implements BadgeNumberManagerInterface {
1414

1515
private constructor() {}
1616

17-
static async init() {
18-
if (BadgeNumberManager.instance) {
17+
static async init(reset = false) {
18+
if (!reset && BadgeNumberManager.instance) {
1919
return BadgeNumberManager.instance;
2020
}
2121
BadgeNumberManager.instance = new BadgeNumberManager();
@@ -73,7 +73,7 @@ export default class BadgeNumberManager implements BadgeNumberManagerInterface {
7373
return await action.setBadgeText({ text });
7474
}
7575

76-
startStorageChangeListener() {
76+
startListeners() {
7777
storage.local.onChanged.addListener((changes) => {
7878
const newValue = changes[BADGE_NUMBER_MANAGER_STORAGE_KEY]?.newValue;
7979
if (!newValue) return;

src/utils/NtfyNotificationManager.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,12 @@ export default class NtfyNotificationManager {
148148
await this.badgeNumberManager.lower();
149149
}
150150
});
151+
152+
storage.local.onChanged.addListener((changes) => {
153+
const newValue = changes[NTFY_NOTIFICATION_MANAGER_STORAGE_KEY]?.newValue;
154+
if (!newValue) return;
155+
156+
this.notificationCache = newValue.notificationCache;
157+
});
151158
}
152159
}
Lines changed: 78 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
jest.mock("webextension-polyfill");
22

3-
import { action } from "webextension-polyfill";
3+
import { action, storage } from "webextension-polyfill";
4+
import { BADGE_NUMBER_MANAGER_STORAGE_KEY } from "../constants";
45

56
type BadgeNumberManagerImport = typeof import("../BadgeNumberManager");
67

@@ -9,6 +10,7 @@ describe("BadgeNumberManager", () => {
910

1011
beforeEach(() => {
1112
jest.clearAllMocks();
13+
storage.local.clear();
1214

1315
jest.isolateModules(() => {
1416
const module = jest.requireActual<BadgeNumberManagerImport>(
@@ -19,51 +21,103 @@ describe("BadgeNumberManager", () => {
1921
});
2022

2123
it("is a singleton", async () => {
22-
const badgeNumberManager1 = await BadgeNumberManager.init();
24+
const badgeNumberManager1 = await BadgeNumberManager.init(true);
2325
const badgeNumberManager2 = await BadgeNumberManager.init();
2426

2527
expect(badgeNumberManager1).toBe(badgeNumberManager2);
2628
});
2729

28-
it("can higher the badge text", async () => {
29-
const badgeNumberManager = await BadgeNumberManager.init();
30+
it("restores values from storage", async () => {
31+
await storage.local.set({
32+
[BADGE_NUMBER_MANAGER_STORAGE_KEY]: {
33+
currentNumber: 2,
34+
},
35+
});
3036

37+
const badgeNumberManager = await BadgeNumberManager.init(true);
3138
await badgeNumberManager.higher();
3239
expect(action.setBadgeText).toHaveBeenNthCalledWith(1, {
33-
text: "1",
40+
text: "3",
3441
});
42+
});
3543

36-
await badgeNumberManager.higher();
37-
expect(action.setBadgeText).toHaveBeenNthCalledWith(2, {
38-
text: "2",
44+
describe("higher", () => {
45+
it("can higher the badge text", async () => {
46+
const badgeNumberManager = await BadgeNumberManager.init(true);
47+
48+
await badgeNumberManager.higher();
49+
expect(action.setBadgeText).toHaveBeenNthCalledWith(1, {
50+
text: "1",
51+
});
52+
53+
await badgeNumberManager.higher();
54+
expect(action.setBadgeText).toHaveBeenNthCalledWith(2, {
55+
text: "2",
56+
});
57+
});
58+
59+
it("stores the new value", async () => {
60+
const badgeNumberManager = await BadgeNumberManager.init(true);
61+
62+
await badgeNumberManager.higher();
63+
expect(storage.local.set).toHaveBeenCalledTimes(1);
64+
expect(storage.local.set).toHaveBeenCalledWith({
65+
[BADGE_NUMBER_MANAGER_STORAGE_KEY]: { currentNumber: 1 },
66+
});
3967
});
4068
});
4169

42-
it("can lower the badge text", async () => {
43-
const badgeNumberManager = await BadgeNumberManager.init();
70+
describe("lower", () => {
71+
it("can lower the badge text", async () => {
72+
const badgeNumberManager = await BadgeNumberManager.init(true);
4473

45-
await badgeNumberManager.higher();
46-
await badgeNumberManager.higher();
74+
await badgeNumberManager.higher();
75+
await badgeNumberManager.higher();
4776

48-
await badgeNumberManager.lower();
49-
expect(action.setBadgeText).toHaveBeenNthCalledWith(3, {
50-
text: "1",
77+
await badgeNumberManager.lower();
78+
expect(action.setBadgeText).toHaveBeenNthCalledWith(3, {
79+
text: "1",
80+
});
81+
82+
await badgeNumberManager.lower();
83+
expect(action.setBadgeText).toHaveBeenNthCalledWith(4, {
84+
text: "",
85+
});
5186
});
5287

53-
await badgeNumberManager.lower();
54-
expect(action.setBadgeText).toHaveBeenNthCalledWith(4, {
55-
text: "",
88+
it("stores the new value", async () => {
89+
const badgeNumberManager = await BadgeNumberManager.init(true);
90+
91+
await badgeNumberManager.higher();
92+
await badgeNumberManager.lower();
93+
expect(storage.local.set).toHaveBeenCalledTimes(2);
94+
expect(storage.local.set).toHaveBeenNthCalledWith(2, {
95+
[BADGE_NUMBER_MANAGER_STORAGE_KEY]: { currentNumber: 0 },
96+
});
5697
});
5798
});
5899

59-
it("can reset the badge text", async () => {
60-
const badgeNumberManager = await BadgeNumberManager.init();
100+
describe("reset", () => {
101+
it("can reset the badge text", async () => {
102+
const badgeNumberManager = await BadgeNumberManager.init(true);
61103

62-
await badgeNumberManager.higher();
104+
await badgeNumberManager.higher();
105+
106+
await badgeNumberManager.reset();
107+
expect(action.setBadgeText).toHaveBeenNthCalledWith(2, {
108+
text: "",
109+
});
110+
});
111+
112+
it("stores the new value", async () => {
113+
const badgeNumberManager = await BadgeNumberManager.init(true);
63114

64-
await badgeNumberManager.reset();
65-
expect(action.setBadgeText).toHaveBeenNthCalledWith(2, {
66-
text: "",
115+
await badgeNumberManager.higher();
116+
await badgeNumberManager.reset();
117+
expect(storage.local.set).toHaveBeenCalledTimes(2);
118+
expect(storage.local.set).toHaveBeenNthCalledWith(2, {
119+
[BADGE_NUMBER_MANAGER_STORAGE_KEY]: { currentNumber: 0 },
120+
});
67121
});
68122
});
69123
});

src/utils/__tests__/NtfyNotificationManager.spec.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,8 @@ describe("NtfyNotificationManager", () => {
107107
it("adds the notification to storage", async () => {
108108
await ntfyNotificationManager.publish(ntfyNotificationMinimal);
109109

110-
expect(
111-
await storage.local.get([NTFY_NOTIFICATION_MANAGER_STORAGE_KEY])
112-
).toEqual({
110+
expect(storage.local.set).toHaveBeenCalledTimes(1);
111+
expect(storage.local.set).toHaveBeenCalledWith({
113112
[NTFY_NOTIFICATION_MANAGER_STORAGE_KEY]: {
114113
notificationCache: [ntfyNotificationMinimal],
115114
},

0 commit comments

Comments
 (0)