wovnrb 3.0.1 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +21 -10
- data/.rubocop_todo.yml +9 -44
- data/Gemfile +0 -5
- data/docker/docker-compose.yml +5 -0
- data/docker/rails/TestSite/app/controllers/custom_response_controller.rb +16 -0
- data/docker/rails/TestSite/config/routes.rb +1 -0
- data/docker/rails/TestSite/yarn.lock +9 -9
- data/lib/wovnrb.rb +1 -3
- data/lib/wovnrb/api_translator.rb +1 -1
- data/lib/wovnrb/headers.rb +30 -39
- data/lib/wovnrb/helpers/nokogumbo_helper.rb +7 -9
- data/lib/wovnrb/lang.rb +15 -14
- data/lib/wovnrb/railtie.rb +3 -1
- data/lib/wovnrb/services/html_converter.rb +7 -7
- data/lib/wovnrb/store.rb +5 -8
- data/lib/wovnrb/version.rb +1 -1
- data/test/lib/api_translator_test.rb +3 -4
- data/test/lib/lang_test.rb +5 -136
- data/test/lib/services/html_converter_test.rb +2 -2
- data/test/lib/wovnrb_test.rb +12 -12
- data/wovnrb.gemspec +1 -0
- metadata +8 -14
- data/.travis.yml +0 -14
- data/lib/wovnrb/text_caches/cache_base.rb +0 -53
- data/lib/wovnrb/text_caches/memory_cache.rb +0 -51
- data/test/lib/text_caches/cache_base_test.rb +0 -31
- data/test/lib/text_caches/memory_cache_test.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ceba766ab6d122f9c54e48ab267ada742f7efabb4fc19e1f9c0a7f5e5ba47983
|
4
|
+
data.tar.gz: dfde93503c625a1bed27cd4b65b44a5cff3adff0d883a0f0824546eb02bd111f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0af38a90017f6e69f344fa9304c5c79dcf242796d57de31b44900534263673e94910109535783272ba7ad8ebfac399389ca20894d8f1a0e50d6ecd99e921b1b
|
7
|
+
data.tar.gz: adfce2cdbb1b99aeeb2612d68eda7e115018186d1cea1d602dd16754532326288610cf1c5db8f1b77a44c044b2a52d35e398135f7a07cef9c19a836c627bb74e
|
data/.circleci/config.yml
CHANGED
@@ -1,18 +1,29 @@
|
|
1
|
-
version: 2
|
1
|
+
version: 2.1
|
2
|
+
|
3
|
+
orbs:
|
4
|
+
# https://github.com/CircleCI-Public/ruby-orb
|
5
|
+
ruby: circleci/ruby@1.1
|
2
6
|
|
3
7
|
jobs:
|
4
|
-
|
8
|
+
test:
|
9
|
+
parameters:
|
10
|
+
ruby-version:
|
11
|
+
type: string
|
5
12
|
docker:
|
6
|
-
- image:
|
13
|
+
- image: cimg/ruby:<< parameters.ruby-version >>
|
7
14
|
steps:
|
8
15
|
- checkout
|
9
|
-
- restore_cache:
|
10
|
-
keys:
|
11
|
-
- bundler-
|
12
16
|
- run: bundle install --path vendor/bundle --jobs=4
|
13
|
-
- save_cache:
|
14
|
-
key: bundler-{{ checksum "Gemfile.lock" }}
|
15
|
-
paths:
|
16
|
-
- vendor/bundle
|
17
17
|
- run: bundle exec rubocop
|
18
18
|
- run: bundle exec rake test
|
19
|
+
|
20
|
+
# https://circleci.com/blog/circleci-matrix-jobs/
|
21
|
+
workflows:
|
22
|
+
build_and_test:
|
23
|
+
jobs:
|
24
|
+
- test:
|
25
|
+
matrix:
|
26
|
+
parameters:
|
27
|
+
# https://github.com/CircleCI-Public/cimg-ruby
|
28
|
+
# only supports the last three ruby versions
|
29
|
+
ruby-version: ["2.5", "2.6", "2.7"]
|
data/.rubocop_todo.yml
CHANGED
@@ -6,17 +6,8 @@
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
Layout/EmptyLinesAroundAccessModifier:
|
12
|
-
Exclude:
|
13
|
-
- 'lib/wovnrb/text_caches/memory_cache.rb'
|
14
|
-
|
15
|
-
# Offense count: 1
|
16
|
-
# Cop supports --auto-correct.
|
17
|
-
Layout/EmptyLinesAroundMethodBody:
|
18
|
-
Exclude:
|
19
|
-
- 'test/lib/text_caches/memory_cache_test.rb'
|
9
|
+
Gemspec/RequiredRubyVersion:
|
10
|
+
Enabled: false
|
20
11
|
|
21
12
|
# Offense count: 11
|
22
13
|
# Cop supports --auto-correct.
|
@@ -25,13 +16,9 @@ Layout/ExtraSpacing:
|
|
25
16
|
Exclude:
|
26
17
|
- 'lib/wovnrb/lang.rb'
|
27
18
|
|
28
|
-
|
29
|
-
# Cop supports --auto-correct.
|
30
|
-
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
31
|
-
# SupportedStyles: special_inside_parentheses, consistent, align_braces
|
32
|
-
Layout/FirstHashElementIndentation:
|
19
|
+
Style/HashEachMethods:
|
33
20
|
Exclude:
|
34
|
-
- 'lib/wovnrb/
|
21
|
+
- 'lib/wovnrb/store.rb'
|
35
22
|
|
36
23
|
# Offense count: 4
|
37
24
|
# Cop supports --auto-correct.
|
@@ -42,13 +29,6 @@ Layout/HeredocIndentation:
|
|
42
29
|
- 'test/lib/lang_test.rb'
|
43
30
|
- 'test/lib/wovnrb_test.rb'
|
44
31
|
|
45
|
-
# Offense count: 1
|
46
|
-
# Cop supports --auto-correct.
|
47
|
-
# Configuration parameters: AllowForAlignment.
|
48
|
-
Layout/SpaceAroundOperators:
|
49
|
-
Exclude:
|
50
|
-
- 'lib/wovnrb/text_caches/memory_cache.rb'
|
51
|
-
|
52
32
|
# Offense count: 3
|
53
33
|
# Configuration parameters: AllowSafeAssignment.
|
54
34
|
Lint/AssignmentInCondition:
|
@@ -70,13 +50,6 @@ Lint/ImplicitStringConcatenation:
|
|
70
50
|
Exclude:
|
71
51
|
- 'test/lib/lang_test.rb'
|
72
52
|
|
73
|
-
# Offense count: 3
|
74
|
-
# Cop supports --auto-correct.
|
75
|
-
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
|
76
|
-
Lint/UnusedMethodArgument:
|
77
|
-
Exclude:
|
78
|
-
- 'lib/wovnrb/text_caches/cache_base.rb'
|
79
|
-
|
80
53
|
# Offense count: 5
|
81
54
|
Lint/UselessAssignment:
|
82
55
|
Exclude:
|
@@ -116,12 +89,13 @@ Metrics/MethodLength:
|
|
116
89
|
# Offense count: 12
|
117
90
|
Metrics/PerceivedComplexity:
|
118
91
|
Max: 22
|
92
|
+
Exclude:
|
93
|
+
- 'lib/wovnrb/headers.rb'
|
119
94
|
|
120
95
|
# Offense count: 3
|
121
96
|
Naming/AccessorMethodName:
|
122
97
|
Exclude:
|
123
98
|
- 'lib/wovnrb/services/wovn_logger.rb'
|
124
|
-
- 'lib/wovnrb/text_caches/cache_base.rb'
|
125
99
|
|
126
100
|
# Offense count: 120
|
127
101
|
# Configuration parameters: .
|
@@ -153,12 +127,6 @@ Style/ClassCheck:
|
|
153
127
|
Exclude:
|
154
128
|
- 'lib/wovnrb/store.rb'
|
155
129
|
|
156
|
-
# Offense count: 6
|
157
|
-
Style/ClassVars:
|
158
|
-
Exclude:
|
159
|
-
- 'lib/wovnrb/text_caches/cache_base.rb'
|
160
|
-
- 'lib/wovnrb/text_caches/memory_cache.rb'
|
161
|
-
|
162
130
|
# Offense count: 1
|
163
131
|
# Cop supports --auto-correct.
|
164
132
|
# Configuration parameters: Keywords.
|
@@ -183,8 +151,6 @@ Style/Documentation:
|
|
183
151
|
- 'lib/wovnrb/services/wovn_logger.rb'
|
184
152
|
- 'lib/wovnrb/settings.rb'
|
185
153
|
- 'lib/wovnrb/store.rb'
|
186
|
-
- 'lib/wovnrb/text_caches/cache_base.rb'
|
187
|
-
- 'lib/wovnrb/text_caches/memory_cache.rb'
|
188
154
|
|
189
155
|
# Offense count: 2
|
190
156
|
Style/DoubleNegation:
|
@@ -224,7 +190,6 @@ Style/IfUnlessModifier:
|
|
224
190
|
- 'Rakefile'
|
225
191
|
- 'lib/wovnrb/helpers/nokogumbo_helper.rb'
|
226
192
|
- 'lib/wovnrb/store.rb'
|
227
|
-
- 'lib/wovnrb/text_caches/memory_cache.rb'
|
228
193
|
|
229
194
|
# Offense count: 1
|
230
195
|
# Cop supports --auto-correct.
|
@@ -241,7 +206,6 @@ Style/NegatedIf:
|
|
241
206
|
Style/PreferredHashMethods:
|
242
207
|
Exclude:
|
243
208
|
- 'lib/wovnrb/store.rb'
|
244
|
-
- 'lib/wovnrb/text_caches/memory_cache.rb'
|
245
209
|
|
246
210
|
# Offense count: 2
|
247
211
|
# Cop supports --auto-correct.
|
@@ -297,7 +261,7 @@ Style/ZeroLengthPredicate:
|
|
297
261
|
# Offense count: 1436
|
298
262
|
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
299
263
|
# URISchemes: http, https
|
300
|
-
|
264
|
+
Layout/LineLength:
|
301
265
|
Max: 1424
|
302
266
|
|
303
267
|
Style/FrozenStringLiteralComment:
|
@@ -310,6 +274,7 @@ Style/SafeNavigation:
|
|
310
274
|
Enabled: false
|
311
275
|
|
312
276
|
AllCops:
|
277
|
+
NewCops: enable
|
313
278
|
Exclude:
|
314
279
|
- 'docker/**/*'
|
315
|
-
- 'vendor/**/*'
|
280
|
+
- 'vendor/**/*'
|
data/Gemfile
CHANGED
data/docker/docker-compose.yml
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
class CustomResponseController < ApplicationController
|
2
|
+
skip_before_action :verify_authenticity_token2
|
3
|
+
|
4
|
+
def make_response
|
5
|
+
response_args_json = params[:response]
|
6
|
+
raise ActionController::BadRequest unless response_args_json
|
7
|
+
|
8
|
+
(response_args_json[:headers] || {}).each do |name, value|
|
9
|
+
response.headers[name] = value
|
10
|
+
end
|
11
|
+
|
12
|
+
render inline: response_args_json[:body],
|
13
|
+
status: response_args_json[:status],
|
14
|
+
content_type: response_args_json[:content_type]
|
15
|
+
end
|
16
|
+
end
|
@@ -2592,9 +2592,9 @@ dns-equal@^1.0.0:
|
|
2592
2592
|
integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0=
|
2593
2593
|
|
2594
2594
|
dns-packet@^1.3.1:
|
2595
|
-
version "1.3.
|
2596
|
-
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.
|
2597
|
-
integrity sha512-
|
2595
|
+
version "1.3.4"
|
2596
|
+
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f"
|
2597
|
+
integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==
|
2598
2598
|
dependencies:
|
2599
2599
|
ip "^1.1.0"
|
2600
2600
|
safe-buffer "^5.0.1"
|
@@ -5863,9 +5863,9 @@ postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1:
|
|
5863
5863
|
uniq "^1.0.1"
|
5864
5864
|
|
5865
5865
|
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
|
5866
|
-
version "7.0.
|
5867
|
-
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.
|
5868
|
-
integrity sha512-
|
5866
|
+
version "7.0.36"
|
5867
|
+
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.36.tgz#056f8cffa939662a8f5905950c07d5285644dfcb"
|
5868
|
+
integrity sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==
|
5869
5869
|
dependencies:
|
5870
5870
|
chalk "^2.4.2"
|
5871
5871
|
source-map "^0.6.1"
|
@@ -7581,9 +7581,9 @@ wrappy@1:
|
|
7581
7581
|
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
7582
7582
|
|
7583
7583
|
ws@^6.2.1:
|
7584
|
-
version "6.2.
|
7585
|
-
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.
|
7586
|
-
integrity sha512-
|
7584
|
+
version "6.2.2"
|
7585
|
+
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e"
|
7586
|
+
integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==
|
7587
7587
|
dependencies:
|
7588
7588
|
async-limiter "~1.0.0"
|
7589
7589
|
|
data/lib/wovnrb.rb
CHANGED
@@ -9,7 +9,6 @@ require 'nokogumbo'
|
|
9
9
|
require 'active_support'
|
10
10
|
require 'json'
|
11
11
|
require 'wovnrb/helpers/nokogumbo_helper'
|
12
|
-
require 'wovnrb/text_caches/cache_base'
|
13
12
|
require 'wovnrb/railtie' if defined?(Rails)
|
14
13
|
require 'wovnrb/version'
|
15
14
|
|
@@ -18,9 +17,8 @@ module Wovnrb
|
|
18
17
|
def initialize(app, opts = {})
|
19
18
|
@app = app
|
20
19
|
@store = Store.instance
|
21
|
-
opts = opts.
|
20
|
+
opts = opts.transform_keys(&:to_s)
|
22
21
|
@store.update_settings(opts)
|
23
|
-
CacheBase.set_single(@store.settings)
|
24
22
|
end
|
25
23
|
|
26
24
|
def call(env)
|
data/lib/wovnrb/headers.rb
CHANGED
@@ -1,17 +1,10 @@
|
|
1
1
|
module Wovnrb
|
2
2
|
class Headers
|
3
|
-
attr_reader :unmasked_url
|
4
|
-
attr_reader :url
|
5
|
-
attr_reader :protocol
|
6
|
-
attr_reader :unmasked_host
|
7
|
-
attr_reader :host
|
8
|
-
attr_reader :unmasked_pathname
|
9
|
-
attr_reader :pathname
|
10
|
-
attr_reader :pathname_with_trailing_slash_if_present
|
3
|
+
attr_reader :unmasked_url, :url, :protocol, :unmasked_host, :host, :unmasked_pathname, :pathname, :pathname_with_trailing_slash_if_present
|
11
4
|
|
12
5
|
# Generates new instance of Wovnrb::Headers.
|
13
6
|
# Its parameters are set by parsing env variable.
|
14
|
-
|
7
|
+
|
15
8
|
def initialize(env, settings)
|
16
9
|
request = Rack::Request.new(env)
|
17
10
|
|
@@ -42,21 +35,21 @@ module Wovnrb
|
|
42
35
|
@pathname, @query = @env['REQUEST_URI'].split('?')
|
43
36
|
@pathname = settings['url_pattern'] == 'path' ? remove_lang(@pathname, lang_code) : @pathname
|
44
37
|
@query ||= ''
|
45
|
-
@url = "#{@host}#{@pathname}#{(
|
46
|
-
if
|
38
|
+
@url = "#{@host}#{@pathname}#{(@query.empty? ? '' : '?') + remove_lang(@query, lang_code)}"
|
39
|
+
if settings['query'].empty?
|
40
|
+
@query = ''
|
41
|
+
else
|
47
42
|
query_vals = []
|
48
43
|
settings['query'].each do |qv|
|
49
44
|
rx = Regexp.new("(^|&)(?<query_val>#{qv}[^&]+)(&|$)")
|
50
45
|
m = @query.match(rx)
|
51
46
|
query_vals.push(m[:query_val]) if m && m[:query_val]
|
52
47
|
end
|
53
|
-
@query = if
|
54
|
-
"?#{query_vals.sort.join('&')}"
|
55
|
-
else
|
48
|
+
@query = if query_vals.empty?
|
56
49
|
''
|
50
|
+
else
|
51
|
+
"?#{query_vals.sort.join('&')}"
|
57
52
|
end
|
58
|
-
else
|
59
|
-
@query = ''
|
60
53
|
end
|
61
54
|
@query = remove_lang(@query, lang_code)
|
62
55
|
@pathname_with_trailing_slash_if_present = @pathname
|
@@ -115,11 +108,11 @@ module Wovnrb
|
|
115
108
|
case @settings['url_pattern']
|
116
109
|
when 'query'
|
117
110
|
lang_param_name = @settings['lang_param_name']
|
118
|
-
if location
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
111
|
+
location = if location =~ /\?/
|
112
|
+
"#{location}&#{lang_param_name}=#{lang_code}"
|
113
|
+
else
|
114
|
+
"#{location}?#{lang_param_name}=#{lang_code}"
|
115
|
+
end
|
123
116
|
when 'subdomain'
|
124
117
|
location = "#{lang_code.downcase}.#{location}"
|
125
118
|
# when 'path'
|
@@ -173,7 +166,7 @@ module Wovnrb
|
|
173
166
|
lang_param_name = @settings['lang_param_name']
|
174
167
|
uri.sub(/(^|\?|&)#{lang_param_name}=#{lang_code}(&|$)/, '\1').gsub(/(\?|&)$/, '')
|
175
168
|
when 'subdomain'
|
176
|
-
rp = Regexp.new(
|
169
|
+
rp = Regexp.new("(^|(//))#{lang_code}\\.", 'i')
|
177
170
|
uri.sub(rp, '\1')
|
178
171
|
# when 'path'
|
179
172
|
else
|
@@ -182,24 +175,22 @@ module Wovnrb
|
|
182
175
|
end
|
183
176
|
|
184
177
|
def out(headers)
|
185
|
-
r = Regexp.new(
|
178
|
+
r = Regexp.new("//#{@host}")
|
186
179
|
lang_code = Store.instance.settings['custom_lang_aliases'][self.lang_code] || self.lang_code
|
187
|
-
if lang_code != @settings['default_lang'] && headers.key?('Location') && headers['Location'] =~ r
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
headers['Location'] = headers['Location'].sub(/(\/\/[^\/]+)/, '\1/' + lang_code)
|
202
|
-
end
|
180
|
+
if lang_code != @settings['default_lang'] && headers.key?('Location') && headers['Location'] =~ r && !@settings['ignore_globs'].ignore?(headers['Location'])
|
181
|
+
case @settings['url_pattern']
|
182
|
+
when 'query'
|
183
|
+
headers['Location'] += if headers['Location'] =~ /\?/
|
184
|
+
'&'
|
185
|
+
else
|
186
|
+
'?'
|
187
|
+
end
|
188
|
+
headers['Location'] += "#{@settings['lang_param_name']}=#{lang_code}"
|
189
|
+
when 'subdomain'
|
190
|
+
headers['Location'] = headers['Location'].sub(/\/\/([^.]+)/, "//#{lang_code}.\\1")
|
191
|
+
# when 'path'
|
192
|
+
else
|
193
|
+
headers['Location'] = headers['Location'].sub(/(\/\/[^\/]+)/, "\\1/#{lang_code}")
|
203
194
|
end
|
204
195
|
end
|
205
196
|
headers
|
@@ -2,15 +2,13 @@ module Wovnrb
|
|
2
2
|
module Helpers
|
3
3
|
module NokogumboHelper
|
4
4
|
def parse_html(html_string, encoding = 'UTF-8')
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
dom
|
5
|
+
if html_string.strip[0..999] =~ /<html/i
|
6
|
+
d = Nokogiri::HTML5(html_string)
|
7
|
+
d.encoding = encoding
|
8
|
+
d
|
9
|
+
else
|
10
|
+
parse_fragment(html_string, encoding)
|
11
|
+
end
|
14
12
|
end
|
15
13
|
|
16
14
|
# https://www.rubydoc.info/gems/nokogumbo/Nokogiri/HTML5#fragment-class_method
|
data/lib/wovnrb/lang.rb
CHANGED
@@ -146,46 +146,47 @@ module Wovnrb
|
|
146
146
|
if uri.host.downcase === headers.host.downcase
|
147
147
|
case pattern
|
148
148
|
when 'subdomain'
|
149
|
-
sub_d = href.match(/\/\/([
|
149
|
+
sub_d = href.match(/\/\/([^.]*)\./)[1]
|
150
150
|
sub_code = Lang.get_code(sub_d)
|
151
151
|
new_href = if sub_code && sub_code.casecmp(code_to_add).zero?
|
152
152
|
href.sub(Regexp.new(code_to_add, 'i'), code_to_add.downcase)
|
153
153
|
else
|
154
|
-
href.sub(/(\/\/)([
|
154
|
+
href.sub(/(\/\/)([^.]*)/, "\\1#{code_to_add.downcase}.\\2")
|
155
155
|
end
|
156
156
|
when 'query'
|
157
157
|
new_href = add_query_lang_code(href, code_to_add, lang_param_name)
|
158
158
|
else # path
|
159
|
-
new_href = href.sub(/([
|
159
|
+
new_href = href.sub(/([^.]*\.[^\/]*)(\/|$)/, "\\1/#{code_to_add}/")
|
160
160
|
end
|
161
161
|
end
|
162
162
|
elsif href
|
163
163
|
case pattern
|
164
164
|
when 'subdomain'
|
165
|
-
lang_url = headers.protocol
|
166
|
-
current_dir = headers.pathname.sub(/[^\/]*\.[
|
167
|
-
new_href =
|
165
|
+
lang_url = "#{headers.protocol}://#{code_to_add.downcase}.#{headers.host}"
|
166
|
+
current_dir = headers.pathname.sub(/[^\/]*\.[^.]{2,6}$/, '')
|
167
|
+
new_href = case href
|
168
|
+
when /^\.\..*$/
|
168
169
|
# ../path
|
169
|
-
lang_url
|
170
|
-
|
170
|
+
"#{lang_url}/#{href.gsub(/^\.\.\//, '')}"
|
171
|
+
when /^\..*$/
|
171
172
|
# ./path
|
172
|
-
lang_url
|
173
|
-
|
173
|
+
"#{lang_url}#{current_dir}/#{href.gsub(/^\.\//, '')}"
|
174
|
+
when /^\/.*$/
|
174
175
|
# /path
|
175
176
|
lang_url + href
|
176
177
|
else
|
177
178
|
# path
|
178
|
-
lang_url
|
179
|
+
"#{lang_url}#{current_dir}/#{href}"
|
179
180
|
end
|
180
181
|
when 'query'
|
181
182
|
new_href = add_query_lang_code(href, code_to_add, lang_param_name)
|
182
183
|
else # path
|
183
184
|
if href =~ /^\//
|
184
|
-
new_href =
|
185
|
+
new_href = "/#{code_to_add}#{href}"
|
185
186
|
else
|
186
|
-
current_dir = headers.pathname.sub(/[^\/]*\.[
|
187
|
+
current_dir = headers.pathname.sub(/[^\/]*\.[^.]{2,6}$/, '')
|
187
188
|
current_dir = '/' if current_dir == ''
|
188
|
-
new_href =
|
189
|
+
new_href = "/#{code_to_add}#{current_dir}#{href}"
|
189
190
|
end
|
190
191
|
end
|
191
192
|
end
|
data/lib/wovnrb/railtie.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
module Wovnrb
|
2
2
|
class Railtie < Rails::Railtie
|
3
3
|
initializer 'wovnrb.configure_rails_initialization' do |app|
|
4
|
-
|
4
|
+
install_middleware = Rails.configuration.wovnrb.fetch(:install_middleware, true)
|
5
|
+
|
6
|
+
app.middleware.insert_before(0, Wovnrb::Interceptor) if install_middleware
|
5
7
|
end
|
6
8
|
end
|
7
9
|
end
|
@@ -41,7 +41,7 @@ module Wovnrb
|
|
41
41
|
|
42
42
|
@dom.traverse { |node| transform_node(node, marker) }
|
43
43
|
|
44
|
-
insert_snippet(true)
|
44
|
+
insert_snippet(adds_backend_error_mark: true)
|
45
45
|
insert_hreflang_tags
|
46
46
|
inject_lang_html_tag
|
47
47
|
|
@@ -79,7 +79,7 @@ module Wovnrb
|
|
79
79
|
return unless classes.present?
|
80
80
|
|
81
81
|
ignored_classes = @store.settings['ignore_class']
|
82
|
-
should_be_ignored = (ignored_classes & classes.split
|
82
|
+
should_be_ignored = (ignored_classes & classes.split).present?
|
83
83
|
|
84
84
|
put_replace_marker(node, marker) if should_be_ignored
|
85
85
|
end
|
@@ -147,10 +147,10 @@ module Wovnrb
|
|
147
147
|
end
|
148
148
|
|
149
149
|
def widget_urls
|
150
|
-
[@store.settings['api_url']
|
150
|
+
["#{@store.settings['api_url']}/widget", 'j.wovn.io', 'j.dev-wovn.io:3000']
|
151
151
|
end
|
152
152
|
|
153
|
-
def insert_snippet(adds_backend_error_mark
|
153
|
+
def insert_snippet(adds_backend_error_mark: true)
|
154
154
|
parent_node = @dom.at_css('head') || @dom.at_css('body') || @dom.at_css('html')
|
155
155
|
return unless parent_node
|
156
156
|
|
@@ -162,10 +162,10 @@ module Wovnrb
|
|
162
162
|
# do this so that there will be a closing tag (better compatibility with browsers)
|
163
163
|
insert_node.content = ''
|
164
164
|
|
165
|
-
if
|
166
|
-
parent_node.children.first.add_previous_sibling(insert_node)
|
167
|
-
else
|
165
|
+
if parent_node.children.empty?
|
168
166
|
parent_node.add_child(insert_node)
|
167
|
+
else
|
168
|
+
parent_node.children.first.add_previous_sibling(insert_node)
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
data/lib/wovnrb/store.rb
CHANGED
@@ -141,19 +141,16 @@ module Wovnrb
|
|
141
141
|
end
|
142
142
|
@settings.delete('user_token')
|
143
143
|
|
144
|
-
|
144
|
+
case @settings['url_pattern']
|
145
|
+
when 'path'
|
145
146
|
@settings['url_pattern_reg'] = "/(?<lang>[^/.?]+)"
|
146
|
-
|
147
|
+
when 'query'
|
147
148
|
@settings['url_pattern_reg'] = "((\\?.*&)|\\?)#{@settings['lang_param_name']}=(?<lang>[^&]+)(&|$)"
|
148
|
-
|
149
|
+
when 'subdomain'
|
149
150
|
@settings['url_pattern_reg'] = "^(?<lang>[^.]+)\."
|
150
151
|
end
|
151
152
|
|
152
|
-
@settings['test_mode'] =
|
153
|
-
false
|
154
|
-
else
|
155
|
-
true
|
156
|
-
end
|
153
|
+
@settings['test_mode'] = !(@settings['test_mode'] != true || @settings['test_mode'] != 'on')
|
157
154
|
|
158
155
|
if @settings['wovn_dev_mode']
|
159
156
|
if @settings['api_url'] == self.class.default_settings['api_url']
|
data/lib/wovnrb/version.rb
CHANGED
@@ -85,11 +85,10 @@ module Wovnrb
|
|
85
85
|
compress(stub_response_json)
|
86
86
|
end
|
87
87
|
response_headers = { 'Content-Encoding' => response[:encoding] || 'gzip' }
|
88
|
-
|
89
|
-
|
90
|
-
|
88
|
+
stub_request(:post, api_url)
|
89
|
+
.with(body: compressed_data, headers: headers)
|
90
|
+
.to_return(status: response[:status_code] || 200, body: stub_response, headers: response_headers)
|
91
91
|
|
92
|
-
stub
|
93
92
|
end
|
94
93
|
end
|
95
94
|
|
data/test/lib/lang_test.rb
CHANGED
@@ -21,9 +21,10 @@ module Wovnrb
|
|
21
21
|
|
22
22
|
def test_iso_639_1_normalization
|
23
23
|
Wovnrb::Lang::LANG.each do |_, l|
|
24
|
-
|
24
|
+
case l[:code]
|
25
|
+
when 'zh-CHS'
|
25
26
|
assert_equal('zh-Hans', Lang.iso_639_1_normalization('zh-CHS'))
|
26
|
-
|
27
|
+
when 'zh-CHT'
|
27
28
|
assert_equal('zh-Hant', Lang.iso_639_1_normalization('zh-CHT'))
|
28
29
|
else
|
29
30
|
assert_equal(l[:code], Lang.iso_639_1_normalization(l[:code]))
|
@@ -89,7 +90,7 @@ module Wovnrb
|
|
89
90
|
assert_equal('http://zh-cht.wovn.io/topics/31', lang.add_lang_code('http://wovn.io/topics/31', 'subdomain', h))
|
90
91
|
end
|
91
92
|
|
92
|
-
def
|
93
|
+
def test_add_lang_code_trad_chinese2
|
93
94
|
lang = Lang.new('zh-cht')
|
94
95
|
h = Wovnrb::Headers.new(Wovnrb.get_env('url' => 'http://zh-cht.wovn.io'), Wovnrb.get_settings('url_pattern' => 'subdomain', 'url_pattern_reg' => '^(?<lang>[^.]+).'))
|
95
96
|
assert_equal('http://zh-cht.wovn.io/topics/31', lang.add_lang_code('/topics/31', 'subdomain', h))
|
@@ -107,7 +108,7 @@ module Wovnrb
|
|
107
108
|
assert_equal('//zh-cht.google.com', lang.add_lang_code('//google.com', 'subdomain', h))
|
108
109
|
end
|
109
110
|
|
110
|
-
def
|
111
|
+
def test_add_lang_code_no_protocol2
|
111
112
|
lang = Lang.new('zh-cht')
|
112
113
|
h = Wovnrb::Headers.new(Wovnrb.get_env('url' => 'https://zh-cht.wovn.io'), Wovnrb.get_settings('url_pattern' => 'subdomain', 'url_pattern_reg' => '^(?<lang>[^.]+).'))
|
113
114
|
assert_equal('//google.com', lang.add_lang_code('//google.com', 'subdomain', h))
|
@@ -311,138 +312,6 @@ module Wovnrb
|
|
311
312
|
assert_equal('/fr/index.html', lang.add_lang_code('index.html', 'path', headers))
|
312
313
|
end
|
313
314
|
|
314
|
-
def generate_body(param = '')
|
315
|
-
body = case param
|
316
|
-
when 'ignore_parent'
|
317
|
-
"<html><body><h1>Mr. Belvedere Fan Club</h1>
|
318
|
-
<div wovn-ignore><p>Hello</p></div>
|
319
|
-
</body></html>"
|
320
|
-
when 'ignore_everything'
|
321
|
-
"<html><body wovn-ignore><h1>Mr. Belvedere Fan Club</h1>
|
322
|
-
<div><p>Hello</p></div>
|
323
|
-
</body></html>"
|
324
|
-
when 'ignore_parent_translated_in_japanese'
|
325
|
-
"<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.ignore-page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://ignore-page.com/\"></head><body><h1><!--wovn-src:Mr. Belvedere Fan Club-->ベルベデアさんファンクラブ</h1>
|
326
|
-
<div wovn-ignore=\"\"><p>Hello</p></div>
|
327
|
-
</body></html>
|
328
|
-
"
|
329
|
-
when 'translated_in_japanese'
|
330
|
-
"<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://page.com/\"></head><body><h1><!--wovn-src:Mr. Belvedere Fan Club-->ベルベデアさんファンクラブ</h1>
|
331
|
-
<div><p><!--wovn-src:Hello-->こんにちは</p></div>
|
332
|
-
</body></html>
|
333
|
-
"
|
334
|
-
when 'ignore_everything_translated'
|
335
|
-
"<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.ignore-page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://ignore-page.com/\"></head><body wovn-ignore=\"\"><h1>Mr. Belvedere Fan Club</h1>
|
336
|
-
<div><p>Hello</p></div>
|
337
|
-
</body></html>
|
338
|
-
"
|
339
|
-
when 'empty'
|
340
|
-
'<html><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore><p>Hello</p></div></body></html>'
|
341
|
-
when 'empty_single_quote'
|
342
|
-
"<html><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore=''><p>Hello</p></div></body></html>"
|
343
|
-
when 'empty_double_quote'
|
344
|
-
'<html><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore=''><p>Hello</p></div></body></html>'
|
345
|
-
when 'value_single_quote'
|
346
|
-
"<html><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore='value'><p>Hello</p></div></body></html>"
|
347
|
-
when 'value_double_quote'
|
348
|
-
'<html><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore="value"><p>Hello</p></div></body></html>'
|
349
|
-
when 'empty_translated'
|
350
|
-
"<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.ignore-page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://ignore-page.com/\"></head><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore=\"\"><p>Hello</p></div></body></html>\n"
|
351
|
-
when 'empty_single_quote_translated'
|
352
|
-
"<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.ignore-page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://ignore-page.com/\"></head><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore=\"\"><p>Hello</p></div></body></html>\n"
|
353
|
-
when 'empty_double_quote_translated'
|
354
|
-
"<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.ignore-page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://ignore-page.com/\"></head><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore=\"\"><p>Hello</p></div></body></html>\n"
|
355
|
-
when 'value_single_quote_translated'
|
356
|
-
"<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.ignore-page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://ignore-page.com/\"></head><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore=\"value\"><p>Hello</p></div></body></html>\n"
|
357
|
-
when 'value_double_quote_translated'
|
358
|
-
"<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.ignore-page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://ignore-page.com/\"></head><body><h1>Mr.BelvedereFanClub</h1><div wovn-ignore=\"value\"><p>Hello</p></div></body></html>\n"
|
359
|
-
when 'meta_img_alt_tags_translated'
|
360
|
-
"<html lang=\"ja\"><head><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><meta name=\"description\" content=\"こんにちは\">\n<meta name=\"title\" content=\"こんにちは\">\n<meta property=\"og:title\" content=\"こんにちは\">\n<meta property=\"og:description\" content=\"こんにちは\">\n<meta property=\"twitter:title\" content=\"こんにちは\">\n<meta property=\"twitter:description\" content=\"こんにちは\"><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://page.com/\"></head>\n<body><h1><!--wovn-src:Mr. Belvedere Fan Club-->ベルベデアさんファンクラブ</h1>\n<div><p><!--wovn-src:Hello-->こんにちは</p></div>\n<!--wovn-src:Hello--><img src=\"http://example.com/photo.png\" alt=\"こんにちは\">\n</body></html>\n"
|
361
|
-
when 'meta_img_alt_tags'
|
362
|
-
"<html><head><meta name =\"description\" content=\"Hello\">\n<meta name=\"title\" content=\"Hello\">\n<meta property=\"og:title\" content=\"Hello\">\n<meta property=\"og:description\" content=\"Hello\">\n<meta property=\"twitter:title\" content=\"Hello\">\n<meta property=\"twitter:description\" content=\"Hello\"></head>
|
363
|
-
<body><h1>Mr. Belvedere Fan Club</h1>
|
364
|
-
<div><p>Hello</p></div>
|
365
|
-
<img src=\"http://example.com/photo.png\" alt=\"Hello\">
|
366
|
-
</body></html>"
|
367
|
-
when 'a_href_javascript'
|
368
|
-
"<html><body><h1>Mr. Belvedere Fan Club</h1>
|
369
|
-
<div><p><a href=\"javascript:void(0)\">Hello</a></p></div>
|
370
|
-
</body></html>"
|
371
|
-
when 'a_href_javascript_translated'
|
372
|
-
"<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"ja\" href=\"http://ja.page.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://page.com/\"></head><body><h1><!--wovn-src:Mr. Belvedere Fan Club-->ベルベデアさんファンクラブ</h1>
|
373
|
-
<div><p><a href=\"javascript:void(0)\"><!--wovn-src:Hello-->こんにちは</a></p></div>
|
374
|
-
</body></html>
|
375
|
-
"
|
376
|
-
when 'unified_values'
|
377
|
-
<<-HTML
|
378
|
-
<html><body>
|
379
|
-
<div>
|
380
|
-
a <span>b</span> c
|
381
|
-
</div>
|
382
|
-
<div>
|
383
|
-
a<span>b</span>
|
384
|
-
</div>
|
385
|
-
<div>
|
386
|
-
<span> b </span>c
|
387
|
-
</div>
|
388
|
-
</body></html>
|
389
|
-
HTML
|
390
|
-
|
391
|
-
when 'unified_values_ja'
|
392
|
-
<<-HTML
|
393
|
-
<html lang=\"ja\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=&backend=true&currentLang=ja&defaultLang=en&urlPattern=path&langCodeAliases={}&version=#{Wovnrb::VERSION}\"> </script><link rel=\"alternate\" hreflang=\"en\" href=\"http://page.com/\"></head><body>
|
394
|
-
<div><!--wovn-src:
|
395
|
-
a -->\u3042<span><!--wovn-src:b-->\u3044</span><!--wovn-src: c
|
396
|
-
-->\u3046</div>
|
397
|
-
<div><!--wovn-src:
|
398
|
-
a-->\u200B<span><!--wovn-src:b-->\u3044</span><!--wovn-src:-->\u3046
|
399
|
-
</div>
|
400
|
-
<div>
|
401
|
-
<!--wovn-src:-->\u3042<span><!--wovn-src: b -->\u3044</span><!--wovn-src:c
|
402
|
-
-->\u200B</div>
|
403
|
-
|
404
|
-
</body></html>
|
405
|
-
HTML
|
406
|
-
|
407
|
-
else # "" case
|
408
|
-
"<html><body><h1>Mr. Belvedere Fan Club</h1>
|
409
|
-
<div><p>Hello</p></div>
|
410
|
-
</body></html>"
|
411
|
-
end
|
412
|
-
|
413
|
-
body
|
414
|
-
end
|
415
|
-
|
416
|
-
def generate_dom(param = '')
|
417
|
-
Wovnrb.to_dom(generate_body(param))
|
418
|
-
end
|
419
|
-
|
420
|
-
def generate_values
|
421
|
-
values = {}
|
422
|
-
values['text_vals'] = {
|
423
|
-
'Hello' => { 'ja' => [{ 'data' => 'こんにちは' }] },
|
424
|
-
'Mr. Belvedere Fan Club' => { 'ja' => [{ 'data' => 'ベルベデアさんファンクラブ' }] }
|
425
|
-
}
|
426
|
-
values
|
427
|
-
end
|
428
|
-
|
429
|
-
def generate_unified_values
|
430
|
-
{
|
431
|
-
'html_text_vals' => {
|
432
|
-
'a<span>b</span>c' =>
|
433
|
-
{ 'ja' =>
|
434
|
-
[{ 'data' => 'あ<span>い</span>う' }] },
|
435
|
-
'a<span>b</span>' =>
|
436
|
-
{ 'ja' =>
|
437
|
-
[{ 'data' => '<span>い</span>う' }] },
|
438
|
-
'<span>b</span>c' =>
|
439
|
-
{ 'ja' =>
|
440
|
-
[{ 'data' => 'あ<span>い</span>' }] }
|
441
|
-
|
442
|
-
}
|
443
|
-
}
|
444
|
-
end
|
445
|
-
|
446
315
|
def test_get_code_from_custom_lang
|
447
316
|
store = Store.instance
|
448
317
|
store.settings['custom_lang_aliases'] = { 'ja' => 'staging-ja' }
|
@@ -25,10 +25,10 @@ module Wovnrb
|
|
25
25
|
|
26
26
|
def test_build_api_compatible_html_not_fail_for_big_content
|
27
27
|
long_string = 'a' * 60_000
|
28
|
-
converter = prepare_html_converter(
|
28
|
+
converter = prepare_html_converter("<html><body><p>#{long_string}</p></body></html>", supported_langs: %w[en vi])
|
29
29
|
converted_html, = converter.build_api_compatible_html
|
30
30
|
|
31
|
-
expected_html = "<html lang=\"en\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=123456&backend=true&currentLang=en&defaultLang=en&urlPattern=query&langCodeAliases={}&langParamName=wovn&version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/?wovn=vi\"></head><body><p
|
31
|
+
expected_html = "<html lang=\"en\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=123456&backend=true&currentLang=en&defaultLang=en&urlPattern=query&langCodeAliases={}&langParamName=wovn&version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/?wovn=vi\"></head><body><p>#{long_string}</p></body></html>"
|
32
32
|
assert_equal(expected_html, converted_html)
|
33
33
|
end
|
34
34
|
|
data/test/lib/wovnrb_test.rb
CHANGED
@@ -24,7 +24,7 @@ class WovnrbTest < Minitest::Test
|
|
24
24
|
'</body></html>'
|
25
25
|
].join
|
26
26
|
|
27
|
-
assert_switch_lang('en', 'ja', body, expected_body, true)
|
27
|
+
assert_switch_lang('en', 'ja', body, expected_body, api_expected: true)
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_switch_lang_with_input_tags
|
@@ -52,14 +52,14 @@ class WovnrbTest < Minitest::Test
|
|
52
52
|
'</body></html>'
|
53
53
|
].join
|
54
54
|
|
55
|
-
assert_switch_lang('en', 'ja', body, expected_body, true)
|
55
|
+
assert_switch_lang('en', 'ja', body, expected_body, api_expected: true)
|
56
56
|
end
|
57
57
|
|
58
58
|
def test_switch_lang_of_html_fragment_with_japanese_translations
|
59
59
|
bodies = ['<span>Hello</span>'].join
|
60
60
|
expected_bodies = ['<span><!--wovn-src:Hello-->こんにちは</span>'].join
|
61
61
|
|
62
|
-
assert_switch_lang('en', 'ja', bodies, expected_bodies, true)
|
62
|
+
assert_switch_lang('en', 'ja', bodies, expected_bodies, api_expected: true)
|
63
63
|
end
|
64
64
|
|
65
65
|
def test_switch_lang_splitted_body
|
@@ -68,7 +68,7 @@ class WovnrbTest < Minitest::Test
|
|
68
68
|
'</body></html>'].join
|
69
69
|
expected_bodies = ["<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"//j.wovn.io/1\" async=\"true\" data-wovnio=\"key=123456&backend=true&currentLang=ja&defaultLang=en&urlPattern=subdomain&langCodeAliases={}&version=WOVN.rb_#{Wovnrb::VERSION}\" data-wovnio-type=\"fallback_snippet\"></script><link rel=\"alternate\" hreflang=\"en\" href=\"http://page.com/\"></head><body><h1>Mr. Belvedere Fan Club</h1><div><p>Hello</p></div></body></html>"].join
|
70
70
|
|
71
|
-
assert_switch_lang('en', 'ja', bodies, expected_bodies, true)
|
71
|
+
assert_switch_lang('en', 'ja', bodies, expected_bodies, api_expected: true)
|
72
72
|
end
|
73
73
|
|
74
74
|
def test_switch_lang_of_html_fragment_in_splitted_body
|
@@ -76,7 +76,7 @@ class WovnrbTest < Minitest::Test
|
|
76
76
|
'<option value="2">2</option></select>'].join
|
77
77
|
expected_body = ['<select name="test"><option value="1">1</option><option value="2">2</option></select>'].join
|
78
78
|
|
79
|
-
assert_switch_lang('en', 'ja', body, expected_body, true)
|
79
|
+
assert_switch_lang('en', 'ja', body, expected_body, api_expected: true)
|
80
80
|
end
|
81
81
|
|
82
82
|
def test_switch_lang_missing_values
|
@@ -88,7 +88,7 @@ class WovnrbTest < Minitest::Test
|
|
88
88
|
</body></html>
|
89
89
|
"
|
90
90
|
|
91
|
-
assert_switch_lang('en', 'ja', body, expected_body, true)
|
91
|
+
assert_switch_lang('en', 'ja', body, expected_body, api_expected: true)
|
92
92
|
end
|
93
93
|
|
94
94
|
def test_switch_lang_on_fragment_with_translate_fragment_false
|
@@ -96,7 +96,7 @@ class WovnrbTest < Minitest::Test
|
|
96
96
|
<div><p>Hello</p></div>"
|
97
97
|
|
98
98
|
Wovnrb::Store.instance.settings['translate_fragment'] = false
|
99
|
-
assert_switch_lang('en', 'ja', body, body, false)
|
99
|
+
assert_switch_lang('en', 'ja', body, body, api_expected: false)
|
100
100
|
end
|
101
101
|
|
102
102
|
def test_switch_lang_on_fragment_with_translate_fragment_true
|
@@ -106,7 +106,7 @@ class WovnrbTest < Minitest::Test
|
|
106
106
|
<div><p><!--wovn-src:Hello-->こんにちは</p></div>"
|
107
107
|
|
108
108
|
Wovnrb::Store.instance.settings['translate_fragment'] = true
|
109
|
-
assert_switch_lang('en', 'ja', body, expected_body, true)
|
109
|
+
assert_switch_lang('en', 'ja', body, expected_body, api_expected: true)
|
110
110
|
end
|
111
111
|
|
112
112
|
def test_switch_lang_ignores_amp
|
@@ -120,7 +120,7 @@ class WovnrbTest < Minitest::Test
|
|
120
120
|
</html>
|
121
121
|
HTML
|
122
122
|
|
123
|
-
assert_switch_lang('en', 'ja', body, body, false)
|
123
|
+
assert_switch_lang('en', 'ja', body, body, api_expected: false)
|
124
124
|
end
|
125
125
|
|
126
126
|
def test_switch_lang_ignores_amp_defined_with_symbol_attribute
|
@@ -133,7 +133,7 @@ HTML
|
|
133
133
|
</html>
|
134
134
|
HTML
|
135
135
|
|
136
|
-
assert_switch_lang('en', 'ja', body, body, false)
|
136
|
+
assert_switch_lang('en', 'ja', body, body, api_expected: false)
|
137
137
|
end
|
138
138
|
|
139
139
|
def test_call_without_path_ignored_should_change_environment
|
@@ -249,7 +249,7 @@ HTML
|
|
249
249
|
assert_equal(unaffected_env != app_mock.env, affected)
|
250
250
|
end
|
251
251
|
|
252
|
-
def assert_switch_lang(original_lang, target_lang, body, expected_body, api_expected
|
252
|
+
def assert_switch_lang(original_lang, target_lang, body, expected_body, api_expected: true)
|
253
253
|
subdomain = target_lang == original_lang ? '' : "#{target_lang}."
|
254
254
|
interceptor = Wovnrb::Interceptor.new(get_app)
|
255
255
|
|
@@ -303,7 +303,7 @@ HTML
|
|
303
303
|
|
304
304
|
def initialize(opts = {})
|
305
305
|
@params = {}
|
306
|
-
if opts.key?(:params) && opts[:params].
|
306
|
+
if opts.key?(:params) && opts[:params].instance_of?(Hash)
|
307
307
|
opts[:params].each do |key, val|
|
308
308
|
@params[key] = val
|
309
309
|
end
|
data/wovnrb.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.description = 'Ruby gem for WOVN backend on Rack.'
|
12
12
|
spec.homepage = 'https://wovn.io'
|
13
13
|
spec.license = 'MIT'
|
14
|
+
spec.required_ruby_version = '>= 2.5'
|
14
15
|
|
15
16
|
files = `git ls-files -z`.split("\x0")
|
16
17
|
files.delete('BEFORE_PUSHING')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wovnrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wovn Technologies, Inc.
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -405,7 +405,6 @@ files:
|
|
405
405
|
- ".gitignore"
|
406
406
|
- ".rubocop.yml"
|
407
407
|
- ".rubocop_todo.yml"
|
408
|
-
- ".travis.yml"
|
409
408
|
- Gemfile
|
410
409
|
- LICENSE.txt
|
411
410
|
- PULL_REQUEST_TEMPLATE
|
@@ -428,6 +427,7 @@ files:
|
|
428
427
|
- docker/rails/TestSite/app/channels/application_cable/connection.rb
|
429
428
|
- docker/rails/TestSite/app/controllers/application_controller.rb
|
430
429
|
- docker/rails/TestSite/app/controllers/concerns/.keep
|
430
|
+
- docker/rails/TestSite/app/controllers/custom_response_controller.rb
|
431
431
|
- docker/rails/TestSite/app/controllers/pages_controller.rb
|
432
432
|
- docker/rails/TestSite/app/controllers/redirects_controller.rb
|
433
433
|
- docker/rails/TestSite/app/helpers/application_helper.rb
|
@@ -527,8 +527,6 @@ files:
|
|
527
527
|
- lib/wovnrb/services/wovn_logger.rb
|
528
528
|
- lib/wovnrb/settings.rb
|
529
529
|
- lib/wovnrb/store.rb
|
530
|
-
- lib/wovnrb/text_caches/cache_base.rb
|
531
|
-
- lib/wovnrb/text_caches/memory_cache.rb
|
532
530
|
- lib/wovnrb/version.rb
|
533
531
|
- makefile
|
534
532
|
- test/fixtures/html/test.html
|
@@ -541,8 +539,6 @@ files:
|
|
541
539
|
- test/lib/services/html_replace_marker_test.rb
|
542
540
|
- test/lib/services/wovn_logger_test.rb
|
543
541
|
- test/lib/store_test.rb
|
544
|
-
- test/lib/text_caches/cache_base_test.rb
|
545
|
-
- test/lib/text_caches/memory_cache_test.rb
|
546
542
|
- test/lib/wovnrb_test.rb
|
547
543
|
- test/test_helper.rb
|
548
544
|
- wovnrb.gemspec
|
@@ -550,7 +546,7 @@ homepage: https://wovn.io
|
|
550
546
|
licenses:
|
551
547
|
- MIT
|
552
548
|
metadata: {}
|
553
|
-
post_install_message:
|
549
|
+
post_install_message:
|
554
550
|
rdoc_options: []
|
555
551
|
require_paths:
|
556
552
|
- lib
|
@@ -558,15 +554,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
558
554
|
requirements:
|
559
555
|
- - ">="
|
560
556
|
- !ruby/object:Gem::Version
|
561
|
-
version: '
|
557
|
+
version: '2.5'
|
562
558
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
563
559
|
requirements:
|
564
560
|
- - ">="
|
565
561
|
- !ruby/object:Gem::Version
|
566
562
|
version: '0'
|
567
563
|
requirements: []
|
568
|
-
rubygems_version: 3.
|
569
|
-
signing_key:
|
564
|
+
rubygems_version: 3.1.4
|
565
|
+
signing_key:
|
570
566
|
specification_version: 4
|
571
567
|
summary: Gem for WOVN.io
|
572
568
|
test_files:
|
@@ -580,7 +576,5 @@ test_files:
|
|
580
576
|
- test/lib/services/html_replace_marker_test.rb
|
581
577
|
- test/lib/services/wovn_logger_test.rb
|
582
578
|
- test/lib/store_test.rb
|
583
|
-
- test/lib/text_caches/cache_base_test.rb
|
584
|
-
- test/lib/text_caches/memory_cache_test.rb
|
585
579
|
- test/lib/wovnrb_test.rb
|
586
580
|
- test/test_helper.rb
|
data/.travis.yml
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
cache: bundler
|
3
|
-
rvm:
|
4
|
-
# Supported versions are
|
5
|
-
# > Ruby version:2.2 or later
|
6
|
-
# https://wovn.io/support/ruby-library/
|
7
|
-
- 2.5.0
|
8
|
-
- 2.4.3
|
9
|
-
- 2.3.6
|
10
|
-
- 2.2.9
|
11
|
-
# There is no support for 2.1 officially, but test for now.
|
12
|
-
- 2.1.10
|
13
|
-
before_install:
|
14
|
-
- gem update bundler --no-document
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'active_support/inflector'
|
2
|
-
|
3
|
-
module Wovnrb
|
4
|
-
class CacheBase
|
5
|
-
@@strategy_map = {
|
6
|
-
memory: :memory_cache
|
7
|
-
}
|
8
|
-
|
9
|
-
@@default_base_config = {
|
10
|
-
strategy: :memory
|
11
|
-
}
|
12
|
-
|
13
|
-
@@singleton_cache = nil
|
14
|
-
def self.get_single
|
15
|
-
raise 'cache is not initialized' unless @@singleton_cache
|
16
|
-
|
17
|
-
@@singleton_cache
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.set_single(config)
|
21
|
-
@@singleton_cache = build(config)
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.reset_cache
|
25
|
-
@@singleton_cache = nil
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.build(config)
|
29
|
-
@config = @@default_base_config.merge config
|
30
|
-
|
31
|
-
strategy = @@strategy_map[@config[:strategy]]
|
32
|
-
raise "Invalid strategy: #{strategy}" unless strategy
|
33
|
-
|
34
|
-
strategy_sym = strategy.to_sym
|
35
|
-
begin
|
36
|
-
require "wovnrb/text_caches/#{strategy_sym}"
|
37
|
-
rescue LoadError => e
|
38
|
-
raise "Could not find #{strategy_sym} (#{e})"
|
39
|
-
end
|
40
|
-
|
41
|
-
strategy_class = Wovnrb.const_get(ActiveSupport::Inflector.camelize(strategy_sym))
|
42
|
-
strategy_class.new(config)
|
43
|
-
end
|
44
|
-
|
45
|
-
def put(key, value)
|
46
|
-
raise NotImplementedError.new('put is not defined')
|
47
|
-
end
|
48
|
-
|
49
|
-
def get(key)
|
50
|
-
raise NotImplementedError.new('put is not defined')
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'active_support/cache'
|
2
|
-
require 'lz4-ruby'
|
3
|
-
|
4
|
-
module Wovnrb
|
5
|
-
class MemoryCache < CacheBase
|
6
|
-
@@default_memory_cache_config = {
|
7
|
-
cache_megabytes: 200,
|
8
|
-
ttl_seconds: 300
|
9
|
-
}
|
10
|
-
|
11
|
-
def initialize(config)
|
12
|
-
@config = merge_setting(@@default_memory_cache_config, config)
|
13
|
-
cache_size = @config[:cache_megabytes].to_f
|
14
|
-
ttl = @config[:ttl_seconds].to_i
|
15
|
-
@cache_store = ActiveSupport::Cache::MemoryStore.new(expires_in: ttl.seconds, size: cache_size.megabytes)
|
16
|
-
end
|
17
|
-
|
18
|
-
def put(key, value)
|
19
|
-
@cache_store.write(key, compress(value))
|
20
|
-
end
|
21
|
-
|
22
|
-
def get(key)
|
23
|
-
stored_value =@cache_store.fetch(key)
|
24
|
-
decompress(stored_value) if stored_value
|
25
|
-
end
|
26
|
-
|
27
|
-
def options
|
28
|
-
@cache_store.options.clone
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
def merge_setting(original_config, merging_config)
|
33
|
-
config = original_config.clone
|
34
|
-
config.keys.each do |key|
|
35
|
-
key_string = key.to_s
|
36
|
-
if merging_config.has_key?(key_string) && merging_config[key_string].present?
|
37
|
-
config[key] = merging_config[key_string]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
config
|
41
|
-
end
|
42
|
-
|
43
|
-
def compress(value)
|
44
|
-
LZ4.compress(value)
|
45
|
-
end
|
46
|
-
|
47
|
-
def decompress(value)
|
48
|
-
LZ4.decompress(value, value.bytesize, 'UTF-8')
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'wovnrb/text_caches/cache_base'
|
2
|
-
require 'minitest/autorun'
|
3
|
-
|
4
|
-
class CacheBaseTest < Minitest::Test
|
5
|
-
def setup
|
6
|
-
Wovnrb::CacheBase.reset_cache
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_build
|
10
|
-
cache = Wovnrb::CacheBase.build({})
|
11
|
-
assert_equal('Wovnrb::MemoryCache', cache.class.name)
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_build_with_invalid_strategy
|
15
|
-
assert_raises RuntimeError do
|
16
|
-
Wovnrb::CacheBase.build(strategy: :invalid)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_set_and_get_single
|
21
|
-
Wovnrb::CacheBase.set_single({})
|
22
|
-
cache = Wovnrb::CacheBase.get_single
|
23
|
-
assert_equal('Wovnrb::MemoryCache', cache.class.name)
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_get_single_without_set
|
27
|
-
assert_raises RuntimeError do
|
28
|
-
Wovnrb::CacheBase.get_single
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
require 'wovnrb/text_caches/cache_base'
|
2
|
-
require 'wovnrb/text_caches/memory_cache'
|
3
|
-
require 'minitest/autorun'
|
4
|
-
require 'timecop'
|
5
|
-
|
6
|
-
class MemoryCacheTest < Minitest::Test
|
7
|
-
def test_initialize
|
8
|
-
memory = Wovnrb::MemoryCache.new(
|
9
|
-
'cache_megabytes' => 1,
|
10
|
-
'ttl_seconds' => 1
|
11
|
-
)
|
12
|
-
option = memory.options
|
13
|
-
assert_equal(1.megabytes, option[:size])
|
14
|
-
assert_equal(1.megabytes, option[:size])
|
15
|
-
assert_equal(1.seconds, option[:expires_in])
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_initialize_without_cache_megabytes
|
19
|
-
memory = Wovnrb::MemoryCache.new(
|
20
|
-
'ttl_seconds' => 1
|
21
|
-
)
|
22
|
-
option = memory.options
|
23
|
-
assert_equal(200.megabytes, option[:size])
|
24
|
-
assert_equal(1.seconds, option[:expires_in])
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_initialize_without_ttl
|
28
|
-
memory = Wovnrb::MemoryCache.new(
|
29
|
-
'cache_megabytes' => 1
|
30
|
-
)
|
31
|
-
option = memory.options
|
32
|
-
assert_equal(1.megabytes, option[:size])
|
33
|
-
assert_equal(300.seconds, option[:expires_in])
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_initialize_with_no_config
|
37
|
-
memory = Wovnrb::MemoryCache.new({})
|
38
|
-
option = memory.options
|
39
|
-
assert_equal(200.megabytes, option[:size])
|
40
|
-
assert_equal(300.seconds, option[:expires_in])
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_put_without_cache
|
44
|
-
memory = Wovnrb::MemoryCache.new({})
|
45
|
-
memory.put('a', 'b')
|
46
|
-
assert_equal('b', memory.get('a'))
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_put_with_cache
|
50
|
-
memory = Wovnrb::MemoryCache.new({})
|
51
|
-
memory.put('a', 'b')
|
52
|
-
memory.put('a', 'b2')
|
53
|
-
assert_equal('b2', memory.get('a'))
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_get_with_cache
|
57
|
-
memory = Wovnrb::MemoryCache.new({})
|
58
|
-
memory.put('a', 'b')
|
59
|
-
assert_equal('b', memory.get('a'))
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_get_without_cache
|
63
|
-
memory = Wovnrb::MemoryCache.new({})
|
64
|
-
assert_nil(memory.get('a'))
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_get_with_timeout
|
69
|
-
memory = Wovnrb::MemoryCache.new({})
|
70
|
-
memory.put('a', 'b')
|
71
|
-
Timecop.travel(1.day.since)
|
72
|
-
assert_nil(memory.get('a'))
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_get_with_over_memory
|
76
|
-
# ActiveSupport::Cache::MemoryStore has 240 bytes overhead per instance
|
77
|
-
memory = Wovnrb::MemoryCache.new(
|
78
|
-
'cache_megabytes' => 400.0 / 1000 / 1000
|
79
|
-
)
|
80
|
-
memory.put('a', 'c')
|
81
|
-
memory.put('b', 'd')
|
82
|
-
assert_nil(memory.get('a'))
|
83
|
-
assert_equal('d', memory.get('b'))
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_get_with_utf8
|
87
|
-
memory = Wovnrb::MemoryCache.new({})
|
88
|
-
memory.put('http://www.example.com', 'あいうえお')
|
89
|
-
assert_equal('あいうえお', memory.get('http://www.example.com'))
|
90
|
-
end
|
91
|
-
end
|