wovnrb 2.2.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21db13334fd0ceefeba7a6d0f23a13c035d8ca2e97796f2c5342659369b4a5d9
4
- data.tar.gz: 6453345eb832513563decad6050d3b44d2f100c203c8e0f3f9cbbd8d6cc833b5
3
+ metadata.gz: b1d7702d09e87b697371b1c5609040910fa9383d55a05ebac5d1ae668b04013c
4
+ data.tar.gz: c18162741b2cbb82137687cd6b9a0176cc576cae8230c3720d4ebd19df065656
5
5
  SHA512:
6
- metadata.gz: a43841cb1cd9a2fcda906663b8c8a5d46e751e37d202591f42d7eea17603df6523e8eca82538c49b7db20e9d3b1d8fd51d5e64e482ee71422384f109f699eef3
7
- data.tar.gz: 6e87c0aa31e2b6853d295e600ba6fef63beb3cc5d0154a872e19a51cdc3a6d7828b1bc7ea21346dfee72c888576885256d11c84e1085608e2a5c55e693312359
6
+ metadata.gz: 3285cbeb773a4415e82fd8cc06b375d4e3e0adea37c2e026699f401cd2692a67972aef40513a209b1d39686fb52664bc3964d6d8be69088d716b960f9e8e1ef3
7
+ data.tar.gz: ea6c7b83a2a2b6c16c5d7d5310ec17e021a4e1b87524cc60de3794230890aeb8742205e7197ba9bbd74d492092523f59bcd48f576440729e6a014919d11f4313
data/README.md CHANGED
@@ -82,6 +82,7 @@ lang_param_name | | 'wovn'
82
82
  query | | []
83
83
  ignore_class | | []
84
84
  translate_fragment | | true
85
+ ignore_paths | | []
85
86
 
86
87
  ### 2.1. project_token
87
88
 
@@ -161,6 +162,17 @@ This option allows to disable translating partial HTML content. By default,
161
162
  partial HTML content is translated but no widget snippet is added. Set
162
163
  `translate_fragment` to `false` to prevent translating partial HTML content.
163
164
 
165
+ ### 2.9 ignore_paths
166
+
167
+ This parameter tells WOVN.rb to not localize content withing given directories.
168
+
169
+ The directories given will only be matched against the beginning of the URL path.
170
+
171
+ For instance, if you want to not localize the admin directory of your website, you should add the following to you WOVN.rb configuration.
172
+ ```
173
+ 'ignore_paths' => ['/admin/']
174
+ ```
175
+
164
176
  ## 3. Contributing
165
177
 
