add integration specs for changing locales

This commit is contained in:
Georg Gadinger 2023-01-06 13:37:22 +01:00
parent 68f5fad5f8
commit 5b8e34aa1d
2 changed files with 86 additions and 3 deletions

View File

@ -11,9 +11,7 @@ class ApplicationController < ActionController::Base
before_action :find_active_announcements before_action :find_active_announcements
# check if user wants to read # check if user wants to read
def switch_locale(&) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity def switch_locale(&)
return I18n.with_locale("en", &) if Rails.env.test?
locale = params[:lang] || current_user&.locale || cookies[:lang] || "en" locale = params[:lang] || current_user&.locale || cookies[:lang] || "en"
if params[:lang] && current_user.present? if params[:lang] && current_user.present?
current_user.locale = locale current_user.locale = locale

View File

@ -0,0 +1,85 @@
# frozen_string_literal: true
require "rails_helper"
require "nokogiri"
describe "locale switching", type: :request do
matcher :have_html_lang do |expected_lang|
description { %(have the HTML "lang" attribute set to #{expected_lang.inspect}) }
match do |result|
Nokogiri::HTML.parse(result).css("html[lang=#{expected_lang}]").size == 1
end
end
context "when user not signed in" do
it "uses the default :en locale" do
get "/"
expect(response.body).to have_html_lang "en"
expect(response.cookies["lang"]).to eq "en"
end
context "when ?lang param is given" do
it "changes the locale" do
# 1. ensure we start with the default :en locale
get "/"
expect(response.body).to have_html_lang "en"
expect(response.cookies["lang"]).to eq "en"
# 2. switch the language to en-xx
get "/?lang=en-xx"
expect(response.body).to have_html_lang "en-xx"
expect(response.cookies["lang"]).to eq "en-xx"
# 3. remove the language parameter again
get "/"
expect(response.body).to have_html_lang "en-xx"
expect(response.cookies["lang"]).to be_nil # no new cookie here, it's already en-xx
end
end
end
context "when user is signed in" do
let(:user) { FactoryBot.create(:user, password: "test1234", locale:) }
let(:locale) { "en" }
before do
post "/sign_in", params: { user: { login: user.email, password: user.password } }
end
it "uses the en locale" do
get "/"
expect(response.body).to have_html_lang "en"
expect(response.cookies["lang"]).to be_nil # no new cookie here, already set by the sign in
end
context "when ?lang param is given" do
it "changes the locale" do
# 1. ensure we start with the :en locale
get "/"
expect(response.body).to have_html_lang "en"
expect(response.cookies["lang"]).to be_nil # no new cookie here, already set by the sign in
# 2. switch the language to en-xx
expect { get "/?lang=en-xx" }.to change { user.reload.locale }.from("en").to("en-xx")
expect(response.body).to have_html_lang "en-xx"
expect(response.cookies["lang"]).to eq "en-xx"
# 3. remove the language parameter again
get "/"
expect(response.body).to have_html_lang "en-xx"
expect(response.cookies["lang"]).to be_nil # no new cookie here, it's already en-xx
end
end
context "when user has a different locale set" do
let(:locale) { "fi" }
it "uses the different locale" do
get "/"
expect(response.body).to have_html_lang "fi"
expect(response.cookies["lang"]).to be_nil # no new cookie here, already set by the sign in
end
end
end
end