mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-28 00:16:48 +09:00
The browser is shared across system tests, and a script added to every
new document stays until it's removed, so later tests would have seen
the granted permission and the fake subscription too.
From #371.
(cherry picked from commit 1af62a5bff)
76 lines
3.0 KiB
Ruby
76 lines
3.0 KiB
Ruby
require "application_system_test_case"
|
|
|
|
class PushSubscriptionResyncTest < ApplicationSystemTestCase
|
|
ENDPOINT = "https://fcm.googleapis.com/fcm/send/system-test"
|
|
|
|
setup do
|
|
stub_web_push_dns_resolution
|
|
fake_a_browser_push_subscription
|
|
end
|
|
|
|
teardown do
|
|
page.driver.browser.execute_cdp "Page.removeScriptToEvaluateOnNewDocument", identifier: @fake_subscription_script
|
|
page.execute_script("localStorage.clear()") if page.current_url.start_with?("http")
|
|
end
|
|
|
|
test "a browser posts its subscription again once per session, so it survives a password change" do
|
|
sign_in "david@37signals.com"
|
|
assert_subscription_registered
|
|
first_sync = subscription.updated_at
|
|
|
|
join_room rooms(:hq)
|
|
assert_equal first_sync, subscription.reload.updated_at, "posted again in the same session"
|
|
|
|
change_password
|
|
assert_nil Push::Subscription.find_by(endpoint: ENDPOINT)
|
|
|
|
join_room rooms(:hq)
|
|
assert_subscription_registered
|
|
assert_not page.evaluate_script("localStorage.getItem('unsubscribed-for-test')")
|
|
end
|
|
|
|
test "a subscription the server refuses stays in the browser" do
|
|
stub_dns_resolution("169.254.169.254")
|
|
|
|
sign_in "david@37signals.com"
|
|
Timeout.timeout(5) { sleep 0.1 until page.evaluate_script("localStorage.getItem('push-subscription-synced-session')") }
|
|
join_room rooms(:hq)
|
|
|
|
assert_not Push::Subscription.exists?(endpoint: ENDPOINT)
|
|
assert_not page.evaluate_script("localStorage.getItem('unsubscribed-for-test')")
|
|
end
|
|
|
|
private
|
|
# Headless Chrome has no push service, so stand in for the subscription the service worker would hold. The
|
|
# browser is shared with other system tests, so teardown removes this again.
|
|
def fake_a_browser_push_subscription
|
|
@fake_subscription_script = page.driver.browser.execute_cdp("Page.addScriptToEvaluateOnNewDocument", source: <<~JS)["identifier"]
|
|
(() => {
|
|
Object.defineProperty(Notification, "permission", { get: () => "granted" })
|
|
const subscription = {
|
|
toJSON: () => ({ endpoint: "#{ENDPOINT}", keys: { p256dh: "p256dh-key", auth: "auth-key" } }),
|
|
unsubscribe: async () => { localStorage.setItem("unsubscribed-for-test", "true") }
|
|
}
|
|
navigator.serviceWorker.getRegistration = async () => ({ pushManager: { getSubscription: async () => subscription } })
|
|
})()
|
|
JS
|
|
end
|
|
|
|
def change_password
|
|
visit user_profile_url
|
|
find("input[name='user[password_challenge]']").fill_in with: "secret123456"
|
|
find("input[name='user[password]']").fill_in with: "a new secret123456"
|
|
find("input[name='user[password]']").send_keys :enter
|
|
assert_selector ".flash", text: "✓"
|
|
end
|
|
|
|
def assert_subscription_registered
|
|
assert_selector "[data-controller~=notifications]", visible: :all
|
|
Timeout.timeout(5) { sleep 0.1 until Push::Subscription.exists?(endpoint: ENDPOINT, user: users(:david)) }
|
|
end
|
|
|
|
def subscription
|
|
Push::Subscription.find_by!(endpoint: ENDPOINT)
|
|
end
|
|
end
|