DEV: Simplify ember-cli proxy strategy (#24242)

Previously, the app HTML served by the Ember-CLI proxy was generated based on a 'bootstrap json' payload generated by Rails. This inevitably leads to differences between the Rails HTML and the Ember-CLI HTML.

This commit overhauls our proxying strategy. Now, we totally ignore the ember-cli `index.html` file. Instead, we take the full HTML from Rails and surgically replace script URLs based on a `data-discourse-entrypoint` attribute. This should be faster (only one request to Rails), more robust, and less confusing for developers.
This commit is contained in:
David Taylor
2023-11-10 11:16:06 +00:00
committed by GitHub
parent 80208d0ab6
commit ac896755bb
12 changed files with 348 additions and 710 deletions

View File

@ -900,6 +900,13 @@ RSpec.describe ApplicationController do
{ HTTP_ACCEPT_LANGUAGE: locale }
end
def locale_scripts(body)
Nokogiri::HTML5
.parse(body)
.css('script[src*="assets/locales/"]')
.map { |script| script.attributes["src"].value }
end
context "with allow_user_locale disabled" do
context "when accept-language header differs from default locale" do
before do
@ -909,9 +916,9 @@ RSpec.describe ApplicationController do
context "with an anonymous user" do
it "uses the default locale" do
get "/bootstrap.json", headers: headers("fr")
get "/latest", headers: headers("fr")
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("en.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/en.js")
end
end
@ -920,9 +927,9 @@ RSpec.describe ApplicationController do
user = Fabricate(:user, locale: :fr)
sign_in(user)
get "/bootstrap.json", headers: headers("fr")
get "/latest", headers: headers("fr")
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("en.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/en.js")
end
end
end
@ -938,15 +945,15 @@ RSpec.describe ApplicationController do
context "with an anonymous user" do
it "uses the locale from the headers" do
get "/bootstrap.json", headers: headers("fr")
get "/latest", headers: headers("fr")
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("fr.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/fr.js")
end
it "doesn't leak after requests" do
get "/bootstrap.json", headers: headers("fr")
get "/latest", headers: headers("fr")
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("fr.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/fr.js")
expect(I18n.locale.to_s).to eq(SiteSettings::DefaultsProvider::DEFAULT_LOCALE)
end
end
@ -957,9 +964,9 @@ RSpec.describe ApplicationController do
before { sign_in(user) }
it "uses the user's preferred locale" do
get "/bootstrap.json", headers: headers("fr")
get "/latest", headers: headers("fr")
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("fr.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/fr.js")
end
it "serves a 404 page in the preferred locale" do
@ -983,9 +990,9 @@ RSpec.describe ApplicationController do
SiteSetting.set_locale_from_accept_language_header = true
SiteSetting.default_locale = "en"
get "/bootstrap.json", headers: headers("zh-CN")
get "/latest", headers: headers("zh-CN")
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("zh_CN.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/zh_CN.js")
end
end
@ -994,9 +1001,9 @@ RSpec.describe ApplicationController do
SiteSetting.allow_user_locale = true
SiteSetting.default_locale = "en"
get "/bootstrap.json", headers: headers("")
get "/latest", headers: headers("")
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("en.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/en.js")
end
end
end
@ -1011,18 +1018,18 @@ RSpec.describe ApplicationController do
context "with an anonymous user" do
it "uses the locale from the cookie" do
get "/bootstrap.json", headers: { Cookie: "locale=es" }
get "/latest", headers: { Cookie: "locale=es" }
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("es.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/es.js")
expect(I18n.locale.to_s).to eq(SiteSettings::DefaultsProvider::DEFAULT_LOCALE) # doesn't leak after requests
end
end
context "when the preferred locale includes a region" do
it "returns the locale and region separated by an underscore" do
get "/bootstrap.json", headers: { Cookie: "locale=zh-CN" }
get "/latest", headers: { Cookie: "locale=zh-CN" }
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("zh_CN.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/zh_CN.js")
end
end
end
@ -1032,9 +1039,9 @@ RSpec.describe ApplicationController do
SiteSetting.allow_user_locale = true
SiteSetting.default_locale = "en"
get "/bootstrap.json", headers: { Cookie: "" }
get "/latest", headers: { Cookie: "" }
expect(response.status).to eq(200)
expect(response.parsed_body["bootstrap"]["locale_script"]).to end_with("en.js")
expect(locale_scripts(response.body)).to contain_exactly("/assets/locales/en.js")
end
end
end