diff --git a/app/services/browser_support.rb b/app/services/browser_support.rb index c3847acd7d3..ee74ad3f604 100644 --- a/app/services/browser_support.rb +++ b/app/services/browser_support.rb @@ -1,18 +1,22 @@ class BrowserSupport @cache = LruRedux::Cache.new(1_000) + # rubocop:disable Layout/LineLength BROWSERSLIST_TO_BROWSER_MAP = { - and_chr: ->(browser, version) { browser.android? && browser.chrome?(version) }, + and_chr: ->(browser, version) { browser.android? && !browser.platform.android_webview? && browser.chrome?(version) }, and_uc: ->(browser, version) { browser.android? && browser.uc_browser?(version) }, - chrome: ->(browser, version) { browser.chrome?(version) }, + android: ->(browser, version) { browser.platform.android_webview? && browser.send(:detect_version?, browser.version, version) }, + chrome: ->(browser, version) { !browser.platform.android_webview? && browser.chrome?(version) }, edge: ->(browser, version) { browser.edge?(version) }, firefox: ->(browser, version) { browser.firefox?(version) }, ios_saf: ->(browser, version) { browser.ios? && browser.safari?(version) }, op_mini: ->(browser, version) { browser.opera_mini?(version) }, + op_mob: ->(browser, version) { browser.platform.android? && browser.opera?(version) }, opera: ->(browser, version) { browser.opera?(version) }, safari: ->(browser, version) { browser.safari?(version) }, samsung: ->(browser, version) { browser.samsung_browser?(version) }, }.with_indifferent_access.freeze + # rubocop:enable Layout/LineLength class << self def supported?(user_agent) diff --git a/spec/services/browser_support_spec.rb b/spec/services/browser_support_spec.rb index d545eb22b14..e53b1d43376 100644 --- a/spec/services/browser_support_spec.rb +++ b/spec/services/browser_support_spec.rb @@ -42,8 +42,9 @@ context 'with valid browser support config' do before do - allow(BrowserSupport).to receive(:browser_support_config). - and_return(['chrome 109', 'and_chr 108', 'ios_saf 14.5-14.8', 'op_mini all']) + allow(BrowserSupport).to receive(:browser_support_config).and_return( + ['chrome 109', 'and_chr 108', 'ios_saf 14.5-14.8', 'op_mini all', 'android 119'], + ) end context 'with nil user agent' do @@ -112,16 +113,81 @@ it { expect(supported).to eq(true) } end end - end - context 'with user agent for platform-specific version support' do - let(:user_agent) do - # Android Chrome v108 - 'Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) ' \ - 'Chrome/108.0.5481.153 Mobile Safari/537.36' + context 'with user agent for platform-specific version support' do + let(:user_agent) do + # Android Chrome v108 + 'Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) ' \ + 'Chrome/108.0.5481.153 Mobile Safari/537.36' + end + + it { expect(supported).to eq(true) } end - it { expect(supported).to eq(true) } + context 'with user agent for webview parsed as chrome' do + context 'with version below supported range' do + let(:user_agent) do + # Android WebView v109 + 'Mozilla/5.0 (Linux; Android 7.0; mione A55 Build/NRD90M; wv) AppleWebKit/537.36 ' \ + '(KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.85 Mobile Safari/537.36' + end + + it { expect(supported).to eq(false) } + end + + context 'with version within supported range' do + let(:user_agent) do + # Android WebView v119 + 'Mozilla/5.0 (Linux; Android 13; SM-A546B Build/TP1A.220624.014; wv) ' \ + 'AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/119.0.6045.66 Mobile ' \ + 'Safari/537.36' + end + + it { expect(supported).to eq(true) } + end + end + + context 'with opera desktop user agent' do + let(:user_agent) do + # Opera 83 + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' \ + 'Chrome/103.0.5046.0 Safari/537.36 OPR/83.0.4254.70' + end + + context 'with opera mobile supported range, but no support for desktop' do + before do + allow(BrowserSupport).to receive(:browser_support_config).and_return(['op_mob 73']) + end + + it { expect(supported).to eq(false) } + end + end + + context 'with opera mobile user agent' do + before do + allow(BrowserSupport).to receive(:browser_support_config).and_return(['op_mob 72']) + end + + context 'with version within supported range' do + let(:user_agent) do + # Opera Mobile 72 + 'Mozilla/5.0 (Linux; Android 6.0.1; TX2) AppleWebKit/537.36 (KHTML, like Gecko) ' \ + 'Chrome/106.0.5249.126 Safari/537.36 OPR/72.9.3767.72992' + end + + it { expect(supported).to eq(true) } + end + + context 'with version below supported range' do + let(:user_agent) do + # Opera Mobile 71 + 'Mozilla/5.0 (Linux; Android 7.1.2; Nexus 7) AppleWebKit/537.36 (KHTML, like Gecko) ' \ + 'Chrome/104.0.5112.97 Safari/537.36 OPR/71.3.3718.67322' + end + + it { expect(supported).to eq(false) } + end + end end end end diff --git a/yarn.lock b/yarn.lock index 2631d8b0c73..7c9e782c6e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2382,9 +2382,9 @@ camelcase@^6.0.0, camelcase@^6.3.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001541: - version "1.0.30001549" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz#7d1a3dce7ea78c06ed72c32c2743ea364b3615aa" - integrity sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA== + version "1.0.30001561" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz#752f21f56f96f1b1a52e97aae98c57c562d5d9da" + integrity sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw== chai-as-promised@^7.1.1: version "7.1.1"