Replace vapid key that accidentally got committed, show notifications in app
Test / test (push) Successful in 1m2s Details

This commit is contained in:
Jeff 2024-10-19 19:20:51 -04:00
parent e9c7d7a8ef
commit 37f32cce3a
6 changed files with 111 additions and 82 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ build/
/playwright-report/
/blob-report/
/playwright/.cache/
send-it.js

View File

@ -20,9 +20,11 @@ const createSelf = () =>
subscribe: jest.fn(() => Promise.resolve(createSubscription())),
getSubscription: jest.fn(() => Promise.resolve(createSubscription())),
},
showNotification: jest.fn(),
},
clients: {
claim: jest.fn(() => Promise.resolve()),
openWindow: jest.fn(() => Promise.resolve()),
},
}) as unknown as ServiceWorkerGlobalScope
@ -37,28 +39,25 @@ describe("service worker", () => {
indexedDB = new IDBFactory()
self = createSelf()
// fetchMock.mockIf(/http:\/\/localhost\/api\/subscribe\/?/, (req) => {
// return Promise.resolve(
// req.method === "POST"
// ? {
// body: JSON.stringify({ subscriptionId: 123 }),
// }
// : req.method === "PUT"
// ? { init: { status: 200 } }
// : { init: { status: 405 } }
// )
// })
fetchMock.mockResponse((req) => {
return Promise.resolve(
if (
req.url.replace(/https?:\/\/[a-zA-Z0-9\.]*/, "") ===
"/api/subscription/" &&
req.method === "POST"
? {
body: JSON.stringify({ subscriptionId: 123 }),
}
: req.method === "PUT"
? { init: { status: 200 } }
: { init: { status: 405 } }
)
) {
return Promise.resolve({
body: JSON.stringify({ subscriptionId: 123 }),
})
} else if (
req.url
.replace(/https?:\/\/[a-zA-Z0-9\.]*/, "")
.startsWith("/api/subscription/") &&
req.method === "PUT"
) {
return Promise.resolve({ init: { status: 200 } })
}
return Promise.resolve({ init: { status: 500 } })
})
})
@ -67,13 +66,56 @@ describe("service worker", () => {
global.window = originalWindow
})
xtest("displays push notifications", () => {
test("displays push notifications", async () => {
initWorker(self)
const pushHandler = getHandler("push")
const pushEvent = createEvent({ data: "HI" })
const pushEvent = createPushEvent(
JSON.stringify({
title: "Test title",
body: "Test text",
icon: "Test icon",
badge: "Test badge",
destination: "tackupnow.com/hi",
})
)
pushHandler(pushEvent)
await waitUntilCalls(pushEvent)
expect(self.registration.showNotification).toHaveBeenCalledWith(
"Test title",
{
body: "Test text",
icon: "Test icon",
badge: "Test badge",
data: { destination: "tackupnow.com/hi" },
}
)
})
test("closes notification on click", async () => {
initWorker(self)
const notificationHandler = getHandler("notificationclick")
const event = createNotificationEvent("tackupnow.com")
notificationHandler(event)
await waitUntilCalls(event)
expect(event.notification.close).toHaveBeenCalled()
})
test("opens tack up now on click", async () => {
initWorker(self)
const notificationHandler = getHandler("notificationclick")
const event = createNotificationEvent("tackupnow.com")
notificationHandler(event)
await waitUntilCalls(event)
expect(self.clients.openWindow).toHaveBeenCalledWith("tackupnow.com")
})
test("claims on activate", async () => {
@ -292,8 +334,19 @@ function createPushEvent(data: string) {
return createEvent(pushFields)
}
function createMessageEvent(message: any) {
return createEvent({ data: message })
function createNotificationEvent(destination: string): NotificationEvent & {
waitUntil: jest.Mock<void, Parameters<ExtendableEvent["waitUntil"]>>
} {
return createEvent({
notification: {
close: jest.fn(),
data: {
destination,
},
},
}) as any as NotificationEvent & {
waitUntil: jest.Mock<void, Parameters<ExtendableEvent["waitUntil"]>>
}
}
function createEvent(properties?: object) {

View File

@ -16,29 +16,26 @@ export default function start(self: ServiceWorkerGlobalScope) {
event.waitUntil(self.clients.claim())
})
// self.addEventListener("push", function (event: PushEvent) {
// console.log("[Service Worker] Push Received.")
// console.log(`[Service Worker] Push had this data: "${event.data?.text()}"`)
self.addEventListener("push", function (event: PushEvent) {
const { title, body, badge, icon, destination } = event.data?.json()
// const title = "Push Codelab"
// const options = {
// body: "Yay it works.",
// icon: "images/icon.png",
// badge: "images/badge.png",
// }
event.waitUntil(
self.registration.showNotification(title, {
body,
badge,
icon,
data: { destination },
})
)
})
// event.waitUntil(self.registration.showNotification(title, options))
// })
self.addEventListener("notificationclick", function (event) {
event.notification.close()
// self.addEventListener("notificationclick", function (event) {
// console.log("[Service Worker] Notification click Received.")
// event.notification.close()
// event.waitUntil(
// self.clients.openWindow("https://developers.google.com/web/")
// )
// })
event.waitUntil(
self.clients.openWindow(event.notification.data.destination)
)
})
self.addEventListener("message", function (event) {
const waitEvent = event as ExtendableEvent

30
package-lock.json generated
View File

@ -31,7 +31,7 @@
"@babel/preset-env": "^7.24.5",
"@babel/preset-react": "^7.24.1",
"@babel/preset-typescript": "^7.24.1",
"@playwright/test": "^1.44.1",
"@playwright/test": "^1.48.1",
"@remix-pwa/dev": "^3.1.0",
"@remix-run/dev": "^2.9.0",
"@remix-run/testing": "^2.9.1",
@ -3324,18 +3324,18 @@
}
},
"node_modules/@playwright/test": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz",
"integrity": "sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==",
"version": "1.48.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.1.tgz",
"integrity": "sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==",
"dev": true,
"dependencies": {
"playwright": "1.44.1"
"playwright": "1.48.1"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=16"
"node": ">=18"
}
},
"node_modules/@remix-pwa/dev": {
@ -13843,33 +13843,33 @@
}
},
"node_modules/playwright": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz",
"integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==",
"version": "1.48.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.1.tgz",
"integrity": "sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==",
"dev": true,
"dependencies": {
"playwright-core": "1.44.1"
"playwright-core": "1.48.1"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=16"
"node": ">=18"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/playwright-core": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz",
"integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==",
"version": "1.48.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.1.tgz",
"integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==",
"dev": true,
"bin": {
"playwright-core": "cli.js"
},
"engines": {
"node": ">=16"
"node": ">=18"
}
},
"node_modules/playwright/node_modules/fsevents": {

View File

@ -1 +1 @@
export default "BKc02U2-z7PkTbYgYLlxELWqzTVE631fs4IPuMLbxY_rxdo9VaduthqwkPOiblwjETl99uXes2Nc9EtPbS5x4uA"
export default "BLoc3g9yZAgSB1HRwolI4NcGUaJRFhLKtf2Ys3Jcbtsr8yKsoCLldc4ynADLTGMbihTYbIKS8PdSHEKDGkCR4fI"

View File

@ -1,22 +0,0 @@
import webPush from "web-push"
const subscription = {
endpoint:
"https://updates.push.services.mozilla.com/wpush/v2/gAAAAABm9FlbY5vMro60hF2iJF3UUBzweuFcg5NRSHXPSpHfUpjo5jKGVRnUxR4ekg0-FsvdQCP89cu__IFd06Tu2TJZ649YyqivRUBnAav0DgOLHGx5-t943QLS-wLvBqyJRCuuLlM1bLz6S9ph9AWJ8CG7rQuTabsHvw--s_w2KDQo3GcQXIM",
expirationTime: null,
keys: {
auth: "dDUqtFo26ekGEAmNzvmJAw",
p256dh:
"BHIT3J6xSRiHfz0m-QRHagDThiOZGVIANtPzOasrOBYG0s_yUnshTVharX5dZcq8GA5OkyMm3mqmA7_o_lFR4WE",
},
}
webPush.setVapidDetails(
"https://tackupnow.com",
"BKc02U2-z7PkTbYgYLlxELWqzTVE631fs4IPuMLbxY_rxdo9VaduthqwkPOiblwjETl99uXes2Nc9EtPbS5x4uA",
"Xmv5Pc4mqr138V3sCxXq7UmsbL5UgSOY43UuJ50nxPw"
)
webPush
.sendNotification(subscription, "Hi what's up?", {})
.then((x) => console.log("It sent", x))
.catch((error) => console.log("It did not send", error))