2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-04 01:15:08 +08:00
discourse/spec/system/mobile_mode_spec.rb
Régis Hanol b109922acd
FIX: topic-navigation crash when viewport crosses mobile/desktop threshold (#36590)
When `viewport_based_mobile_mode` is enabled, `site.mobileView` and
`site.desktopView` are dynamic - they change in real-time as the browser
window is resized across the 640px threshold.

The `topic-navigation` component was written assuming these values are
static. It set up desktop-specific listeners (mediaQuery, composer
events) only if `site.desktopView` was true at insertion time, but
checked `site.desktopView` again at teardown to decide whether to remove
them.

This caused a crash when:
1. Component inserted in mobile view (desktop listeners not set up)
2. User resizes to desktop (site.desktopView becomes true)
3. User navigates away (teardown tries to remove non-existent listeners)

The fix tracks which listeners were actually set up using
`_desktopListenersActive` and `_mobileListenersActive` flags, and uses
these flags in teardown instead of re-checking the current viewport
state.

Internal ref - t/170549
2025-12-10 17:26:23 +01:00

49 lines
1.5 KiB
Ruby

# frozen_string_literal: true
RSpec.describe "Viewport-based mobile mode", type: :system do
before { SiteSetting.viewport_based_mobile_mode = true }
it "has both stylesheets, and updates classes at runtime" do
visit "/"
mobile_stylesheet = find("link[rel=stylesheet][href*='stylesheets/mobile']", visible: false)
desktop_stylesheet = find("link[rel=stylesheet][href*='stylesheets/desktop']", visible: false)
expect(mobile_stylesheet["media"]).to include("max-width")
expect(desktop_stylesheet["media"]).to include("min-width")
expect(page).to have_css("html.desktop-view")
expect(page).not_to have_css("html.mobile-view")
resize_window(width: 400) do
expect(page).to have_css("html.mobile-view")
expect(page).not_to have_css("html.desktop-view")
end
end
context "when resizing viewport while on a topic page" do
fab!(:topic)
fab!(:post) { Fabricate(:post, topic:) }
it "handles navigation after resize from mobile to desktop" do
resize_window(width: 400) do
visit "/t/#{topic.slug}/#{topic.id}"
expect(page).to have_css("html.mobile-view")
end
click_logo
expect(page).to have_css(".topic-list")
end
it "handles navigation after resize from desktop to mobile" do
visit "/t/#{topic.slug}/#{topic.id}"
expect(page).to have_css("html.desktop-view")
resize_window(width: 400) do
expect(page).to have_css("html.mobile-view")
click_logo
expect(page).to have_css(".topic-list")
end
end
end
end