166
178
  1. Fork it ( https://github.com/WOVNio/wovnrb/fork )
@@ -32,14 +32,21 @@ module Wovnrb
32
32
 
33
33
  @env = env
34
34
  headers = Headers.new(env, @store.settings)
35
+ default_lang = @store.settings['default_lang']
35
36
  return @app.call(env) if @store.settings['test_mode'] && @store.settings['test_url'] != headers.url
36
37
 
37
38
  # redirect if the path is set to the default language (for SEO purposes)
38
- if headers.path_lang == @store.settings['default_lang']
39
- redirect_headers = headers.redirect(@store.settings['default_lang'])
39
+ if headers.path_lang == default_lang
40
+ redirect_headers = headers.redirect(default_lang)
40
41
  return [307, redirect_headers, ['']]
41
42
  end
42
43
 
44
+ # if path containing language code is ignored, do nothing
45
+ if headers.lang_code != default_lang && ignore_path?(headers.unmasked_pathname_without_trailing_slash)
46
+ status, res_headers, body = @app.call(env)
47
+
48
+ return output(headers, status, res_headers, body)
49
+ end
43
50
  # pass to application
44
51
  status, res_headers, body = @app.call(headers.request_out)
45
52
 
@@ -51,7 +58,7 @@ module Wovnrb
51
58
  return output(headers, status, res_headers, body) if request.params['wovn_disable'] == true
52
59
 
53
60
  @store.settings.update_dynamic_settings!(request.params)
54
- return output(headers, status, res_headers, body) if @store.settings['ignore_globs'].any? { |g| g.match?(headers.pathname) }
61
+ return output(headers, status, res_headers, body) if ignore_path?(headers.pathname)
55
62
 
56
63
  body = switch_lang(headers, body) unless status.to_s =~ /^1|302/
57
64
 
@@ -105,6 +112,10 @@ module Wovnrb
105
112
  !html_body.xpath('//html[@wovn-ignore]').empty?
106
113
  end
107
114
 
115
+ def ignore_path?(path)
116
+ @store.settings['ignore_globs'].ignore?(path)
117
+ end
118
+
108
119
  # Checks if a given HTML body is an Accelerated Mobile Page (AMP).
109
120
  # To do so, it looks at the required attributes for the HTML tag:
110
121
  # https://www.ampproject.org/docs/tutorials/create/basic_markup.
@@ -39,7 +39,6 @@ module Wovnrb
39
39
  else
40
40
  @env['HTTP_HOST']
41
41
  end
42
- @env['wovnrb.target_lang'] = lang_code
43
42
  @host = settings['url_pattern'] == 'subdomain' ? remove_lang(@host, lang_code) : @host
44
43
  @pathname, @query = @env['REQUEST_URI'].split('?')
45
44
  @pathname = settings['url_pattern'] == 'path' ? remove_lang(@pathname, lang_code) : @pathname
@@ -66,6 +65,10 @@ module Wovnrb
66
65
  @redis_url = "#{@host}#{@pathname}#{@query}"
67
66
  end
68
67
 
68
+ def unmasked_pathname_without_trailing_slash
69
+ @unmasked_pathname.chomp('/')
70
+ end
71
+
69
72
  # Get the language code of the current request
70
73
  #
71
74
  # @return [String] The lang code of the current page
@@ -150,6 +153,7 @@ module Wovnrb
150
153
  end
151
154
 
152
155
  def request_out(_def_lang = @settings['default_lang'])
156
+ @env['wovnrb.target_lang'] = lang_code
153
157
  case @settings['url_pattern']
154
158
  when 'query'
155
159
  @env['REQUEST_URI'] = remove_lang(@env['REQUEST_URI']) if @env.key?('REQUEST_URI')
@@ -203,19 +207,21 @@ module Wovnrb
203
207
  r = Regexp.new('//' + @host)
204
208
  lang_code = Store.instance.settings['custom_lang_aliases'][self.lang_code] || self.lang_code
205
209
  if lang_code != @settings['default_lang'] && headers.key?('Location') && headers['Location'] =~ r
206
- case @settings['url_pattern']
207
- when 'query'
208
- headers['Location'] += if headers['Location'] =~ /\?/
209
- '&'
210
- else
211
- '?'
212
- end
213
- headers['Location'] += "#{@settings['lang_param_name']}=#{lang_code}"
214
- when 'subdomain'
215
- headers['Location'] = headers['Location'].sub(/\/\/([^.]+)/, '//' + lang_code + '.\1')
216
- # when 'path'
217
- else
218
- headers['Location'] = headers['Location'].sub(/(\/\/[^\/]+)/, '\1/' + lang_code)
210
+ unless @settings['ignore_globs'].ignore?(headers['Location'])
211
+ case @settings['url_pattern']
212
+ when 'query'
213
+ headers['Location'] += if headers['Location'] =~ /\?/
214
+ '&'
215
+ else
216
+ '?'
217
+ end
218
+ headers['Location'] += "#{@settings['lang_param_name']}=#{lang_code}"
219
+ when 'subdomain'
220
+ headers['Location'] = headers['Location'].sub(/\/\/([^.]+)/, '//' + lang_code + '.\1')
221
+ # when 'path'
222
+ else
223
+ headers['Location'] = headers['Location'].sub(/(\/\/[^\/]+)/, '\1/' + lang_code)
224
+ end
219
225
  end
220
226
  end
221
227
  headers
@@ -7,7 +7,7 @@ module Wovnrb
7
7
 
8
8
  def [](key)
9
9
  return @dynamic_settings[key] if @dynamic_settings.key?(key)
10
- return ignore_globs if key == 'ignore_globs'
10
+ return IgnoreGlobsWrapper.new(ignore_globs) if key == 'ignore_globs'
11
11
 
12
12
  super(key)
13
13
  end
@@ -35,5 +35,13 @@ module Wovnrb
35
35
  'wovn_token' => 'project_token',
36
36
  'wovn_ignore_paths' => 'ignore_paths'
37
37
  }.freeze
38
+
39
+ class IgnoreGlobsWrapper < Array
40
+ def ignore?(uri)
41
+ path = Addressable::URI.parse(uri).path
42
+
43
+ any? { |glob| glob.match?(path) }
44
+ end
45
+ end
38
46
  end
