wovnrb 3.2.0 → 3.5.0
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 +4 -4
- data/.rubocop.yml +5 -0
- data/README.en.md +21 -16
- data/README.ja.md +6 -6
- data/Rakefile +0 -1
- data/docker/rails/TestSite/Gemfile +1 -1
- data/docker/rails/TestSite/start.sh +0 -1
- data/docker/rails/TestSite/yarn.lock +3 -3
- data/lib/wovnrb/api_translator.rb +48 -33
- data/lib/wovnrb/headers.rb +4 -4
- data/lib/wovnrb/helpers/nokogumbo_helper.rb +1 -1
- data/lib/wovnrb/lang.rb +3 -3
- data/lib/wovnrb/services/html_converter.rb +4 -0
- data/lib/wovnrb/store.rb +9 -4
- data/lib/wovnrb/version.rb +1 -1
- data/lib/wovnrb.rb +3 -3
- data/test/lib/api_translator_test.rb +65 -22
- data/test/lib/headers_test.rb +2 -2
- data/test/lib/services/html_converter_test.rb +2 -2
- data/test/test_helper.rb +1 -1
- data/wovnrb.gemspec +3 -2
- metadata +23 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13d349b3045beb3370a29aca8ebe22f93fdcdeb143a7fefe0f4ecb031b8ffda9
|
4
|
+
data.tar.gz: da704d4f640423bc7a5c85151d3e531e95d564949812a032a925326b3a278219
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de57bbecbd55635636928d9de85a7e3e196098476684cdac3cc1f6f399434543dfd7cc7afa0cb947676cd9403c37d9122d82fa1c60dd20a304cf4cb3e5481ad4
|
7
|
+
data.tar.gz: aa54a84bb9b8a4d42126283ba7ca17c00214c6daf745132c1f7a4c4b50407772e8b6c8bd141f483e8d1b95b02ba3181e047a6ee51b0898daec75b688ed32881a
|
data/.rubocop.yml
CHANGED
data/README.en.md
CHANGED
@@ -39,8 +39,8 @@ Insert the following into either config/application.rb or config/environments/.
|
|
39
39
|
|
40
40
|
config.wovnrb = {
|
41
41
|
:project_token => 'EnS!t3',
|
42
|
-
:default_lang => '
|
43
|
-
:supported_langs => ['en'],
|
42
|
+
:default_lang => 'ja',
|
43
|
+
:supported_langs => ['ja', en'],
|
44
44
|
:url_pattern => 'path'
|
45
45
|
}
|
46
46
|
|
@@ -60,8 +60,8 @@ require 'wovnrb'
|
|
60
60
|
|
61
61
|
use Wovnrb::Interceptor, {
|
62
62
|
:project_token => 'EnS!t3',
|
63
|
-
:default_lang => '
|
64
|
-
:supported_langs => ['en'],
|
63
|
+
:default_lang => 'ja',
|
64
|
+
:supported_langs => ['ja', 'en'],
|
65
65
|
:url_pattern => 'path'
|
66
66
|
}
|
67
67
|
|
@@ -74,18 +74,19 @@ After completing setup, start the Ruby Application, and make sure the WOVN.io li
|
|
74
74
|
|
75
75
|
The following is a list of the WOVN.io Ruby Library's valid parameters.
|
76
76
|
|
77
|
-
Parameter Name
|
78
|
-
|
79
|
-
project_token
|
80
|
-
default_lang
|
81
|
-
supported_langs
|
82
|
-
url_pattern
|
83
|
-
lang_param_name
|
84
|
-
query
|
85
|
-
ignore_class
|
86
|
-
translate_fragment
|
87
|
-
ignore_paths
|
88
|
-
install_middleware
|
77
|
+
Parameter Name | Required | Default Setting
|
78
|
+
----------------------| -------- | ----------------
|
79
|
+
project_token | yes | ''
|
80
|
+
default_lang | yes | 'ja'
|
81
|
+
supported_langs | yes | ['ja', 'en']
|
82
|
+
url_pattern | yes | 'path'
|
83
|
+
lang_param_name | | 'wovn'
|
84
|
+
query | | []
|
85
|
+
ignore_class | | []
|
86
|
+
translate_fragment | | true
|
87
|
+
ignore_paths | | []
|
88
|
+
install_middleware | | true
|
89
|
+
compress_api_requests | | true
|
89
90
|
|
90
91
|
### 2.1. project_token
|
91
92
|
|
@@ -196,3 +197,7 @@ WOVN.rb needs to be added after any compression middleware.
|
|
196
197
|
:install_middleware => false
|
197
198
|
}
|
198
199
|
```
|
200
|
+
|
201
|
+
### 2.11 compress_api_requests
|
202
|
+
|
203
|
+
By default, requests to the translation API will be sent with gzip compression. Set to false to disable compression.
|
data/README.ja.md
CHANGED
@@ -44,8 +44,8 @@ bundle install
|
|
44
44
|
|
45
45
|
config.wovnrb = {
|
46
46
|
:project_token => 'EnS!t3',
|
47
|
-
:default_lang => '
|
48
|
-
:supported_langs => ['en'],
|
47
|
+
:default_lang => 'ja',
|
48
|
+
:supported_langs => ['ja', en'],
|
49
49
|
:url_pattern => 'path'
|
50
50
|
}
|
51
51
|
|
@@ -63,8 +63,8 @@ require 'wovnrb'
|
|
63
63
|
|
64
64
|
use Wovnrb::Interceptor, {
|
65
65
|
:project_token => 'EnS!t3',
|
66
|
-
:default_lang => '
|
67
|
-
:supported_langs => ['en'],
|
66
|
+
:default_lang => 'ja',
|
67
|
+
:supported_langs => ['ja', 'en'],
|
68
68
|
:url_pattern => 'path'
|
69
69
|
}
|
70
70
|
|
@@ -80,8 +80,8 @@ use Wovnrb::Interceptor, {
|
|
80
80
|
パラメータ名 | 必須 | デフォルト設定
|
81
81
|
------------------ | -------- | ----------------
|
82
82
|
project_token | yes | ''
|
83
|
-
default_lang | yes | '
|
84
|
-
supported_langs | yes | ['en']
|
83
|
+
default_lang | yes | 'ja'
|
84
|
+
supported_langs | yes | ['ja', 'en']
|
85
85
|
url_pattern | yes | 'path'
|
86
86
|
lang_param_name | | 'wovn'
|
87
87
|
query | | []
|
data/Rakefile
CHANGED
@@ -5129,9 +5129,9 @@ path-key@^2.0.0, path-key@^2.0.1:
|
|
5129
5129
|
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
5130
5130
|
|
5131
5131
|
path-parse@^1.0.6:
|
5132
|
-
version "1.0.
|
5133
|
-
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.
|
5134
|
-
integrity sha512-
|
5132
|
+
version "1.0.7"
|
5133
|
+
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
5134
|
+
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
5135
5135
|
|
5136
5136
|
path-to-regexp@0.1.7:
|
5137
5137
|
version "0.1.7"
|
@@ -24,18 +24,19 @@ module Wovnrb
|
|
24
24
|
|
25
25
|
case response
|
26
26
|
when Net::HTTPSuccess
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
begin
|
28
|
+
raw_response_body = @store.dev_mode? ? response.body : Zlib::GzipReader.new(StringIO.new(response.body)).read
|
29
|
+
rescue Zlib::GzipFile::Error
|
30
|
+
raw_response_body = response.body
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
JSON.parse(raw_response_body)['body'] || body
|
35
|
+
rescue JSON::JSONError
|
35
36
|
body
|
36
37
|
end
|
37
38
|
else
|
38
|
-
WovnLogger.error("Received \"#{response.message}\" from WOVNio translation API.")
|
39
|
+
WovnLogger.error("HTML-swapper call failed. Received \"#{response.message}\" from WOVNio translation API.")
|
39
40
|
body
|
40
41
|
end
|
41
42
|
end
|
@@ -52,25 +53,45 @@ module Wovnrb
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def prepare_request(body)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
}
|
62
|
-
request = Net::HTTP::Post.new(generate_request_path(body), headers)
|
56
|
+
if @store.compress_api_requests?
|
57
|
+
gzip_request(body)
|
58
|
+
else
|
59
|
+
json_request(body)
|
60
|
+
end
|
61
|
+
end
|
63
62
|
|
64
|
-
|
63
|
+
def gzip_request(html_body)
|
64
|
+
api_params = build_api_params(html_body)
|
65
|
+
compressed_body = compress_request_data(api_params.to_json)
|
66
|
+
request = Net::HTTP::Post.new(request_path(html_body), {
|
67
|
+
'Accept-Encoding' => 'gzip',
|
68
|
+
'Content-Type' => 'application/json',
|
69
|
+
'Content-Encoding' => 'gzip',
|
70
|
+
'Content-Length' => compressed_body.bytesize.to_s,
|
71
|
+
'X-Request-Id' => @uuid
|
72
|
+
})
|
73
|
+
request.body = compressed_body
|
65
74
|
|
66
75
|
request
|
67
76
|
end
|
68
77
|
|
69
|
-
def
|
70
|
-
|
78
|
+
def json_request(html_body)
|
79
|
+
api_params = build_api_params(html_body)
|
80
|
+
request = Net::HTTP::Post.new(request_path(html_body), {
|
81
|
+
'Accept-Encoding' => 'gzip',
|
82
|
+
'Content-Type' => 'application/json',
|
83
|
+
'X-Request-Id' => @uuid
|
84
|
+
})
|
85
|
+
request.body = api_params.to_json
|
86
|
+
|
87
|
+
request
|
88
|
+
end
|
89
|
+
|
90
|
+
def request_path(body)
|
91
|
+
"#{api_uri.path}/translation?cache_key=#{cache_key(body)}"
|
71
92
|
end
|
72
93
|
|
73
|
-
def
|
94
|
+
def cache_key(body)
|
74
95
|
cache_key_components = {
|
75
96
|
'token' => token,
|
76
97
|
'settings_hash' => settings_hash,
|
@@ -83,8 +104,8 @@ module Wovnrb
|
|
83
104
|
CGI.escape("(#{cache_key_components})")
|
84
105
|
end
|
85
106
|
|
86
|
-
def
|
87
|
-
|
107
|
+
def build_api_params(body)
|
108
|
+
result = {
|
88
109
|
'url' => page_url,
|
89
110
|
'token' => token,
|
90
111
|
'lang_code' => lang_code,
|
@@ -95,23 +116,17 @@ module Wovnrb
|
|
95
116
|
'body' => body
|
96
117
|
}
|
97
118
|
|
98
|
-
|
119
|
+
result['custom_lang_aliases'] = JSON.dump(custom_lang_aliases) unless custom_lang_aliases.empty?
|
99
120
|
|
100
|
-
|
121
|
+
result
|
101
122
|
end
|
102
123
|
|
103
124
|
def compress_request_data(data_hash)
|
104
|
-
|
105
|
-
"#{key}=#{CGI.escape(value)}"
|
106
|
-
end
|
107
|
-
|
108
|
-
gzip = Zlib::GzipWriter.new(StringIO.new)
|
109
|
-
gzip << encoded_data_components.join('&')
|
110
|
-
gzip.close.string
|
125
|
+
ActiveSupport::Gzip.compress(data_hash)
|
111
126
|
end
|
112
127
|
|
113
128
|
def api_uri
|
114
|
-
Addressable::URI.parse("#{@store.settings['api_url']}/v0
|
129
|
+
Addressable::URI.parse("#{@store.settings['api_url']}/v0")
|
115
130
|
end
|
116
131
|
|
117
132
|
def api_timeout
|
data/lib/wovnrb/headers.rb
CHANGED
@@ -18,11 +18,11 @@ module Wovnrb
|
|
18
18
|
end
|
19
19
|
unless @env.key?('REQUEST_URI')
|
20
20
|
# Add '/' to PATH_INFO as a possible fix for pow server
|
21
|
-
@env['REQUEST_URI'] = (@env['PATH_INFO']
|
21
|
+
@env['REQUEST_URI'] = (/^[^\/]/.match?(@env['PATH_INFO']) ? '/' : '') + @env['PATH_INFO'] + (@env['QUERY_STRING'].empty? ? '' : "?#{@env['QUERY_STRING']}")
|
22
22
|
end
|
23
23
|
# REQUEST_URI is expected to not contain the server name
|
24
24
|
# heroku contains http://...
|
25
|
-
@env['REQUEST_URI'] = @env['REQUEST_URI'].sub(/^https?:\/\/[^\/]+/, '') if @env['REQUEST_URI']
|
25
|
+
@env['REQUEST_URI'] = @env['REQUEST_URI'].sub(/^https?:\/\/[^\/]+/, '') if /^https?:\/\//.match?(@env['REQUEST_URI'])
|
26
26
|
@unmasked_pathname = @env['REQUEST_URI'].split('?')[0]
|
27
27
|
@unmasked_pathname += '/' unless @unmasked_pathname =~ /\/$/ || @unmasked_pathname =~ /\/[^\/.]+\.[^\/.]+$/
|
28
28
|
@unmasked_url = "#{@protocol}://#{@unmasked_host}#{@unmasked_pathname}"
|
@@ -108,7 +108,7 @@ module Wovnrb
|
|
108
108
|
case @settings['url_pattern']
|
109
109
|
when 'query'
|
110
110
|
lang_param_name = @settings['lang_param_name']
|
111
|
-
location = if location
|
111
|
+
location = if /\?/.match?(location)
|
112
112
|
"#{location}&#{lang_param_name}=#{lang_code}"
|
113
113
|
else
|
114
114
|
"#{location}?#{lang_param_name}=#{lang_code}"
|
@@ -180,7 +180,7 @@ module Wovnrb
|
|
180
180
|
if lang_code != @settings['default_lang'] && headers.key?('Location') && headers['Location'] =~ r && !@settings['ignore_globs'].ignore?(headers['Location'])
|
181
181
|
case @settings['url_pattern']
|
182
182
|
when 'query'
|
183
|
-
headers['Location'] += if headers['Location']
|
183
|
+
headers['Location'] += if /\?/.match?(headers['Location'])
|
184
184
|
'&'
|
185
185
|
else
|
186
186
|
'?'
|
data/lib/wovnrb/lang.rb
CHANGED
@@ -126,7 +126,7 @@ module Wovnrb
|
|
126
126
|
# @param [Wovnrb::Header] headers instance of Wovn::Header. It generates new env variable for original request.
|
127
127
|
# @return [String] URL added langauge code.
|
128
128
|
def add_lang_code(href, pattern, headers)
|
129
|
-
return href if
|
129
|
+
return href if /^(#.*)?$/.match?(href)
|
130
130
|
|
131
131
|
settings = Store.instance.settings
|
132
132
|
code_to_add = settings['custom_lang_aliases'][@lang_code] || @lang_code
|
@@ -181,7 +181,7 @@ module Wovnrb
|
|
181
181
|
when 'query'
|
182
182
|
new_href = add_query_lang_code(href, code_to_add, lang_param_name)
|
183
183
|
else # path
|
184
|
-
if href
|
184
|
+
if /^\//.match?(href)
|
185
185
|
new_href = "/#{code_to_add}#{href}"
|
186
186
|
else
|
187
187
|
current_dir = headers.pathname.sub(/[^\/]*\.[^.]{2,6}$/, '')
|
@@ -250,7 +250,7 @@ module Wovnrb
|
|
250
250
|
end
|
251
251
|
|
252
252
|
def add_query_lang_code(href, lang_code, lang_param_name)
|
253
|
-
query_separator = href
|
253
|
+
query_separator = /\?/.match?(href) ? '&' : '?'
|
254
254
|
|
255
255
|
href.sub(/(#|$)/, "#{query_separator}#{lang_param_name}=#{lang_code}\\1")
|
256
256
|
end
|
@@ -21,6 +21,10 @@ module Wovnrb
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def html
|
24
|
+
# Ensure a Content-Type declaration in the header. This mimics Nokogumbo
|
25
|
+
# 1.5.0 default serialization behavior.
|
26
|
+
@dom.meta_encoding = 'UTF-8' if @dom.respond_to?(:meta_encoding=)
|
27
|
+
|
24
28
|
@dom.to_html(save_with: 0).strip
|
25
29
|
end
|
26
30
|
|
data/lib/wovnrb/store.rb
CHANGED
@@ -25,8 +25,8 @@ module Wovnrb
|
|
25
25
|
'ignore_class' => [],
|
26
26
|
'api_url' => 'https://wovn.global.ssl.fastly.net',
|
27
27
|
'api_timeout_seconds' => 1.0,
|
28
|
-
'default_lang' => '
|
29
|
-
'supported_langs' => [
|
28
|
+
'default_lang' => 'ja',
|
29
|
+
'supported_langs' => %w[en ja],
|
30
30
|
'test_mode' => false,
|
31
31
|
'test_url' => '',
|
32
32
|
'cache_megabytes' => nil,
|
@@ -35,7 +35,8 @@ module Wovnrb
|
|
35
35
|
'custom_lang_aliases' => {},
|
36
36
|
'translate_fragment' => true,
|
37
37
|
'widget_url' => 'https://j.wovn.io/1',
|
38
|
-
'wovn_dev_mode' => false
|
38
|
+
'wovn_dev_mode' => false,
|
39
|
+
'compress_api_requests' => true
|
39
40
|
)
|
40
41
|
end
|
41
42
|
|
@@ -113,7 +114,7 @@ module Wovnrb
|
|
113
114
|
# Load Rails config.wovnrb
|
114
115
|
#
|
115
116
|
def load_settings
|
116
|
-
if Object.const_defined?(
|
117
|
+
if Object.const_defined?(:Rails) && Rails.configuration.respond_to?(:wovnrb)
|
117
118
|
@config_loaded = true
|
118
119
|
update_settings(Rails.configuration.wovnrb)
|
119
120
|
end
|
@@ -181,6 +182,10 @@ module Wovnrb
|
|
181
182
|
@settings['supported_langs'] || []
|
182
183
|
end
|
183
184
|
|
185
|
+
def compress_api_requests?
|
186
|
+
@settings['compress_api_requests']
|
187
|
+
end
|
188
|
+
|
184
189
|
def widget_url
|
185
190
|
@settings['widget_url'] || 'https://j.wovn.io/1'
|
186
191
|
end
|
data/lib/wovnrb/version.rb
CHANGED
data/lib/wovnrb.rb
CHANGED
@@ -5,7 +5,7 @@ require 'wovnrb/store'
|
|
5
5
|
require 'wovnrb/lang'
|
6
6
|
require 'wovnrb/services/html_converter'
|
7
7
|
require 'wovnrb/services/html_replace_marker'
|
8
|
-
require '
|
8
|
+
require 'nokogiri'
|
9
9
|
require 'active_support'
|
10
10
|
require 'json'
|
11
11
|
require 'wovnrb/helpers/nokogumbo_helper'
|
@@ -49,7 +49,7 @@ module Wovnrb
|
|
49
49
|
status, res_headers, body = @app.call(headers.request_out)
|
50
50
|
|
51
51
|
# disabled by next Rack middleware
|
52
|
-
return output(headers, status, res_headers, body) unless res_headers['Content-Type']
|
52
|
+
return output(headers, status, res_headers, body) unless /html/.match?(res_headers['Content-Type'])
|
53
53
|
|
54
54
|
request = Rack::Request.new(env)
|
55
55
|
|
@@ -58,7 +58,7 @@ module Wovnrb
|
|
58
58
|
@store.settings.update_dynamic_settings!(request.params)
|
59
59
|
return output(headers, status, res_headers, body) if ignore_path?(headers.pathname)
|
60
60
|
|
61
|
-
body = switch_lang(headers, body) unless
|
61
|
+
body = switch_lang(headers, body) unless /^1|302/.match?(status.to_s)
|
62
62
|
|
63
63
|
content_length = 0
|
64
64
|
body.each { |b| content_length += b.respond_to?(:bytesize) ? b.bytesize : 0 }
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
module Wovnrb
|
4
|
+
REQUEST_UUID = 'ABCD'.freeze
|
5
|
+
|
4
6
|
class ApiTranslatorTest < WovnMiniTest
|
5
7
|
def test_translate
|
6
8
|
assert_translation('test.html', 'test_translated.html', true)
|
@@ -8,28 +10,64 @@ module Wovnrb
|
|
8
10
|
|
9
11
|
def test_translate_falls_back_to_original_body_if_exception
|
10
12
|
Net::HTTP.any_instance.expects(:request).raises
|
11
|
-
assert_translation('test.html', 'test_translated.html', false, nil)
|
13
|
+
assert_translation('test.html', 'test_translated.html', false, response: nil)
|
12
14
|
end
|
13
15
|
|
14
16
|
def test_translate_falls_back_to_original_body_if_api_error
|
15
|
-
assert_translation('test.html', 'test_translated.html', false, status_code: 500)
|
17
|
+
assert_translation('test.html', 'test_translated.html', false, response: { encoding: 'text/json', status_code: 500 })
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_translate_continues_if_api_response_is_not_compressed
|
21
|
+
assert_translation('test.html', 'test_translated.html', true, response: { encoding: 'unknown', status: 200 }, compress_data: false)
|
16
22
|
end
|
17
23
|
|
18
|
-
def
|
19
|
-
assert_translation('test.html', 'test_translated.html',
|
24
|
+
def test_translate_continues_if_api_response_is_compressed
|
25
|
+
assert_translation('test.html', 'test_translated.html', true, response: { encoding: 'unknown', status: 200 })
|
20
26
|
end
|
21
27
|
|
22
28
|
def test_translate_accepts_uncompressed_response_from_api_in_dev_mode
|
23
29
|
Wovnrb::Store.instance.update_settings('wovn_dev_mode' => true)
|
24
|
-
assert_translation('test.html', 'test_translated.html', true, encoding: 'text/json')
|
30
|
+
assert_translation('test.html', 'test_translated.html', true, response: { encoding: 'text/json', status: 200 }, compress_data: false)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_translate_without_api_compression_sends_json
|
34
|
+
Wovnrb::Store.instance.update_settings('compress_api_requests' => false)
|
35
|
+
sut, _store, _headers = create_sut
|
36
|
+
html_body = 'foo'
|
37
|
+
|
38
|
+
stub_request(:post, %r{http://wovn\.global\.ssl\.fastly\.net/v0/translation\?cache_key=.*})
|
39
|
+
.to_return(status: 200, body: { 'body' => 'translated_body' }.to_json)
|
40
|
+
|
41
|
+
sut.translate(html_body)
|
42
|
+
|
43
|
+
assert_requested :post, %r{http://wovn\.global\.ssl\.fastly\.net/v0/translation\?cache_key=.*},
|
44
|
+
headers: {
|
45
|
+
'Accept' => '*/*',
|
46
|
+
'Accept-Encoding' => 'gzip',
|
47
|
+
'Content-Type' => 'application/json',
|
48
|
+
'User-Agent' => 'Ruby',
|
49
|
+
'X-Request-Id' => REQUEST_UUID
|
50
|
+
},
|
51
|
+
body: {
|
52
|
+
'url' => 'http://wovn.io/test',
|
53
|
+
'token' => '123456',
|
54
|
+
'lang_code' => 'fr',
|
55
|
+
'url_pattern' => 'subdomain',
|
56
|
+
'lang_param_name' => 'lang',
|
57
|
+
'product' => 'WOVN.rb',
|
58
|
+
'version' => VERSION,
|
59
|
+
'body' => 'foo',
|
60
|
+
'custom_lang_aliases' => { 'ja' => 'Japanese' }.to_json
|
61
|
+
}.to_json,
|
62
|
+
times: 1
|
25
63
|
end
|
26
64
|
|
27
65
|
private
|
28
66
|
|
29
|
-
def assert_translation(original_html_fixture, translated_html_fixture, success_expected, response
|
67
|
+
def assert_translation(original_html_fixture, translated_html_fixture, success_expected, response: { encoding: 'gzip', status_code: 200 }, compress_data: true)
|
30
68
|
original_html = File.read("test/fixtures/html/#{original_html_fixture}")
|
31
69
|
translated_html = File.read("test/fixtures/html/#{translated_html_fixture}")
|
32
|
-
actual_translated_html = translate(original_html, translated_html, response)
|
70
|
+
actual_translated_html = translate(original_html, translated_html, response, compress_data: compress_data)
|
33
71
|
|
34
72
|
if success_expected
|
35
73
|
assert_equal(actual_translated_html, translated_html)
|
@@ -38,7 +76,16 @@ module Wovnrb
|
|
38
76
|
end
|
39
77
|
end
|
40
78
|
|
41
|
-
def translate(original_html, translated_html, response)
|
79
|
+
def translate(original_html, translated_html, response, compress_data: true)
|
80
|
+
api_translator, store, _headers = create_sut
|
81
|
+
translation_request_stub = stub_translation_api_request(store, original_html, translated_html, response, compress_data: compress_data)
|
82
|
+
|
83
|
+
actual_translated_html = api_translator.translate(original_html)
|
84
|
+
assert_requested(translation_request_stub, times: 1) if translation_request_stub
|
85
|
+
actual_translated_html
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_sut
|
42
89
|
settings = {
|
43
90
|
'project_token' => '123456',
|
44
91
|
'custom_lang_aliases' => { 'ja' => 'Japanese' },
|
@@ -53,15 +100,12 @@ module Wovnrb
|
|
53
100
|
Wovnrb.get_env('url' => 'http://fr.wovn.io/test'),
|
54
101
|
Wovnrb.get_settings(settings)
|
55
102
|
)
|
56
|
-
api_translator = ApiTranslator.new(store, headers,
|
57
|
-
translation_request_stub = stub_translation_api_request(store, headers, original_html, translated_html, response)
|
103
|
+
api_translator = ApiTranslator.new(store, headers, REQUEST_UUID)
|
58
104
|
|
59
|
-
|
60
|
-
assert_requested(translation_request_stub, times: 1) if translation_request_stub
|
61
|
-
actual_translated_html
|
105
|
+
[api_translator, store, headers]
|
62
106
|
end
|
63
107
|
|
64
|
-
def stub_translation_api_request(store,
|
108
|
+
def stub_translation_api_request(store, original_html, translated_html, response, compress_data: true)
|
65
109
|
if response
|
66
110
|
cache_key = generate_cache_key(store, original_html)
|
67
111
|
api_host = if store.dev_mode?
|
@@ -75,14 +119,15 @@ module Wovnrb
|
|
75
119
|
'Accept' => '*/*',
|
76
120
|
'Accept-Encoding' => 'gzip',
|
77
121
|
'Content-Length' => compressed_data.bytesize,
|
78
|
-
'Content-Type' => 'application/
|
122
|
+
'Content-Type' => 'application/json',
|
123
|
+
'Content-Encoding' => 'gzip',
|
79
124
|
'User-Agent' => 'Ruby'
|
80
125
|
}
|
81
126
|
stub_response_json = "{\"body\":\"#{translated_html.gsub("\n", '\n')}\"}"
|
82
|
-
stub_response = if
|
83
|
-
stub_response_json
|
84
|
-
else
|
127
|
+
stub_response = if compress_data
|
85
128
|
compress(stub_response_json)
|
129
|
+
else
|
130
|
+
stub_response_json
|
86
131
|
end
|
87
132
|
response_headers = { 'Content-Encoding' => response[:encoding] || 'gzip' }
|
88
133
|
stub_request(:post, api_url)
|
@@ -113,13 +158,11 @@ module Wovnrb
|
|
113
158
|
'custom_lang_aliases' => '{"ja":"Japanese"}'
|
114
159
|
}
|
115
160
|
|
116
|
-
data.
|
161
|
+
data.to_json
|
117
162
|
end
|
118
163
|
|
119
164
|
def compress(string)
|
120
|
-
|
121
|
-
gzip << string
|
122
|
-
gzip.close.string
|
165
|
+
ActiveSupport::Gzip.compress(string)
|
123
166
|
end
|
124
167
|
end
|
125
168
|
end
|
data/test/lib/headers_test.rb
CHANGED
@@ -170,7 +170,7 @@ module Wovnrb
|
|
170
170
|
Wovnrb.get_env('url' => 'http://wovn.io/contact', 'HTTP_X_FORWARDED_HOST' => 'wovn.io'),
|
171
171
|
Store.instance.settings
|
172
172
|
)
|
173
|
-
assert_equal('http://wovn.io/contact?wovn=
|
173
|
+
assert_equal('http://wovn.io/contact?wovn=en', sut.redirect_location('en'))
|
174
174
|
end
|
175
175
|
|
176
176
|
def test_redirect_location_with_lang_param_name
|
@@ -179,7 +179,7 @@ module Wovnrb
|
|
179
179
|
Wovnrb.get_env('url' => 'http://wovn.io/contact', 'HTTP_X_FORWARDED_HOST' => 'wovn.io'),
|
180
180
|
Store.instance.settings
|
181
181
|
)
|
182
|
-
assert_equal('http://wovn.io/contact?lang=
|
182
|
+
assert_equal('http://wovn.io/contact?lang=en', sut.redirect_location('en'))
|
183
183
|
end
|
184
184
|
|
185
185
|
#########################
|
@@ -45,7 +45,7 @@ module Wovnrb
|
|
45
45
|
converter = prepare_html_converter(html, ignore_class: ['ignore-me'])
|
46
46
|
converted_html, = converter.build_api_compatible_html
|
47
47
|
|
48
|
-
expected_convert_html = "<html lang=\"en\"><head><script src=\"https://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><
|
48
|
+
expected_convert_html = "<html lang=\"en\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"https://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=\"fr\" href=\"http://my-site.com/?wovn=fr\"><link rel=\"alternate\" hreflang=\"ja\" href=\"http://my-site.com/?wovn=ja\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/?wovn=vi\"></head><body><p>Hello <span wovn-ignore=\"\"><!-- __wovn-backend-ignored-key-0 --></span></p><p></p><p>Hello <span data-wovn-ignore=\"\"><!-- __wovn-backend-ignored-key-1 --></span></p><p></p><div><span class=\"ignore-me\"><!-- __wovn-backend-ignored-key-2 --></span></div><span>Have a nice day!</span></body></html>"
|
49
49
|
assert_equal(expected_convert_html, converted_html)
|
50
50
|
end
|
51
51
|
|
@@ -62,7 +62,7 @@ module Wovnrb
|
|
62
62
|
converter = prepare_html_converter(html, ignore_class: [])
|
63
63
|
converted_html, = converter.build_api_compatible_html
|
64
64
|
|
65
|
-
expected_convert_html = "<html lang=\"en\"><head><script src=\"https://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><
|
65
|
+
expected_convert_html = "<html lang=\"en\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"https://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=\"fr\" href=\"http://my-site.com/?wovn=fr\"><link rel=\"alternate\" hreflang=\"ja\" href=\"http://my-site.com/?wovn=ja\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/?wovn=vi\"></head><body><form action=\"/test\" method=\"POST\"><!-- __wovn-backend-ignored-key-0 --></form></body></html>"
|
66
66
|
assert_equal(expected_convert_html, converted_html)
|
67
67
|
end
|
68
68
|
|
data/test/test_helper.rb
CHANGED
data/wovnrb.gemspec
CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.homepage = 'https://wovn.io'
|
13
13
|
spec.license = 'MIT'
|
14
14
|
spec.required_ruby_version = '>= 2.5'
|
15
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
15
16
|
|
16
17
|
files = `git ls-files -z`.split("\x0")
|
17
18
|
files.delete('BEFORE_PUSHING')
|
@@ -23,8 +24,7 @@ Gem::Specification.new do |spec|
|
|
23
24
|
spec.add_dependency 'activesupport'
|
24
25
|
spec.add_dependency 'addressable'
|
25
26
|
spec.add_dependency 'lz4-ruby'
|
26
|
-
spec.add_dependency 'nokogiri', '>= 1.
|
27
|
-
spec.add_dependency 'nokogumbo', '>= 1.4.0', '< 2.0.0'
|
27
|
+
spec.add_dependency 'nokogiri', '>= 1.12', '<2'
|
28
28
|
spec.add_dependency 'rack'
|
29
29
|
|
30
30
|
spec.add_development_dependency 'bundler', '>= 1.7'
|
@@ -45,6 +45,7 @@ Gem::Specification.new do |spec|
|
|
45
45
|
|
46
46
|
spec.add_development_dependency 'rake-compiler'
|
47
47
|
spec.add_development_dependency 'rubocop'
|
48
|
+
spec.add_development_dependency 'rubocop-performance'
|
48
49
|
spec.add_development_dependency 'timecop'
|
49
50
|
|
50
51
|
# NOTE; it need to use webmock 2.3.2 for avoiding error when we use ruby 2.4.x.
|
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.
|
4
|
+
version: 3.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wovn Technologies, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -58,40 +58,20 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.
|
62
|
-
- - "<="
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '1.11'
|
65
|
-
type: :runtime
|
66
|
-
prerelease: false
|
67
|
-
version_requirements: !ruby/object:Gem::Requirement
|
68
|
-
requirements:
|
69
|
-
- - ">="
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
version: 1.8.1
|
72
|
-
- - "<="
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '1.11'
|
75
|
-
- !ruby/object:Gem::Dependency
|
76
|
-
name: nokogumbo
|
77
|
-
requirement: !ruby/object:Gem::Requirement
|
78
|
-
requirements:
|
79
|
-
- - ">="
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
version: 1.4.0
|
61
|
+
version: '1.12'
|
82
62
|
- - "<"
|
83
63
|
- !ruby/object:Gem::Version
|
84
|
-
version: 2
|
64
|
+
version: '2'
|
85
65
|
type: :runtime
|
86
66
|
prerelease: false
|
87
67
|
version_requirements: !ruby/object:Gem::Requirement
|
88
68
|
requirements:
|
89
69
|
- - ">="
|
90
70
|
- !ruby/object:Gem::Version
|
91
|
-
version: 1.
|
71
|
+
version: '1.12'
|
92
72
|
- - "<"
|
93
73
|
- !ruby/object:Gem::Version
|
94
|
-
version: 2
|
74
|
+
version: '2'
|
95
75
|
- !ruby/object:Gem::Dependency
|
96
76
|
name: rack
|
97
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -344,6 +324,20 @@ dependencies:
|
|
344
324
|
- - ">="
|
345
325
|
- !ruby/object:Gem::Version
|
346
326
|
version: '0'
|
327
|
+
- !ruby/object:Gem::Dependency
|
328
|
+
name: rubocop-performance
|
329
|
+
requirement: !ruby/object:Gem::Requirement
|
330
|
+
requirements:
|
331
|
+
- - ">="
|
332
|
+
- !ruby/object:Gem::Version
|
333
|
+
version: '0'
|
334
|
+
type: :development
|
335
|
+
prerelease: false
|
336
|
+
version_requirements: !ruby/object:Gem::Requirement
|
337
|
+
requirements:
|
338
|
+
- - ">="
|
339
|
+
- !ruby/object:Gem::Version
|
340
|
+
version: '0'
|
347
341
|
- !ruby/object:Gem::Dependency
|
348
342
|
name: timecop
|
349
343
|
requirement: !ruby/object:Gem::Requirement
|
@@ -551,7 +545,8 @@ files:
|
|
551
545
|
homepage: https://wovn.io
|
552
546
|
licenses:
|
553
547
|
- MIT
|
554
|
-
metadata:
|
548
|
+
metadata:
|
549
|
+
rubygems_mfa_required: 'true'
|
555
550
|
post_install_message:
|
556
551
|
rdoc_options: []
|
557
552
|
require_paths:
|
@@ -567,7 +562,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
567
562
|
- !ruby/object:Gem::Version
|
568
563
|
version: '0'
|
569
564
|
requirements: []
|
570
|
-
rubygems_version: 3.
|
565
|
+
rubygems_version: 3.2.3
|
571
566
|
signing_key:
|
572
567
|
specification_version: 4
|
573
568
|
summary: Gem for WOVN.io
|