Extract component for locale switcher
Note that in order to simplify the component tests (which for some reason seem to be whitespace-sensitive), we have to omit whitespace characters inside the `<option>` tags. Also note we're simplifying the test with a missing language name; since a component test doesn't involve a whole request, we don't need a complex setup (I'm not sure we even need it in system tests).
This commit is contained in:
@@ -486,24 +486,6 @@ body > header,
|
|||||||
border-bottom: 1px solid #fff;
|
border-bottom: 1px solid #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.locale {
|
|
||||||
float: left;
|
|
||||||
height: $line-height * 1.5;
|
|
||||||
margin-left: $line-height / 2;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
color: #808080;
|
|
||||||
content: "\61";
|
|
||||||
font-family: "icons" !important;
|
|
||||||
font-size: $small-font-size;
|
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
|
||||||
right: 2px;
|
|
||||||
top: 9px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.remote-translations-button {
|
.remote-translations-button {
|
||||||
|
|
||||||
&.callout {
|
&.callout {
|
||||||
@@ -982,46 +964,6 @@ footer {
|
|||||||
// 06. Forms
|
// 06. Forms
|
||||||
// ---------
|
// ---------
|
||||||
|
|
||||||
.locale-form {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
label {
|
|
||||||
color: #fff;
|
|
||||||
font-size: $tiny-font-size;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
|
|
||||||
option {
|
|
||||||
background: $body-background;
|
|
||||||
color: $text;
|
|
||||||
border: 0;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.locale-switcher {
|
|
||||||
background: #001d33;
|
|
||||||
border: 0;
|
|
||||||
border-radius: rem-calc(4);
|
|
||||||
color: #fff;
|
|
||||||
font-size: $small-font-size;
|
|
||||||
height: $line-height;
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: $line-height / 4;
|
|
||||||
outline: none;
|
|
||||||
padding-left: $line-height / 4;
|
|
||||||
padding-right: calc(#{$line-height / 4} + 1em);
|
|
||||||
width: auto;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: $outline-focus;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
form {
|
||||||
|
|
||||||
label {
|
label {
|
||||||
|
|||||||
54
app/assets/stylesheets/layout/locale_switcher.scss
Normal file
54
app/assets/stylesheets/layout/locale_switcher.scss
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
.locale {
|
||||||
|
float: left;
|
||||||
|
height: $line-height * 1.5;
|
||||||
|
margin-left: $line-height / 2;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
color: #808080;
|
||||||
|
content: "\61";
|
||||||
|
font-family: "icons" !important;
|
||||||
|
font-size: $small-font-size;
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
right: 2px;
|
||||||
|
top: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.locale-form {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
label {
|
||||||
|
color: #fff;
|
||||||
|
font-size: $tiny-font-size;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
background: #001d33;
|
||||||
|
border: 0;
|
||||||
|
border-radius: rem-calc(4);
|
||||||
|
color: #fff;
|
||||||
|
font-size: $small-font-size;
|
||||||
|
height: $line-height;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: $line-height / 4;
|
||||||
|
outline: none;
|
||||||
|
padding-left: $line-height / 4;
|
||||||
|
padding-right: calc(#{$line-height / 4} + 1em);
|
||||||
|
width: auto;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: $outline-focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
option {
|
||||||
|
background: $body-background;
|
||||||
|
color: $text;
|
||||||
|
border: 0;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
app/components/layout/locale_switcher_component.html.erb
Normal file
15
app/components/layout/locale_switcher_component.html.erb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<% if I18n.available_locales.size > 1 %>
|
||||||
|
<div class="locale">
|
||||||
|
<form class="locale-form">
|
||||||
|
<label class="inline-block" for="locale-switcher">
|
||||||
|
<%= t("layouts.header.locale") %>
|
||||||
|
</label>
|
||||||
|
<select class="js-location-changer locale-switcher inline-block" name="locale-switcher" id="locale-switcher">
|
||||||
|
<% I18n.available_locales.map do |loc| %>
|
||||||
|
<option <%= "selected" if loc == I18n.locale %>
|
||||||
|
value="<%= current_path_with_query_params(locale: loc) %>"><%= name_for_locale(loc) %></option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
3
app/components/layout/locale_switcher_component.rb
Normal file
3
app/components/layout/locale_switcher_component.rb
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
class Layout::LocaleSwitcherComponent < ApplicationComponent
|
||||||
|
delegate :name_for_locale, :current_path_with_query_params, to: :helpers
|
||||||
|
end
|
||||||
@@ -1,17 +1 @@
|
|||||||
<% if I18n.available_locales.size > 1 %>
|
<%= render Layout::LocaleSwitcherComponent.new %>
|
||||||
<div class="locale">
|
|
||||||
<form class="locale-form">
|
|
||||||
<label class="inline-block" for="locale-switcher">
|
|
||||||
<%= t("layouts.header.locale") %>
|
|
||||||
</label>
|
|
||||||
<select class="js-location-changer locale-switcher inline-block" name="locale-switcher" id="locale-switcher">
|
|
||||||
<% I18n.available_locales.map do |loc| %>
|
|
||||||
<option <%= "selected" if loc == I18n.locale %>
|
|
||||||
value="<%= current_path_with_query_params(locale: loc) %>">
|
|
||||||
<%= name_for_locale(loc) %>
|
|
||||||
</option>
|
|
||||||
<% end %>
|
|
||||||
</select>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|||||||
56
spec/components/layout/locale_switcher_component_spec.rb
Normal file
56
spec/components/layout/locale_switcher_component_spec.rb
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe Layout::LocaleSwitcherComponent, type: :component do
|
||||||
|
let(:component) { Layout::LocaleSwitcherComponent.new }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(request).to receive(:path_parameters).and_return(
|
||||||
|
Rails.application.routes.recognize_path("/")
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with only one language" do
|
||||||
|
before { allow(I18n).to receive(:available_locales).and_return([:en]) }
|
||||||
|
|
||||||
|
it "doesn't render anything" do
|
||||||
|
render_inline component
|
||||||
|
|
||||||
|
expect(page.text).to be_empty
|
||||||
|
expect(page).not_to have_css ".locale"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with many languages" do
|
||||||
|
before { allow(I18n).to receive(:available_locales).and_return(%i[de en es fr nl]) }
|
||||||
|
|
||||||
|
it "renders a form to select the language" do
|
||||||
|
render_inline component
|
||||||
|
|
||||||
|
expect(page).to have_css "form"
|
||||||
|
expect(page).to have_select "Language:", options: %w[Deutsch English Español Français Nederlands]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "selects the current locale" do
|
||||||
|
render_inline component
|
||||||
|
|
||||||
|
expect(page).to have_select "Language:", selected: "English"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "missing language names" do
|
||||||
|
let!(:default_enforce) { I18n.enforce_available_locales }
|
||||||
|
|
||||||
|
before do
|
||||||
|
I18n.enforce_available_locales = false
|
||||||
|
allow(I18n).to receive(:available_locales).and_return(%i[de en es fr nl wl])
|
||||||
|
end
|
||||||
|
|
||||||
|
after { I18n.enforce_available_locales = default_enforce }
|
||||||
|
|
||||||
|
it "renders the locale key" do
|
||||||
|
render_inline component
|
||||||
|
|
||||||
|
expect(page).to have_select "Language:", with_options: ["wl"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -16,17 +16,6 @@ describe "Localization" do
|
|||||||
expect(page).to have_text("Bienvenido a CONSUL")
|
expect(page).to have_text("Bienvenido a CONSUL")
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Available locales appear in the locale switcher" do
|
|
||||||
visit "/"
|
|
||||||
|
|
||||||
expect(page).to have_select "Language:", with_options: %w[Español English]
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "The current locale is selected" do
|
|
||||||
visit "/"
|
|
||||||
expect(page).to have_select "Language:", selected: "English"
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Changing the locale" do
|
scenario "Changing the locale" do
|
||||||
visit "/"
|
visit "/"
|
||||||
select "Español", from: "Language:"
|
select "Español", from: "Language:"
|
||||||
@@ -44,44 +33,6 @@ describe "Localization" do
|
|||||||
expect(page).to have_current_path "/debates?locale=es&order=created_at"
|
expect(page).to have_current_path "/debates?locale=es&order=created_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
context "Only one locale" do
|
|
||||||
before do
|
|
||||||
allow(I18n).to receive(:available_locales).and_return([:en])
|
|
||||||
I18n.reload!
|
|
||||||
end
|
|
||||||
|
|
||||||
after { I18n.reload! }
|
|
||||||
|
|
||||||
scenario "Locale switcher not present" do
|
|
||||||
visit "/"
|
|
||||||
expect(page).not_to have_content("Language")
|
|
||||||
expect(page).not_to have_css("div.locale")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "Missing language names" do
|
|
||||||
let!(:default_enforce) { I18n.enforce_available_locales }
|
|
||||||
let!(:default_locales) { I18n.available_locales.dup }
|
|
||||||
|
|
||||||
before do
|
|
||||||
I18n.enforce_available_locales = false
|
|
||||||
I18n.available_locales = default_locales + [:wl]
|
|
||||||
I18n.locale = :wl
|
|
||||||
end
|
|
||||||
|
|
||||||
after do
|
|
||||||
I18n.enforce_available_locales = default_enforce
|
|
||||||
I18n.available_locales = default_locales
|
|
||||||
I18n.locale = I18n.default_locale
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Available locales without language translation display locale key" do
|
|
||||||
visit "/"
|
|
||||||
|
|
||||||
expect(page).to have_select "Language:", with_options: ["wl"]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "uses default locale when session locale has disappeared" do
|
scenario "uses default locale when session locale has disappeared" do
|
||||||
default_locales = I18n.available_locales
|
default_locales = I18n.available_locales
|
||||||
|
|
||||||
|
|||||||
@@ -9,31 +9,12 @@ describe "Localization" do
|
|||||||
expect(page).to have_text("Gestión")
|
expect(page).to have_text("Gestión")
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Available locales appear in the locale switcher" do
|
|
||||||
login_as_manager
|
|
||||||
|
|
||||||
expect(page).to have_select "Language:", with_options: %w[Español English]
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "The current locale is selected" do
|
|
||||||
login_as_manager
|
|
||||||
expect(page).to have_select "Language:", selected: "English"
|
|
||||||
expect(page).to have_text("Management")
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Changing the locale" do
|
scenario "Changing the locale" do
|
||||||
login_as_manager
|
login_as_manager
|
||||||
select "Español", from: "Language:"
|
select "Español", from: "Language:"
|
||||||
|
|
||||||
expect(page).not_to have_select "Language:"
|
expect(page).not_to have_select "Language:"
|
||||||
expect(page).to have_select "Idioma:", selected: "Español"
|
expect(page).to have_select "Idioma:", selected: "Español"
|
||||||
end
|
expect(page).to have_content "Gestión"
|
||||||
|
|
||||||
scenario "Locale switcher not present if only one locale" do
|
|
||||||
allow(I18n).to receive(:available_locales).and_return([:en])
|
|
||||||
|
|
||||||
login_as_manager
|
|
||||||
expect(page).not_to have_content("Language")
|
|
||||||
expect(page).not_to have_css("div.locale")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user