39
47
  end
@@ -1,3 +1,3 @@
1
1
  module Wovnrb
2
- VERSION = '2.2.0'.freeze
2
+ VERSION = '2.2.1'.freeze
3
3
  end
@@ -279,6 +279,49 @@ module Wovnrb
279
279
  assert_equal('http://wovn.io/test', env['HTTP_REFERER'])
280
280
  end
281
281
 
282
+ def test_out_should_add_lang_code_to_redirection
283
+ sut = Wovnrb::Headers.new(
284
+ Wovnrb.get_env(
285
+ 'SERVER_NAME' => 'wovn.io',
286
+ 'REQUEST_URI' => '/ja/test',
287
+ 'HTTP_REFERER' => 'http://wovn.io/ja/test'
288
+ ),
289
+ Wovnrb.get_settings(
290
+ 'default_lang' => 'en',
291
+ 'supported_langs' => %w[en ja],
292
+ 'url_pattern' => 'path',
293
+ 'url_pattern_reg' => '/(?<lang>[^/.?]+)'
294
+ )
295
+ )
296
+ headers = {
297
+ 'Location' => 'http://wovn.io/'
298
+ }
299
+
300
+ assert_equal('http://wovn.io/ja/', sut.out(headers)['Location'])
301
+ end
302
+
303
+ def test_out_should_not_add_lang_code_to_ignored_redirection
304
+ sut = Wovnrb::Headers.new(
305
+ Wovnrb.get_env(
306
+ 'SERVER_NAME' => 'wovn.io',
307
+ 'REQUEST_URI' => '/ja/test',
308
+ 'HTTP_REFERER' => 'http://wovn.io/ja/test'
309
+ ),
310
+ Wovnrb.get_settings(
311
+ 'default_lang' => 'en',
312
+ 'supported_langs' => %w[en ja],
313
+ 'url_pattern' => 'path',
314
+ 'url_pattern_reg' => '/(?<lang>[^/.?]+)',
315
+ 'ignore_paths' => ['/static/']
316
+ )
317
+ )
318
+ headers = {
319
+ 'Location' => 'http://wovn.io/static/'
320
+ }
321
+
322
+ assert_equal('http://wovn.io/static/', sut.out(headers)['Location'])
323
+ end
324
+
282
325
  def test_out_http_referer_subdomain_with_custom_lang_code
283
326
  Store.instance.update_settings('custom_lang_aliases' => { 'ja' => 'staging-ja' })
