http_accept_language_v2 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3674378e35da2c8cb7ff2f7dff176ab8d1037158b3c2024690143064b4cfed72
4
+ data.tar.gz: d57a9880c727af8b8b084de1818f656fd516561f7b03b7397775ac066dab9400
5
+ SHA512:
6
+ metadata.gz: 4e7d7b7d180be9f80e1e4637235624070203d0514a1b57d0e58b3cd01c1a0b0c9881f7b238716c25a1d47435f53555e81886d19af5af82bb6f44df0e6704a2ac
7
+ data.tar.gz: e768458d391b2a5cfe628ddd62fcffe52bb5ce95be6fbc888841ef56c6433001981bee3d8e8e94f2a499a37cada119841431d3ba8d2633046c8358e907038d05
@@ -0,0 +1,25 @@
1
+ on:
2
+ push
3
+
4
+ jobs:
5
+ rspec:
6
+ name: Rspec Ruby ${{ matrix.ruby }} Rails ${{ matrix.rails }}
7
+ strategy:
8
+ fail-fast: false
9
+ matrix:
10
+ rails: [5.2, 6.0, 6.1]
11
+ ruby: [2.6, 2.7, 3.0]
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: actions/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby }}
18
+ - name: Specs
19
+ env:
20
+ RAILS_VERSION: ${{ matrix.rails }}
21
+ run: |
22
+ gem install bundler
23
+ bundle install --jobs 4 --retry 3
24
+ gem install rails --version "=$RAILS_VERSION"
25
+ bundle exec rspec spec
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
6
+ log/*.log
7
+ tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ guard 'rspec', :cli => "-fd", :version => 2 do
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ watch(%r{^lib/(.+)\.rb$}) { "spec" }
6
+ watch('spec/spec_helper.rb') { "spec" }
7
+ end
8
+
data/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # HttpAcceptLanguage [![Build Status](https://travis-ci.org/iain/http_accept_language.svg?branch=master)](https://travis-ci.org/iain/http_accept_language)
2
+
3
+ A gem which helps you detect the users preferred language, as sent by the "Accept-Language" HTTP header.
4
+
5
+ The algorithm is based on [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html), with one exception:
6
+ when a user requests "en-US" and "en" is an available language, "en" is deemed compatible with "en-US".
7
+ The RFC specifies that the requested language must either exactly match the available language or must exactly match a prefix of the available language. This means that when the user requests "en" and "en-US" is available, "en-US" would be compatible, but not the other way around. This is usually not what you're looking for.
8
+
9
+ Since version 2.0, this gem is Rack middleware.
10
+
11
+ ## Example
12
+
13
+ The `http_accept_language` method is available in any controller:
14
+
15
+ ```ruby
16
+ class SomeController < ApplicationController
17
+ def some_action
18
+ http_accept_language.user_preferred_languages # => %w(nl-NL nl-BE nl en-US en)
19
+ available = %w(en en-US nl-BE)
20
+ http_accept_language.preferred_language_from(available) # => 'nl-BE'
21
+
22
+ http_accept_language.user_preferred_languages # => %w(en-GB)
23
+ available = %w(en-US)
24
+ http_accept_language.compatible_language_from(available) # => 'en-US'
25
+
26
+ http_accept_language.user_preferred_languages # => %w(nl-NL nl-BE nl en-US en)
27
+ available = %w(en nl de) # This could be from I18n.available_locales
28
+ http_accept_language.preferred_language_from(available) # => 'nl'
29
+ end
30
+ end
31
+ ```
32
+
33
+ You can easily set the locale used for i18n in a before-filter:
34
+
35
+ ```ruby
36
+ class SomeController < ApplicationController
37
+ before_filter :set_locale
38
+
39
+ private
40
+ def set_locale
41
+ I18n.locale = http_accept_language.compatible_language_from(I18n.available_locales)
42
+ end
43
+ end
44
+ ```
45
+
46
+ If you want to enable this behavior by default in your controllers, you can just include the provided concern:
47
+
48
+ ```ruby
49
+ class ApplicationController < ActionController::Base
50
+ include HttpAcceptLanguage::AutoLocale
51
+
52
+ #...
53
+ end
54
+ ```
55
+
56
+ Then set available locales in `config/application.rb`:
57
+
58
+ ```ruby
59
+ config.i18n.available_locales = %w(en nl de fr)
60
+ ```
61
+
62
+ To use the middleware in any Rack application, simply add the middleware:
63
+
64
+ ``` ruby
65
+ require 'http_accept_language'
66
+ use HttpAcceptLanguage::Middleware
67
+ run YourAwesomeApp
68
+ ```
69
+
70
+ Then you can access it from `env`:
71
+
72
+ ``` ruby
73
+ class YourAwesomeApp
74
+
75
+ def initialize(app)
76
+ @app = app
77
+ end
78
+
79
+ def call(env)
80
+ available = %w(en en-US nl-BE)
81
+ language = env.http_accept_language.preferred_language_from(available)
82
+
83
+ [200, {}, ["Oh, you speak #{language}!"]]
84
+ end
85
+
86
+ end
87
+ ```
88
+
89
+ ## Available methods
90
+
91
+ * **user_preferred_languages**:
92
+ Returns a sorted array based on user preference in HTTP_ACCEPT_LANGUAGE, sanitized and all.
93
+ * **preferred_language_from(languages)**:
94
+ Finds the locale specifically requested by the browser
95
+ * **compatible_language_from(languages)**:
96
+ Returns the first of the user_preferred_languages that is compatible with the available locales.
97
+ Ignores region.
98
+ * **sanitize_available_locales(languages)**:
99
+ Returns a supplied list of available locals without any extra application info
100
+ that may be attached to the locale for storage in the application.
101
+ * **language_region_compatible_from(languages)**:
102
+ Returns the first of the user preferred languages that is
103
+ also found in available languages. Finds best fit by matching on
104
+ primary language first and secondarily on region. If no matching region is
105
+ found, return the first language in the group matching that primary language.
106
+
107
+ ## Installation
108
+
109
+ ### Without Bundler
110
+
111
+ Install the gem `http_accept_language`
112
+
113
+ ### With Bundler
114
+
115
+ Add the gem to your Gemfile:
116
+
117
+ ``` ruby
118
+ gem 'http_accept_language'
119
+ ```
120
+
121
+ Run `bundle install` to install it.
122
+
123
+ ---
124
+
125
+ Released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ require 'cucumber/rake/task'
7
+ Cucumber::Rake::Task.new(:cucumber)
8
+
9
+ Cucumber::Rake::Task.new(:wip, "Run features tagged with @wip") do |t|
10
+ t.profile = "wip"
11
+ end
12
+
13
+ task :default => [:spec, :cucumber, :wip]
data/cucumber.yml ADDED
@@ -0,0 +1,2 @@
1
+ default: --format progress --strict --tags ~@wip
2
+ wip: --format pretty --wip --tags @wip
@@ -0,0 +1,29 @@
1
+ @rails
2
+ Feature: Rails Integration
3
+
4
+ To use http_accept_language inside a Rails application, just add it to your
5
+ Gemfile and run `bundle install`.
6
+
7
+ It is automatically added to your middleware.
8
+
9
+ Scenario: Installing
10
+ When I generate a new Rails app
11
+ And I add http_accept_language to my Gemfile
12
+ And I run `rake middleware`
13
+ Then the output should contain "use HttpAcceptLanguage::Middleware"
14
+
15
+ Scenario: Using
16
+ Given I have installed http_accept_language
17
+ When I generate the following controller:
18
+ """
19
+ class LanguagesController < ApplicationController
20
+
21
+ def index
22
+ languages = http_accept_language.user_preferred_languages
23
+ render :text => "Languages: #{languages.join(' : ')}"
24
+ end
25
+
26
+ end
27
+ """
28
+ When I access that action with the HTTP_ACCEPT_LANGUAGE header "en-us,en-gb;q=0.8,en;q=0.6,es-419"
29
+ Then the response should contain "Languages: en-US : es-419 : en-GB : en"
@@ -0,0 +1,37 @@
1
+ Before "@rails" do
2
+ @rails = RailsDriver.new
3
+ end
4
+
5
+ When /^I generate a new Rails app$/ do
6
+ @rails.generate_rails
7
+ end
8
+
9
+ When /^I add http_accept_language to my Gemfile$/ do
10
+ @rails.append_gemfile
11
+ end
12
+
13
+ Given /^I have installed http_accept_language$/ do
14
+ @rails.install_gem
15
+ end
16
+
17
+ When /^I generate the following controller:$/ do |string|
18
+ @rails.generate_controller "languages", string
19
+ end
20
+
21
+ When /^I access that action with the HTTP_ACCEPT_LANGUAGE header "(.*?)"$/ do |header|
22
+ @rails.with_rails_running do
23
+ @rails.request_with_http_accept_language_header(header, "/languages")
24
+ end
25
+ end
26
+
27
+ Then /^the response should contain "(.*?)"$/ do |output|
28
+ @rails.output_should_contain(output)
29
+ end
30
+
31
+ When /^I run `rake middleware`$/ do
32
+ @rails.bundle_exec("rake middleware")
33
+ end
34
+
35
+ Then /^the output should contain "(.*?)"$/ do |expected|
36
+ @rails.assert_partial_output(expected, @rails.all_output)
37
+ end
@@ -0,0 +1,93 @@
1
+ require 'aruba/api'
2
+
3
+ class RailsDriver
4
+ include Aruba::Api
5
+
6
+ def initialize
7
+ @aruba_io_wait_seconds = 10
8
+ # @announce_stdout = true
9
+ # @announce_stderr = true
10
+ # @announce_cmd = true
11
+ # @announce_dir = true
12
+ # @announce_env = true
13
+ end
14
+
15
+ def app_name
16
+ "foobar"
17
+ end
18
+
19
+ def install_gem
20
+ if app_exists?
21
+ cd app_name
22
+ else
23
+ generate_rails
24
+ append_gemfile
25
+ end
26
+ end
27
+
28
+ def app_exists?
29
+ in_current_dir do
30
+ File.exist?("#{app_name}/Gemfile")
31
+ end
32
+ end
33
+
34
+ def bundle_exec(cmd)
35
+ run_simple "bundle exec #{cmd}"
36
+ end
37
+
38
+ def generate_rails
39
+ # install rails with as few things as possible, for speed!
40
+ bundle_exec "rails new #{app_name} --force --skip-git --skip-active-record --skip-sprockets --skip-javascript --skip-test-unit --old-style-hash"
41
+ cd app_name
42
+ end
43
+
44
+ def append_gemfile
45
+ # Specifiy a path so cucumber will use the unreleased version of the gem
46
+ append_to_file "Gemfile", "gem 'http_accept_language', :path => '#{gem_path}'"
47
+ end
48
+
49
+ def gem_path
50
+ File.expand_path('../../../', __FILE__)
51
+ end
52
+
53
+ def generate_controller(name, content)
54
+ bundle_exec "rails generate resource #{name} --force"
55
+ write_file "app/controllers/#{name}_controller.rb", content
56
+ end
57
+
58
+ def request_with_http_accept_language_header(header, path)
59
+ run_simple "curl --retry 10 -H 'Accept-language: #{header}' #{File.join(host, path)} -o #{response}"
60
+ run_simple "cat out.html"
61
+ end
62
+
63
+ def host
64
+ "http://localhost:13000"
65
+ end
66
+
67
+ def with_rails_running
68
+ start_rails
69
+ yield
70
+ ensure
71
+ stop_rails
72
+ end
73
+
74
+ def start_rails
75
+ bundle_exec "rails server -p 13000 -d"
76
+ end
77
+
78
+ def stop_rails
79
+ in_current_dir do
80
+ `cat tmp/pids/server.pid | xargs kill -9`
81
+ end
82
+ end
83
+
84
+ def response
85
+ File.expand_path(File.join(current_dir, 'out.html'))
86
+ end
87
+
88
+ def output_should_contain(expected)
89
+ actual = File.open(response, 'r:utf-8').read
90
+ actual.should include expected
91
+ end
92
+
93
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "http_accept_language/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "http_accept_language_v2"
7
+ s.version = HttpAcceptLanguage::VERSION
8
+ s.authors = ["iain", "yknx4"]
9
+ s.email = ["iain@iain.nl", "me@ale.world"]
10
+ s.homepage = "https://github.com/yknx4/http_accept_language"
11
+ s.summary = %q{Find out which locale the user preferes by reading the languages they specified in their browser}
12
+ s.description = %q{Find out which locale the user preferes by reading the languages they specified in their browser}
13
+ s.license = "MIT"
14
+
15
+ s.rubyforge_project = "http_accept_language"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency 'rake'
23
+ s.add_development_dependency 'rspec'
24
+ s.add_development_dependency 'rack-test'
25
+ s.add_development_dependency 'guard-rspec'
26
+ s.add_development_dependency 'rails', ['>= 5.2', '< 7.0']
27
+ s.add_development_dependency 'cucumber'
28
+ s.add_development_dependency 'aruba'
29
+ end
@@ -0,0 +1,4 @@
1
+ require 'http_accept_language/auto_locale'
2
+ require 'http_accept_language/parser'
3
+ require 'http_accept_language/middleware'
4
+ require 'http_accept_language/railtie' if defined?(Rails::Railtie)
@@ -0,0 +1,21 @@
1
+ require 'active_support/concern'
2
+
3
+ module HttpAcceptLanguage
4
+ module AutoLocale
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ if respond_to?(:prepend_before_action)
9
+ prepend_before_action :set_locale
10
+ else
11
+ prepend_before_filter :set_locale
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def set_locale
18
+ I18n.locale = http_accept_language.compatible_language_from(I18n.available_locales) || I18n.default_locale
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ module HttpAcceptLanguage
2
+ class Middleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ env["http_accept_language.parser"] = Parser.new(env["HTTP_ACCEPT_LANGUAGE"])
9
+
10
+ def env.http_accept_language
11
+ self["http_accept_language.parser"]
12
+ end
13
+
14
+ @app.call(env)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,108 @@
1
+ module HttpAcceptLanguage
2
+ class Parser
3
+ attr_accessor :header
4
+
5
+ def initialize(header)
6
+ @header = header
7
+ end
8
+
9
+ # Returns a sorted array based on user preference in HTTP_ACCEPT_LANGUAGE.
10
+ # Browsers send this HTTP header, so don't think this is holy.
11
+ #
12
+ # Example:
13
+ #
14
+ # request.user_preferred_languages
15
+ # # => [ 'nl-NL', 'nl-BE', 'nl', 'en-US', 'en' ]
16
+ #
17
+ def user_preferred_languages
18
+ @user_preferred_languages ||= begin
19
+ header.to_s.gsub(/\s+/, '').split(',').map do |language|
20
+ locale, quality = language.split(';q=')
21
+ raise ArgumentError, 'Not correctly formatted' unless locale =~ /^[a-z\-0-9]+|\*$/i
22
+
23
+ locale = locale.downcase.gsub(/-[a-z0-9]+$/i, &:upcase) # Uppercase territory
24
+ locale = nil if locale == '*' # Ignore wildcards
25
+
26
+ quality = quality ? quality.to_f : 1.0
27
+
28
+ [locale, quality]
29
+ end.sort do |(_, left), (_, right)|
30
+ right <=> left
31
+ end.map(&:first).compact
32
+ rescue ArgumentError # Just rescue anything if the browser messed up badly.
33
+ []
34
+ end
35
+ end
36
+
37
+ # Sets the user languages preference, overriding the browser
38
+ #
39
+ def user_preferred_languages=(languages)
40
+ @user_preferred_languages = languages
41
+ end
42
+
43
+ # Finds the locale specifically requested by the browser.
44
+ #
45
+ # Example:
46
+ #
47
+ # request.preferred_language_from I18n.available_locales
48
+ # # => 'nl'
49
+ #
50
+ def preferred_language_from(array)
51
+ (user_preferred_languages & array.map(&:to_s)).first
52
+ end
53
+
54
+ # Returns the first of the user_preferred_languages that is compatible
55
+ # with the available locales. Ignores region.
56
+ #
57
+ # Example:
58
+ #
59
+ # request.compatible_language_from I18n.available_locales
60
+ #
61
+ def compatible_language_from(available_languages)
62
+ user_preferred_languages.map do |preferred| #en-US
63
+ preferred = preferred.downcase
64
+ preferred_language = preferred.split('-', 2).first
65
+
66
+ available_languages.find do |available| # en
67
+ available = available.to_s.downcase
68
+ preferred == available || preferred_language == available.split('-', 2).first
69
+ end
70
+ end.compact.first
71
+ end
72
+
73
+ # Returns a supplied list of available locals without any extra application info
74
+ # that may be attached to the locale for storage in the application.
75
+ #
76
+ # Example:
77
+ # [ja_JP-x1, en-US-x4, en_UK-x5, fr-FR-x3] => [ja-JP, en-US, en-UK, fr-FR]
78
+ #
79
+ def sanitize_available_locales(available_languages)
80
+ available_languages.map do |available|
81
+ available.to_s.split(/[_-]/).reject { |part| part.start_with?("x") }.join("-")
82
+ end
83
+ end
84
+
85
+ # Returns the first of the user preferred languages that is
86
+ # also found in available languages. Finds best fit by matching on
87
+ # primary language first and secondarily on region. If no matching region is
88
+ # found, return the first language in the group matching that primary language.
89
+ #
90
+ # Example:
91
+ #
92
+ # request.language_region_compatible(available_languages)
93
+ #
94
+ def language_region_compatible_from(available_languages)
95
+ available_languages = sanitize_available_locales(available_languages)
96
+ user_preferred_languages.map do |preferred| #en-US
97
+ preferred = preferred.downcase
98
+ preferred_language = preferred.split('-', 2).first
99
+
100
+ lang_group = available_languages.select do |available| # en
101
+ preferred_language == available.downcase.split('-', 2).first
102
+ end
103
+
104
+ lang_group.find { |lang| lang.downcase == preferred } || lang_group.first #en-US, en-UK
105
+ end.compact.first
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,17 @@
1
+ module HttpAcceptLanguage
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "http_accept_language.add_middleware" do |app|
4
+ app.middleware.use Middleware
5
+
6
+ ActiveSupport.on_load :action_controller do
7
+ include EasyAccess
8
+ end
9
+ end
10
+ end
11
+
12
+ module EasyAccess
13
+ def http_accept_language
14
+ @http_accept_language ||= request.env["http_accept_language.parser"] || Parser.new(request.env["HTTP_ACCEPT_LANGUAGE"])
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module HttpAcceptLanguage
2
+ VERSION = '2.1.2'
3
+ end
@@ -0,0 +1,71 @@
1
+ require 'i18n'
2
+ require 'http_accept_language/auto_locale'
3
+ require 'http_accept_language/parser'
4
+ require 'http_accept_language/middleware'
5
+
6
+ describe HttpAcceptLanguage::AutoLocale do
7
+ let(:controller_class) do
8
+ Class.new do
9
+ def initialize(header = nil)
10
+ super()
11
+ @header = header
12
+ end
13
+
14
+ def self.prepend_before_action(dummy)
15
+ # dummy method
16
+ end
17
+
18
+ def self.prepend_before_filter(dummy)
19
+ # dummy method
20
+ end
21
+
22
+ def http_accept_language
23
+ @http_accept_language ||= HttpAcceptLanguage::Parser.new(@header)
24
+ end
25
+
26
+ include HttpAcceptLanguage::AutoLocale
27
+ end
28
+ end
29
+
30
+ let(:controller) { controller_class.new("ja,en-us;q=0.7,en;q=0.3") }
31
+
32
+ context "available languages includes accept_languages" do
33
+ before do
34
+ I18n.available_locales = [:en, :ja]
35
+ end
36
+
37
+ it "take a suitable locale" do
38
+ controller.send(:set_locale)
39
+
40
+ expect(I18n.locale).to eq(:ja)
41
+ end
42
+ end
43
+
44
+ context "available languages do not include accept_languages" do
45
+ before do
46
+ I18n.available_locales = [:es]
47
+ I18n.default_locale = :es
48
+ end
49
+
50
+ it "set the locale to default" do
51
+ no_accept_language_controller.send(:set_locale)
52
+
53
+ expect(I18n.locale).to eq(:es)
54
+ end
55
+ end
56
+
57
+ let(:no_accept_language_controller) { controller_class.new() }
58
+
59
+ context "default locale is ja" do
60
+ before do
61
+ I18n.available_locales = [:en, :ja]
62
+ I18n.default_locale = :ja
63
+ end
64
+
65
+ it "set the locale to default" do
66
+ no_accept_language_controller.send(:set_locale)
67
+
68
+ expect(I18n.locale).to eq(:ja)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,60 @@
1
+ require 'http_accept_language'
2
+ require 'rack/test'
3
+ require 'json'
4
+
5
+ class TestRackApp
6
+
7
+ def call(env)
8
+ request = Rack::Request.new(env)
9
+ http_accept_language = env.http_accept_language
10
+ result = {
11
+ :user_preferred_languages => http_accept_language.user_preferred_languages,
12
+ }
13
+ if request.params['preferred']
14
+ result[:preferred_language_from] = http_accept_language.preferred_language_from(request.params['preferred'])
15
+ end
16
+ [ 200, {}, [ JSON.generate(result) ]]
17
+ end
18
+
19
+ end
20
+
21
+ describe "Rack integration" do
22
+ include Rack::Test::Methods
23
+
24
+ def app
25
+ Rack::Builder.new do
26
+ use HttpAcceptLanguage::Middleware
27
+ run TestRackApp.new
28
+ end.to_app
29
+ end
30
+
31
+ it "handles reuse of the env instance" do
32
+ env = { "HTTP_ACCEPT_LANGUAGE" => "en" }
33
+ app = lambda { |env| env }
34
+ middleware = HttpAcceptLanguage::Middleware.new(app)
35
+ middleware.call(env)
36
+ expect(env.http_accept_language.user_preferred_languages).to eq %w{en}
37
+ env["HTTP_ACCEPT_LANGUAGE"] = "de"
38
+ middleware.call(env)
39
+ expect(env.http_accept_language.user_preferred_languages).to eq %w{de}
40
+ end
41
+
42
+ it "decodes the HTTP_ACCEPT_LANGUAGE header" do
43
+ request_with_header 'en-us,en-gb;q=0.8,en;q=0.6,es-419'
44
+ expect(r['user_preferred_languages']).to eq %w{en-US es-419 en-GB en}
45
+ end
46
+
47
+ it "finds the first available language" do
48
+ request_with_header 'en-us,en-gb;q=0.8,en;q=0.6,es-419', :preferred => %w(en en-GB)
49
+ expect(r['preferred_language_from']).to eq 'en-GB'
50
+ end
51
+
52
+ def request_with_header(header, params = {})
53
+ get "/", params, 'HTTP_ACCEPT_LANGUAGE' => header
54
+ end
55
+
56
+ def r
57
+ JSON.parse(last_response.body)
58
+ end
59
+
60
+ end
@@ -0,0 +1,65 @@
1
+ require 'http_accept_language/parser'
2
+
3
+ describe HttpAcceptLanguage::Parser do
4
+
5
+ def parser
6
+ @parser ||= HttpAcceptLanguage::Parser.new('en-us,en-gb;q=0.8,en;q=0.6,es-419')
7
+ end
8
+
9
+ it "should return empty array" do
10
+ parser.header = nil
11
+ expect(parser.user_preferred_languages).to eq []
12
+ end
13
+
14
+ it "should properly split" do
15
+ expect(parser.user_preferred_languages).to eq %w{en-US es-419 en-GB en}
16
+ end
17
+
18
+ it "should ignore jambled header" do
19
+ parser.header = 'odkhjf89fioma098jq .,.,'
20
+ expect(parser.user_preferred_languages).to eq []
21
+ end
22
+
23
+ it "should properly respect whitespace" do
24
+ parser.header = 'en-us, en-gb; q=0.8,en;q = 0.6,es-419'
25
+ expect(parser.user_preferred_languages).to eq %w{en-US es-419 en-GB en}
26
+ end
27
+
28
+ it "should find first available language" do
29
+ expect(parser.preferred_language_from(%w{en en-GB})).to eq "en-GB"
30
+ end
31
+
32
+ it "should find first compatible language" do
33
+ expect(parser.compatible_language_from(%w{en-hk})).to eq "en-hk"
34
+ expect(parser.compatible_language_from(%w{en})).to eq "en"
35
+ end
36
+
37
+ it "should find first compatible from user preferred" do
38
+ parser.header = 'en-us,de-de'
39
+ expect(parser.compatible_language_from(%w{de en})).to eq 'en'
40
+ end
41
+
42
+ it "should accept symbols as available languages" do
43
+ parser.header = 'en-us'
44
+ expect(parser.compatible_language_from([:"en-HK"])).to eq :"en-HK"
45
+ end
46
+
47
+ it "should accept and ignore wildcards" do
48
+ parser.header = 'en-US,en,*'
49
+ expect(parser.compatible_language_from([:"en-US"])).to eq :"en-US"
50
+ end
51
+
52
+ it "should sanitize available language names" do
53
+ expect(parser.sanitize_available_locales(%w{en_UK-x3 en-US-x1 ja_JP-x2 pt-BR-x5 es-419-x4})).to eq ["en-UK", "en-US", "ja-JP", "pt-BR", "es-419"]
54
+ end
55
+
56
+ it "should accept available language names as symbols and return them as strings" do
57
+ expect(parser.sanitize_available_locales([:en, :"en-US", :ca, :"ca-ES"])).to eq ["en", "en-US", "ca", "ca-ES"]
58
+ end
59
+
60
+ it "should find most compatible language from user preferred" do
61
+ parser.header = 'ja,en-gb,en-us,fr-fr'
62
+ expect(parser.language_region_compatible_from(%w{en-UK en-US ja-JP})).to eq "ja-JP"
63
+ end
64
+
65
+ end
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: http_accept_language_v2
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.2
5
+ platform: ruby
6
+ authors:
7
+ - iain
8
+ - yknx4
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2021-06-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rack-test
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: guard-rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rails
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '5.2'
77
+ - - "<"
78
+ - !ruby/object:Gem::Version
79
+ version: '7.0'
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '5.2'
87
+ - - "<"
88
+ - !ruby/object:Gem::Version
89
+ version: '7.0'
90
+ - !ruby/object:Gem::Dependency
91
+ name: cucumber
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ - !ruby/object:Gem::Dependency
105
+ name: aruba
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ description: Find out which locale the user preferes by reading the languages they
119
+ specified in their browser
120
+ email:
121
+ - iain@iain.nl
122
+ - me@ale.world
123
+ executables: []
124
+ extensions: []
125
+ extra_rdoc_files: []
126
+ files:
127
+ - ".github/workflows/tests.yml"
128
+ - ".gitignore"
129
+ - ".rspec"
130
+ - Gemfile
131
+ - Guardfile
132
+ - README.md
133
+ - Rakefile
134
+ - cucumber.yml
135
+ - features/rails_integration.feature
136
+ - features/steps/rails.rb
137
+ - features/support/rails_driver.rb
138
+ - http_accept_language.gemspec
139
+ - lib/http_accept_language.rb
140
+ - lib/http_accept_language/auto_locale.rb
141
+ - lib/http_accept_language/middleware.rb
142
+ - lib/http_accept_language/parser.rb
143
+ - lib/http_accept_language/railtie.rb
144
+ - lib/http_accept_language/version.rb
145
+ - spec/auto_locale_spec.rb
146
+ - spec/middleware_spec.rb
147
+ - spec/parser_spec.rb
148
+ homepage: https://github.com/yknx4/http_accept_language
149
+ licenses:
150
+ - MIT
151
+ metadata: {}
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubygems_version: 3.2.15
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: Find out which locale the user preferes by reading the languages they specified
171
+ in their browser
172
+ test_files: []