mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-27 07:56: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.
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
|