284
327
  h = Wovnrb::Headers.new(
@@ -108,8 +108,119 @@ HTML
108
108
  assert_switch_lang('en', 'ja', body, body, false)
109
109
  end
110
110
 
111
+ def test_call_without_path_ignored_should_change_environment
112
+ settings = {
113
+ 'project_token' => '123456',
114
+ 'url_pattern' => 'path',
115
+ 'default_lang' => 'ja',
116
+ 'supported_langs' => %w[ja en],
117
+ 'ignore_paths' => ['/en/ignored']
118
+ }
119
+ env = {
120
+ 'rack.input' => '',
121
+ 'rack.request.query_string' => '',
122
+ 'rack.request.query_hash' => {},
123
+ 'HTTP_HOST' => 'test.com',
124
+ 'REQUEST_URI' => '/en/not_ignored',
125
+ 'PATH_INFO' => '/en/not_ignored'
126
+ }
127
+
128
+ assert_call_affects_env(settings, env, mock_api: true, affected: true)
129
+ end
130
+
131
+ def test_call_with_path_ignored_with_language_code_should_change_environment
132
+ settings = {
133
+ 'project_token' => '123456',
134
+ 'url_pattern' => 'path',
135
+ 'default_lang' => 'ja',
136
+ 'supported_langs' => %w[ja en],
137
+ 'ignore_paths' => ['/en/ignored']
138
+ }
139
+ env = {
140
+ 'rack.input' => '',
141
+ 'rack.request.query_string' => '',
142
+ 'rack.request.query_hash' => {},
143
+ 'HTTP_HOST' => 'test.com',
144
+ 'REQUEST_URI' => '/ignored',
145
+ 'PATH_INFO' => '/ignored'
146
+ }
147
+
148
+ assert_call_affects_env(settings, env, mock_api: false, affected: true)
149
+ end
150
+
151
+ def test_call_with_path_ignored_without_language_code_should_change_environment
152
+ settings = {
153
+ 'project_token' => '123456',
154
+ 'url_pattern' => 'path',
155
+ 'default_lang' => 'ja',
156
+ 'supported_langs' => %w[ja en],
157
+ 'ignore_paths' => ['/ignored']
158
+ }
159
+ env = {
160
+ 'rack.input' => '',
161
+ 'rack.request.query_string' => '',
162
+ 'rack.request.query_hash' => {},
163
+ 'HTTP_HOST' => 'test.com',
164
+ 'REQUEST_URI' => '/en/ignored',
165
+ 'PATH_INFO' => '/en/ignored'
166
+ }
167
+
168
+ assert_call_affects_env(settings, env, mock_api: false, affected: true)
169
+ end
170
+
171
+ def test_call_with_path_ignored_without_language_code_in_original_language_should_change_environment
172
+ settings = {
173
+ 'project_token' => '123456',
174
+ 'url_pattern' => 'path',
175
+ 'default_lang' => 'ja',
176
+ 'supported_langs' => %w[ja en],
177
+ 'ignore_paths' => ['/ignored']
178
+ }
179
+ env = {
180
+ 'rack.input' => '',
181
+ 'rack.request.query_string' => '',
182
+ 'rack.request.query_hash' => {},
183
+ 'HTTP_HOST' => 'test.com',
184
+ 'REQUEST_URI' => '/ignored',
185
+ 'PATH_INFO' => '/ignored'
186
+ }
187
+
188
+ assert_call_affects_env(settings, env, mock_api: false, affected: true)
189
+ end
190
+
191
+ def test_call_with_path_ignored_should_not_change_environment
192
+ settings = {
193
+ 'project_token' => '123456',
194
+ 'url_pattern' => 'path',
195
+ 'default_lang' => 'ja',
196
+ 'supported_langs' => %w[ja en],
197
+ 'ignore_paths' => ['/en/ignored']
198
+ }
199
+ env = {
200
+ 'rack.input' => '',
201
+ 'rack.request.query_string' => '',
202
+ 'rack.request.query_hash' => {},
203
+ 'HTTP_HOST' => 'test.com',
204
+ 'REQUEST_URI' => '/en/ignored',
205
+ 'PATH_INFO' => '/en/ignored'
206
+ }
207
+
208
+ assert_call_affects_env(settings, env, mock_api: false, affected: false)
209
+ end
210
+
111
211
  private
112
212
 
213
+ def assert_call_affects_env(settings, env, mock_api:, affected:)
214
+ app_mock = get_app
215
+ sut = Wovnrb::Interceptor.new(app_mock, settings)
216
+ unaffected_env = env
217
+
218
+ mock_translation_api_response('', '') if mock_api
219
+ sut.call(env.clone)
220
+
221
+ assert_equal(unaffected_env != app_mock.env, affected)
222
+ end
223
+
113
224
  def assert_switch_lang(original_lang, target_lang, body, expected_body, api_expected = true)
114
225
  subdomain = target_lang == original_lang ? '' : "#{target_lang}."
115
226
  interceptor = Wovnrb::Interceptor.new(get_app)
@@ -160,7 +271,7 @@ HTML
160
271
  end
161
272
 
162
273
  class RackMock
163
- attr_accessor :params
274
+ attr_accessor :params, :env
164
275
 
165
276
  def initialize(opts = {})
166
277
  @params = {}
@@ -59,7 +59,8 @@ module Wovnrb
59
59
  end
60
60
 
61
61
  def get_settings(options = {})
62
- settings = {}
62
+ settings = Wovnrb::Store.default_settings
63
+
63
64
  settings['project_token'] = 'OHYx9'
64
65
  settings['url_pattern'] = 'path'
65
66
  settings['url_pattern_reg'] = '/(?<lang>[^/.?]+)'
@@ -68,7 +69,8 @@ module Wovnrb
68
69
  settings['api_url'] = 'http://localhost/v0/values'
69
70
  settings['default_lang'] = 'en'
70
71
  settings['supported_langs'] = %w[en ja]
71
- settings.merge(options)
72
+
73
+ Wovnrb::Settings.new.merge(settings.merge(options))
72
74
  end
73
75
 
74
76
  def get_env(options = {})
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wovnrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Sandford
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-07-11 00:00:00.000000000 Z
12
+ date: 2019-10-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport