|
|
|
|
@ -25,6 +25,7 @@ const createSelf = () =>
|
|
|
|
|
clients: {
|
|
|
|
|
claim: jest.fn(() => Promise.resolve()),
|
|
|
|
|
openWindow: jest.fn(() => Promise.resolve()),
|
|
|
|
|
matchAll: jest.fn(() => Promise.resolve([])),
|
|
|
|
|
},
|
|
|
|
|
}) as unknown as ServiceWorkerGlobalScope
|
|
|
|
|
|
|
|
|
|
@ -32,12 +33,16 @@ let originalWindow: Window & typeof globalThis
|
|
|
|
|
|
|
|
|
|
describe("service worker", () => {
|
|
|
|
|
let self: ServiceWorkerGlobalScope
|
|
|
|
|
let controlledClients: Client[]
|
|
|
|
|
let uncontrolledClients: Client[]
|
|
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
|
originalWindow = global.window
|
|
|
|
|
global.window = undefined as any
|
|
|
|
|
indexedDB = new IDBFactory()
|
|
|
|
|
self = createSelf()
|
|
|
|
|
controlledClients = []
|
|
|
|
|
uncontrolledClients = []
|
|
|
|
|
|
|
|
|
|
fetchMock.mockResponse((req) => {
|
|
|
|
|
if (
|
|
|
|
|
@ -94,28 +99,71 @@ describe("service worker", () => {
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("closes notification on click", async () => {
|
|
|
|
|
initWorker(self)
|
|
|
|
|
describe("on notification click", () => {
|
|
|
|
|
test("the notification is closed", async () => {
|
|
|
|
|
initWorker(self)
|
|
|
|
|
|
|
|
|
|
const notificationHandler = getHandler("notificationclick")
|
|
|
|
|
const notificationHandler = getHandler("notificationclick")
|
|
|
|
|
|
|
|
|
|
const event = createNotificationEvent("tackupnow.com")
|
|
|
|
|
notificationHandler(event)
|
|
|
|
|
await waitUntilCalls(event)
|
|
|
|
|
const event = createNotificationEvent("tackupnow.com")
|
|
|
|
|
notificationHandler(event)
|
|
|
|
|
await waitUntilCalls(event)
|
|
|
|
|
|
|
|
|
|
expect(event.notification.close).toHaveBeenCalled()
|
|
|
|
|
})
|
|
|
|
|
expect(event.notification.close).toHaveBeenCalled()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("opens tack up now on click", async () => {
|
|
|
|
|
initWorker(self)
|
|
|
|
|
test("opens tack up now if no clients match the destination", async () => {
|
|
|
|
|
initWorker(self)
|
|
|
|
|
|
|
|
|
|
const notificationHandler = getHandler("notificationclick")
|
|
|
|
|
const notificationHandler = getHandler("notificationclick")
|
|
|
|
|
|
|
|
|
|
const event = createNotificationEvent("tackupnow.com")
|
|
|
|
|
notificationHandler(event)
|
|
|
|
|
await waitUntilCalls(event)
|
|
|
|
|
const event = createNotificationEvent("tackupnow.com")
|
|
|
|
|
notificationHandler(event)
|
|
|
|
|
await waitUntilCalls(event)
|
|
|
|
|
|
|
|
|
|
expect(self.clients.openWindow).toHaveBeenCalledWith("tackupnow.com")
|
|
|
|
|
expect(self.clients.openWindow).toHaveBeenCalledWith("tackupnow.com")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("focuses first matching client", async () => {
|
|
|
|
|
addClient("https://tackupnow.com/place", "window", true)
|
|
|
|
|
const matchingClient = addClient(
|
|
|
|
|
"https://tackupnow.com/otherplace",
|
|
|
|
|
"window",
|
|
|
|
|
true
|
|
|
|
|
)
|
|
|
|
|
addClient("https://tackupnow.com/yetanotherotherplace", "window", true)
|
|
|
|
|
|
|
|
|
|
initWorker(self)
|
|
|
|
|
|
|
|
|
|
const notificationHandler = getHandler("notificationclick")
|
|
|
|
|
|
|
|
|
|
const event = createNotificationEvent("https://tackupnow.com/otherplace")
|
|
|
|
|
notificationHandler(event)
|
|
|
|
|
await waitUntilCalls(event)
|
|
|
|
|
|
|
|
|
|
expect(matchingClient.focus).toHaveBeenCalled()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("focuses uncontrolled matching clients", async () => {
|
|
|
|
|
addClient("https://derpatious.world", "window", false)
|
|
|
|
|
addClient("https://tackupnow.com/1", "window", false)
|
|
|
|
|
const matchingClient = addClient(
|
|
|
|
|
"https://tackupnow.com/2",
|
|
|
|
|
"window",
|
|
|
|
|
false
|
|
|
|
|
)
|
|
|
|
|
addClient("https://tackupnow.com/controlled", "window", true)
|
|
|
|
|
|
|
|
|
|
initWorker(self)
|
|
|
|
|
|
|
|
|
|
const notificationHandler = getHandler("notificationclick")
|
|
|
|
|
|
|
|
|
|
const event = createNotificationEvent("https://tackupnow.com/2")
|
|
|
|
|
notificationHandler(event)
|
|
|
|
|
await waitUntilCalls(event)
|
|
|
|
|
|
|
|
|
|
expect(matchingClient.focus).toHaveBeenCalled()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("claims on activate", async () => {
|
|
|
|
|
@ -287,6 +335,31 @@ describe("service worker", () => {
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function addClient(url: string, type: ClientTypes, controlled: boolean) {
|
|
|
|
|
const matchAllMock = self.clients.matchAll as jest.Mock
|
|
|
|
|
|
|
|
|
|
matchAllMock.mockImplementation(
|
|
|
|
|
(args: { type: string; includeUncontrolled?: boolean }) => {
|
|
|
|
|
const clientList = args.includeUncontrolled
|
|
|
|
|
? [...uncontrolledClients, ...controlledClients]
|
|
|
|
|
: controlledClients
|
|
|
|
|
return clientList.filter((client) => client.type === args.type)
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const clientList = controlled ? controlledClients : uncontrolledClients
|
|
|
|
|
|
|
|
|
|
const client: WindowClient = {
|
|
|
|
|
url,
|
|
|
|
|
type,
|
|
|
|
|
focus: jest.fn(() => Promise.resolve(client)) as WindowClient["focus"],
|
|
|
|
|
} as WindowClient
|
|
|
|
|
|
|
|
|
|
clientList.push(client)
|
|
|
|
|
|
|
|
|
|
return client
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getHandler(eventName: string) {
|
|
|
|
|
expect(self.addEventListener).toHaveBeenCalledWith(
|
|
|
|
|
eventName,
|
|
|
|
|
|