wovnrb 3.3.1 → 3.6.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 +30 -13
- data/Rakefile +0 -1
- data/build.sh +7 -0
- data/docker/nginx/Dockerfile +18 -0
- data/docker/nginx/README.md +13 -0
- data/docker/nginx/build.sh +8 -0
- data/docker/nginx/scripts/configure_sshd.sh +25 -0
- data/docker/nginx/scripts/startup.sh +10 -0
- data/docker/nginx/wovnrb.conf +19 -0
- data/docker/rails/Dockerfile +9 -0
- data/docker/rails/Dockerfile.ECS +17 -0
- data/docker/rails/TestSite/Gemfile +0 -2
- data/docker/rails/TestSite/app/controllers/custom_response_controller.rb +1 -1
- data/docker/rails/TestSite/config/environments/development.rb +2 -0
- data/docker/rails/TestSite/config/environments/production.rb +2 -0
- data/docker/rails/TestSite/config/environments/test.rb +2 -0
- data/docker/rails/TestSite/public/index.html +1 -1
- data/docker/rails/TestSite/start.sh +2 -12
- data/docker/rails/TestSite/start_rails.sh +9 -0
- data/docker/rails/TestSite/yarn.lock +6 -6
- data/docker/scripts/jenkins/build.sh +45 -0
- data/docker/scripts/jenkins/tag_and_push_image.sh +30 -0
- data/docker/scripts/jenkins/taskdef.json +104 -0
- data/docker/scripts/jenkins/taskdef.json.bak +99 -0
- data/lib/wovnrb/api_translator.rb +19 -19
- data/lib/wovnrb/headers.rb +23 -6
- data/lib/wovnrb/helpers/nokogumbo_helper.rb +1 -1
- data/lib/wovnrb/lang.rb +3 -3
- data/lib/wovnrb/services/html_converter.rb +21 -1
- data/lib/wovnrb/services/url.rb +136 -0
- data/lib/wovnrb/store.rb +9 -3
- data/lib/wovnrb/url_language_switcher.rb +124 -0
- data/lib/wovnrb/version.rb +1 -1
- data/lib/wovnrb.rb +6 -4
- data/test/lib/api_translator_test.rb +66 -19
- data/test/lib/services/html_converter_test.rb +212 -39
- data/test/lib/services/url_test.rb +308 -0
- data/test/lib/url_language_switcher_test.rb +798 -0
- data/test/lib/wovnrb_test.rb +2 -1
- data/test/test_helper.rb +5 -2
- data/wovnrb.gemspec +3 -2
- metadata +42 -28
@@ -10,20 +10,24 @@ module Wovnrb
|
|
10
10
|
|
11
11
|
def test_translate_falls_back_to_original_body_if_exception
|
12
12
|
Net::HTTP.any_instance.expects(:request).raises
|
13
|
-
assert_translation('test.html', 'test_translated.html', false, nil)
|
13
|
+
assert_translation('test.html', 'test_translated.html', false, response: nil)
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_translate_falls_back_to_original_body_if_api_error
|
17
|
-
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
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
assert_translation('test.html', 'test_translated.html',
|
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)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_translate_continues_if_api_response_is_compressed
|
25
|
+
assert_translation('test.html', 'test_translated.html', true, response: { encoding: 'unknown', status: 200 })
|
22
26
|
end
|
23
27
|
|
24
28
|
def test_translate_accepts_uncompressed_response_from_api_in_dev_mode
|
25
29
|
Wovnrb::Store.instance.update_settings('wovn_dev_mode' => true)
|
26
|
-
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)
|
27
31
|
end
|
28
32
|
|
29
33
|
def test_translate_without_api_compression_sends_json
|
@@ -50,6 +54,7 @@ module Wovnrb
|
|
50
54
|
'lang_code' => 'fr',
|
51
55
|
'url_pattern' => 'subdomain',
|
52
56
|
'lang_param_name' => 'lang',
|
57
|
+
'translate_canonical_tag' => true,
|
53
58
|
'product' => 'WOVN.rb',
|
54
59
|
'version' => VERSION,
|
55
60
|
'body' => 'foo',
|
@@ -58,12 +63,52 @@ module Wovnrb
|
|
58
63
|
times: 1
|
59
64
|
end
|
60
65
|
|
66
|
+
def test_api_timeout_is_search_engine_user_higher_default
|
67
|
+
settings = {
|
68
|
+
'project_token' => '123456',
|
69
|
+
'custom_lang_aliases' => { 'ja' => 'Japanese' },
|
70
|
+
'default_lang' => 'en',
|
71
|
+
'url_pattern' => 'subdomain',
|
72
|
+
'url_pattern_reg' => '^(?<lang>[^.]+).',
|
73
|
+
'lang_param_name' => 'lang'
|
74
|
+
}
|
75
|
+
store = Wovnrb::Store.instance
|
76
|
+
store.update_settings(settings)
|
77
|
+
headers = Wovnrb::Headers.new(
|
78
|
+
Wovnrb.get_env('url' => 'http://fr.wovn.io/test', 'HTTP_USER_AGENT' => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'),
|
79
|
+
Wovnrb.get_settings(settings)
|
80
|
+
)
|
81
|
+
api_translator = ApiTranslator.new(store, headers, REQUEST_UUID)
|
82
|
+
assert_equal(5.0, api_translator.send(:api_timeout))
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_api_timeout_no_user_agent_use_normal_default
|
86
|
+
settings = {
|
87
|
+
'project_token' => '123456',
|
88
|
+
'custom_lang_aliases' => { 'ja' => 'Japanese' },
|
89
|
+
'default_lang' => 'en',
|
90
|
+
'url_pattern' => 'subdomain',
|
91
|
+
'url_pattern_reg' => '^(?<lang>[^.]+).',
|
92
|
+
'lang_param_name' => 'lang'
|
93
|
+
}
|
94
|
+
store = Wovnrb::Store.instance
|
95
|
+
store.update_settings(settings)
|
96
|
+
env = Wovnrb.get_env('url' => 'http://fr.wovn.io/test')
|
97
|
+
env.delete('HTTP_USER_AGENT')
|
98
|
+
headers = Wovnrb::Headers.new(
|
99
|
+
env,
|
100
|
+
Wovnrb.get_settings(settings)
|
101
|
+
)
|
102
|
+
api_translator = ApiTranslator.new(store, headers, REQUEST_UUID)
|
103
|
+
assert_equal(1.0, api_translator.send(:api_timeout))
|
104
|
+
end
|
105
|
+
|
61
106
|
private
|
62
107
|
|
63
|
-
def assert_translation(original_html_fixture, translated_html_fixture, success_expected, response
|
108
|
+
def assert_translation(original_html_fixture, translated_html_fixture, success_expected, response: { encoding: 'gzip', status_code: 200 }, compress_data: true)
|
64
109
|
original_html = File.read("test/fixtures/html/#{original_html_fixture}")
|
65
110
|
translated_html = File.read("test/fixtures/html/#{translated_html_fixture}")
|
66
|
-
actual_translated_html = translate(original_html, translated_html, response)
|
111
|
+
actual_translated_html = translate(original_html, translated_html, response, compress_data: compress_data)
|
67
112
|
|
68
113
|
if success_expected
|
69
114
|
assert_equal(actual_translated_html, translated_html)
|
@@ -72,10 +117,12 @@ module Wovnrb
|
|
72
117
|
end
|
73
118
|
end
|
74
119
|
|
75
|
-
def translate(original_html, translated_html, response)
|
76
|
-
api_translator, store,
|
77
|
-
translation_request_stub = stub_translation_api_request(store,
|
120
|
+
def translate(original_html, translated_html, response, compress_data: true)
|
121
|
+
api_translator, store, _headers = create_sut
|
122
|
+
translation_request_stub = stub_translation_api_request(store, original_html, translated_html, response, compress_data: compress_data)
|
78
123
|
|
124
|
+
expected_api_timeout = store.settings['api_timeout_seconds']
|
125
|
+
assert_equal(expected_api_timeout, api_translator.send(:api_timeout))
|
79
126
|
actual_translated_html = api_translator.translate(original_html)
|
80
127
|
assert_requested(translation_request_stub, times: 1) if translation_request_stub
|
81
128
|
actual_translated_html
|
@@ -101,7 +148,7 @@ module Wovnrb
|
|
101
148
|
[api_translator, store, headers]
|
102
149
|
end
|
103
150
|
|
104
|
-
def stub_translation_api_request(store,
|
151
|
+
def stub_translation_api_request(store, original_html, translated_html, response, compress_data: true)
|
105
152
|
if response
|
106
153
|
cache_key = generate_cache_key(store, original_html)
|
107
154
|
api_host = if store.dev_mode?
|
@@ -115,14 +162,15 @@ module Wovnrb
|
|
115
162
|
'Accept' => '*/*',
|
116
163
|
'Accept-Encoding' => 'gzip',
|
117
164
|
'Content-Length' => compressed_data.bytesize,
|
118
|
-
'Content-Type' => 'application/
|
165
|
+
'Content-Type' => 'application/json',
|
166
|
+
'Content-Encoding' => 'gzip',
|
119
167
|
'User-Agent' => 'Ruby'
|
120
168
|
}
|
121
169
|
stub_response_json = "{\"body\":\"#{translated_html.gsub("\n", '\n')}\"}"
|
122
|
-
stub_response = if
|
123
|
-
stub_response_json
|
124
|
-
else
|
170
|
+
stub_response = if compress_data
|
125
171
|
compress(stub_response_json)
|
172
|
+
else
|
173
|
+
stub_response_json
|
126
174
|
end
|
127
175
|
response_headers = { 'Content-Encoding' => response[:encoding] || 'gzip' }
|
128
176
|
stub_request(:post, api_url)
|
@@ -147,19 +195,18 @@ module Wovnrb
|
|
147
195
|
'lang_code' => 'fr',
|
148
196
|
'url_pattern' => 'subdomain',
|
149
197
|
'lang_param_name' => 'lang',
|
198
|
+
'translate_canonical_tag' => true,
|
150
199
|
'product' => 'WOVN.rb',
|
151
200
|
'version' => VERSION,
|
152
201
|
'body' => original_html,
|
153
202
|
'custom_lang_aliases' => '{"ja":"Japanese"}'
|
154
203
|
}
|
155
204
|
|
156
|
-
data.
|
205
|
+
data.to_json
|
157
206
|
end
|
158
207
|
|
159
208
|
def compress(string)
|
160
|
-
|
161
|
-
gzip << string
|
162
|
-
gzip.close.string
|
209
|
+
ActiveSupport::Gzip.compress(string)
|
163
210
|
end
|
164
211
|
end
|
165
212
|
end
|
@@ -2,7 +2,7 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
module Wovnrb
|
4
4
|
class HtmlConverterTest < WovnMiniTest
|
5
|
-
|
5
|
+
test 'build API compatible html' do
|
6
6
|
converter = prepare_html_converter('<html><body><a class="test">hello</a></body></html>', supported_langs: %w[en vi])
|
7
7
|
converted_html, = converter.build_api_compatible_html
|
8
8
|
|
@@ -10,7 +10,7 @@ module Wovnrb
|
|
10
10
|
assert_equal(expected_html, converted_html)
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
test 'build API compatible html - with custom lang param name' do
|
14
14
|
settings = {
|
15
15
|
supported_langs: %w[en vi],
|
16
16
|
url_lang_pattern: 'query',
|
@@ -23,7 +23,7 @@ module Wovnrb
|
|
23
23
|
assert_equal(expected_html, converted_html)
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
test 'build API compatible html - excessively large HTML' do
|
27
27
|
long_string = 'a' * 60_000
|
28
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
|
@@ -32,7 +32,7 @@ module Wovnrb
|
|
32
32
|
assert_equal(expected_html, converted_html)
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
test 'build API compatible html - ignored content should not be sent' do
|
36
36
|
html = [
|
37
37
|
'<html><body>',
|
38
38
|
'<p>Hello <span wovn-ignore>WOVN</span><p>',
|
@@ -45,11 +45,11 @@ 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
|
|
52
|
-
|
52
|
+
test 'build API compatible html - do not send html form' do
|
53
53
|
html = [
|
54
54
|
'<html><body>',
|
55
55
|
'<form action="/test" method="POST">',
|
@@ -62,11 +62,11 @@ 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
|
|
69
|
-
|
69
|
+
test 'build API compatible html - do not send hidden form input' do
|
70
70
|
html = [
|
71
71
|
'<html><body>',
|
72
72
|
'<input id="user-id" type="hidden" value="secret-id">',
|
@@ -91,7 +91,7 @@ module Wovnrb
|
|
91
91
|
assert_equal(expected_convert_html, converted_html)
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
test 'Transform HTML' do
|
95
95
|
converter = prepare_html_converter('<html><body><a>hello</a></body></html>', supported_langs: %w[en vi])
|
96
96
|
translated_html = converter.build
|
97
97
|
|
@@ -99,7 +99,7 @@ module Wovnrb
|
|
99
99
|
assert_equal(expected_html, translated_html)
|
100
100
|
end
|
101
101
|
|
102
|
-
|
102
|
+
test 'Transform HTML - with empty supported langs' do
|
103
103
|
converter = prepare_html_converter('<html><body><a>hello</a></body></html>', supported_langs: [])
|
104
104
|
translated_html = converter.build
|
105
105
|
|
@@ -107,7 +107,7 @@ module Wovnrb
|
|
107
107
|
assert_equal(expected_html, translated_html)
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
test 'Transform HTML - with head tag' do
|
111
111
|
converter = prepare_html_converter('<html><head><title>TITLE</title></head><body><a>hello</a></body></html>', supported_langs: %w[en vi])
|
112
112
|
translated_html = converter.build
|
113
113
|
|
@@ -115,7 +115,7 @@ module Wovnrb
|
|
115
115
|
assert_equal(expected_html, translated_html)
|
116
116
|
end
|
117
117
|
|
118
|
-
|
118
|
+
test 'Transform HTML - without body' do
|
119
119
|
converter = prepare_html_converter('<html>hello<a>world</a></html>', supported_langs: [])
|
120
120
|
translated_html = converter.build
|
121
121
|
|
@@ -123,7 +123,7 @@ module Wovnrb
|
|
123
123
|
assert_equal(expected_html, translated_html)
|
124
124
|
end
|
125
125
|
|
126
|
-
|
126
|
+
test 'Transform HTML - default lang - with query pattern and supported langs defined' do
|
127
127
|
dom = get_dom('<html>hello<a>world</a></html>')
|
128
128
|
settings = {
|
129
129
|
'default_lang' => 'en',
|
@@ -131,14 +131,101 @@ module Wovnrb
|
|
131
131
|
'url_pattern' => 'query'
|
132
132
|
}
|
133
133
|
store, headers = store_headers_factory(settings)
|
134
|
-
|
134
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
135
|
+
converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
|
135
136
|
translated_html = converter.build
|
136
137
|
|
137
138
|
expected_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=\"ja\" href=\"http://my-site.com/?wovn=ja\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/?wovn=vi\"></head><body>hello<a>world</a></body></html>"
|
138
139
|
assert_equal(expected_html, translated_html)
|
139
140
|
end
|
140
141
|
|
141
|
-
|
142
|
+
test 'Transform HTML - canonical tag - target lang - should translate' do
|
143
|
+
dom = get_dom('<html><head><link rel="canonical" href="http://my-site.com/" /></head><body></body></html>')
|
144
|
+
settings = {
|
145
|
+
'default_lang' => 'en',
|
146
|
+
'supported_langs' => %w[en ja vi],
|
147
|
+
'url_pattern' => 'path',
|
148
|
+
'translate_canonical_tag' => true
|
149
|
+
}
|
150
|
+
store, headers = store_headers_factory(settings, 'http://my-site.com/vi/')
|
151
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
152
|
+
converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
|
153
|
+
translated_html = converter.build
|
154
|
+
|
155
|
+
expected_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=vi&defaultLang=en&urlPattern=path&langCodeAliases={}&langParamName=wovn&version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script><link rel=\"canonical\" href=\"http://my-site.com/vi/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"ja\" href=\"http://my-site.com/ja/\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/vi/\"></head><body></body></html>"
|
156
|
+
assert_equal(expected_html, translated_html)
|
157
|
+
end
|
158
|
+
|
159
|
+
test 'Transform HTML - canonical tag - default lang - path pattern - no need to translate' do
|
160
|
+
dom = get_dom('<html><head><link rel="canonical" href="http://my-site.com/" /></head><body></body></html>')
|
161
|
+
settings = {
|
162
|
+
'default_lang' => 'en',
|
163
|
+
'supported_langs' => %w[en ja vi],
|
164
|
+
'url_pattern' => 'path',
|
165
|
+
'translate_canonical_tag' => true
|
166
|
+
}
|
167
|
+
store, headers = store_headers_factory(settings, 'http://my-site.com/')
|
168
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
169
|
+
converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
|
170
|
+
translated_html = converter.build
|
171
|
+
|
172
|
+
expected_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=path&langCodeAliases={}&langParamName=wovn&version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script><link rel=\"canonical\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"ja\" href=\"http://my-site.com/ja/\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/vi/\"></head><body></body></html>"
|
173
|
+
assert_equal(expected_html, translated_html)
|
174
|
+
end
|
175
|
+
|
176
|
+
test 'Transform HTML - canonical tag - default lang - query pattern - no need to translate' do
|
177
|
+
dom = get_dom('<html><head><link rel="canonical" href="http://my-site.com/" /></head><body></body></html>')
|
178
|
+
settings = {
|
179
|
+
'default_lang' => 'en',
|
180
|
+
'supported_langs' => %w[en ja vi],
|
181
|
+
'url_pattern' => 'query',
|
182
|
+
'translate_canonical_tag' => true
|
183
|
+
}
|
184
|
+
store, headers = store_headers_factory(settings, 'http://my-site.com/')
|
185
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
186
|
+
converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
|
187
|
+
translated_html = converter.build
|
188
|
+
|
189
|
+
expected_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=\"canonical\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><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></body></html>"
|
190
|
+
assert_equal(expected_html, translated_html)
|
191
|
+
end
|
192
|
+
|
193
|
+
test 'Transform HTML - canonical tag - default lang - has default lang alias - should use alias' do
|
194
|
+
dom = get_dom('<html><head><link rel="canonical" href="http://my-site.com/" /></head><body></body></html>')
|
195
|
+
settings = {
|
196
|
+
'default_lang' => 'en',
|
197
|
+
'supported_langs' => %w[en ja vi],
|
198
|
+
'url_pattern' => 'query',
|
199
|
+
'translate_canonical_tag' => true,
|
200
|
+
'custom_lang_aliases' => { 'en' => 'english' }
|
201
|
+
}
|
202
|
+
store, headers = store_headers_factory(settings, 'http://my-site.com/')
|
203
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
204
|
+
converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
|
205
|
+
translated_html = converter.build
|
206
|
+
|
207
|
+
expected_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={"en":"english"}&langParamName=wovn&version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script><link rel=\"canonical\" href=\"http://my-site.com/?wovn=english\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><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></body></html>"
|
208
|
+
assert_equal(expected_html, translated_html)
|
209
|
+
end
|
210
|
+
|
211
|
+
test 'Transform HTML - canonical tag - disabled - do not translate' do
|
212
|
+
dom = get_dom('<html><head><link rel="canonical" href="http://my-site.com/" /></head><body></body></html>')
|
213
|
+
settings = {
|
214
|
+
'default_lang' => 'en',
|
215
|
+
'supported_langs' => %w[en ja vi],
|
216
|
+
'url_pattern' => 'path',
|
217
|
+
'translate_canonical_tag' => false
|
218
|
+
}
|
219
|
+
store, headers = store_headers_factory(settings, 'http://my-site.com/vi/')
|
220
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
221
|
+
converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
|
222
|
+
translated_html = converter.build
|
223
|
+
|
224
|
+
expected_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=vi&defaultLang=en&urlPattern=path&langCodeAliases={}&langParamName=wovn&version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script><link rel=\"canonical\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"ja\" href=\"http://my-site.com/ja/\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/vi/\"></head><body></body></html>"
|
225
|
+
assert_equal(expected_html, translated_html)
|
226
|
+
end
|
227
|
+
|
228
|
+
test 'Transform HTML - default lang - with path pattern and supported langs defined' do
|
142
229
|
dom = get_dom('<html>hello<a>world</a></html>')
|
143
230
|
settings = {
|
144
231
|
'default_lang' => 'en',
|
@@ -146,14 +233,15 @@ module Wovnrb
|
|
146
233
|
'url_pattern' => 'path'
|
147
234
|
}
|
148
235
|
store, headers = store_headers_factory(settings)
|
149
|
-
|
236
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
237
|
+
converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
|
150
238
|
translated_html = converter.build
|
151
239
|
|
152
240
|
expected_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=path&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=\"ja\" href=\"http://my-site.com/ja/\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/vi/\"></head><body>hello<a>world</a></body></html>"
|
153
241
|
assert_equal(expected_html, translated_html)
|
154
242
|
end
|
155
243
|
|
156
|
-
|
244
|
+
test 'replace_snippet' do
|
157
245
|
converter = prepare_html_converter('<html><head>
|
158
246
|
<script src="/a"></script>
|
159
247
|
<script src="//j.wovn.io/1" async="true">
|
@@ -161,21 +249,46 @@ module Wovnrb
|
|
161
249
|
<script src="https//cdn.wovn.io/" data-wovnio="key=2wpv0n async></script>
|
162
250
|
<script src="https://wovn.global.ssl.fastly.net/widget/abcdef></script>
|
163
251
|
</head></html>')
|
164
|
-
converter.
|
165
|
-
|
166
|
-
|
167
|
-
assert_equal(
|
252
|
+
translated_html = converter.build
|
253
|
+
dom = Helpers::NokogumboHelper.parse_html(translated_html)
|
254
|
+
scripts = dom.css('script')
|
255
|
+
assert_equal(2, scripts.length)
|
256
|
+
expected_wovn_script = "<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>"
|
257
|
+
assert_equal(expected_wovn_script, scripts.first.to_html)
|
168
258
|
end
|
169
259
|
|
170
|
-
|
260
|
+
test 'replace_hreflangs' do
|
171
261
|
converter = prepare_html_converter('<html><head><link rel="alternate" hreflang="en" href="https://wovn.io/en/"></head></html>')
|
172
|
-
converter.
|
173
|
-
|
174
|
-
|
175
|
-
assert_equal(
|
262
|
+
translated_html = converter.build
|
263
|
+
dom = Helpers::NokogumboHelper.parse_html(translated_html)
|
264
|
+
href_langs = dom.css('link[rel="alternate"]')
|
265
|
+
assert_equal(4, href_langs.length)
|
266
|
+
expected_href_langs = {
|
267
|
+
'en' =>
|
268
|
+
{
|
269
|
+
'href' => 'http://my-site.com/'
|
270
|
+
},
|
271
|
+
'fr' =>
|
272
|
+
{
|
273
|
+
'href' => 'http://my-site.com/?wovn=fr'
|
274
|
+
},
|
275
|
+
'ja' =>
|
276
|
+
{
|
277
|
+
'href' => 'http://my-site.com/?wovn=ja'
|
278
|
+
},
|
279
|
+
'vi' =>
|
280
|
+
{
|
281
|
+
'href' => 'http://my-site.com/?wovn=vi'
|
282
|
+
}
|
283
|
+
}
|
284
|
+
href_langs.each do |node|
|
285
|
+
assertions = expected_href_langs[node['hreflang']]
|
286
|
+
assert_not_nil(assertions)
|
287
|
+
assert_equal(assertions['href'], node['href'])
|
288
|
+
end
|
176
289
|
end
|
177
290
|
|
178
|
-
|
291
|
+
test 'inject_lang_html_tag - with no lang in HTML tag - should inject' do
|
179
292
|
settings = default_store_settings
|
180
293
|
store = Wovnrb::Store.instance
|
181
294
|
store.update_settings(settings)
|
@@ -184,13 +297,14 @@ module Wovnrb
|
|
184
297
|
Wovnrb.get_env('url' => 'http://my-site.com/'),
|
185
298
|
Wovnrb.get_settings(settings)
|
186
299
|
)
|
187
|
-
|
188
|
-
converter.
|
189
|
-
|
190
|
-
|
300
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
301
|
+
converter = HtmlConverter.new(get_dom('<html><body>hello</body></html>'), store, headers, url_lang_switcher)
|
302
|
+
translated_html = converter.build
|
303
|
+
dom = Helpers::NokogumboHelper.parse_html(translated_html)
|
304
|
+
assert_equal('en', dom.at_css('html')['lang'])
|
191
305
|
end
|
192
306
|
|
193
|
-
|
307
|
+
test 'inject_lang_html_tag - with lang in HTML tag - do not override' do
|
194
308
|
settings = default_store_settings
|
195
309
|
store = Wovnrb::Store.instance
|
196
310
|
store.update_settings(settings)
|
@@ -199,26 +313,85 @@ module Wovnrb
|
|
199
313
|
Wovnrb.get_env('url' => 'http://my-site.com/'),
|
200
314
|
Wovnrb.get_settings(settings)
|
201
315
|
)
|
202
|
-
|
203
|
-
converter.
|
204
|
-
|
205
|
-
|
316
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
317
|
+
converter = HtmlConverter.new(get_dom('<html lang="th"><body>hello</body></html>'), store, headers, url_lang_switcher)
|
318
|
+
translated_html = converter.build
|
319
|
+
dom = Helpers::NokogumboHelper.parse_html(translated_html)
|
320
|
+
assert_equal('th', dom.at_css('html')['lang'])
|
321
|
+
end
|
322
|
+
|
323
|
+
test 'translate_canonical_tag' do
|
324
|
+
settings = default_store_settings
|
325
|
+
store = Wovnrb::Store.instance
|
326
|
+
store.update_settings(settings)
|
327
|
+
|
328
|
+
headers = Wovnrb::Headers.new(
|
329
|
+
Wovnrb.get_env('url' => 'http://my-site.com/?wovn=fr'),
|
330
|
+
store.settings
|
331
|
+
)
|
332
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
333
|
+
converter = HtmlConverter.new(get_dom('<html lang="th"><head><link rel="canonical" href="http://my-site.com" /></head><body>hello</body></html>'), store, headers, url_lang_switcher)
|
334
|
+
translated_html = converter.build
|
335
|
+
dom = Helpers::NokogumboHelper.parse_html(translated_html)
|
336
|
+
canonical_tag = dom.at_css('link[rel="canonical"]')
|
337
|
+
assert_not_nil(canonical_tag)
|
338
|
+
assert_equal('http://my-site.com?wovn=fr', canonical_tag['href'])
|
339
|
+
end
|
340
|
+
|
341
|
+
test 'translate_canonical_tag - path pattern' do
|
342
|
+
settings = default_store_settings
|
343
|
+
settings['url_pattern'] = 'path'
|
344
|
+
store = Wovnrb::Store.instance
|
345
|
+
store.update_settings(settings)
|
346
|
+
|
347
|
+
headers = Wovnrb::Headers.new(
|
348
|
+
Wovnrb.get_env('url' => 'http://my-site.com/fr/'),
|
349
|
+
store.settings
|
350
|
+
)
|
351
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
352
|
+
converter = HtmlConverter.new(get_dom('<html lang="th"><head><link rel="canonical" href="http://my-site.com/" /></head><body>hello</body></html>'), store, headers, url_lang_switcher)
|
353
|
+
translated_html = converter.build
|
354
|
+
dom = Helpers::NokogumboHelper.parse_html(translated_html)
|
355
|
+
canonical_tag = dom.at_css('link[rel="canonical"]')
|
356
|
+
assert_not_nil(canonical_tag)
|
357
|
+
assert_equal('http://my-site.com/fr/', canonical_tag['href'])
|
358
|
+
end
|
359
|
+
|
360
|
+
test 'translate_canonical_tag - canonical tag is already translated' do
|
361
|
+
# NOTE: this behavior is not correct, but it is the same as html-swapper
|
362
|
+
settings = default_store_settings
|
363
|
+
settings['url_pattern'] = 'path'
|
364
|
+
store = Wovnrb::Store.instance
|
365
|
+
store.update_settings(settings)
|
366
|
+
|
367
|
+
headers = Wovnrb::Headers.new(
|
368
|
+
Wovnrb.get_env('url' => 'http://my-site.com/fr/'),
|
369
|
+
store.settings
|
370
|
+
)
|
371
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
372
|
+
converter = HtmlConverter.new(get_dom('<html lang="th"><head><link rel="canonical" href="http://my-site.com/fr/" /></head><body>hello</body></html>'), store, headers, url_lang_switcher)
|
373
|
+
translated_html = converter.build
|
374
|
+
dom = Helpers::NokogumboHelper.parse_html(translated_html)
|
375
|
+
canonical_tag = dom.at_css('link[rel="canonical"]')
|
376
|
+
assert_not_nil(canonical_tag)
|
377
|
+
assert_equal('http://my-site.com/fr/fr/', canonical_tag['href'])
|
206
378
|
end
|
207
379
|
|
208
380
|
private
|
209
381
|
|
210
382
|
def prepare_html_converter(input_html, store_options = {})
|
211
383
|
store, headers = store_headers_factory(store_options)
|
212
|
-
|
384
|
+
url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
|
385
|
+
HtmlConverter.new(get_dom(input_html), store, headers, url_lang_switcher)
|
213
386
|
end
|
214
387
|
|
215
|
-
def store_headers_factory(setting_opts = {})
|
388
|
+
def store_headers_factory(setting_opts = {}, url = 'http://my-site.com')
|
216
389
|
settings = default_store_settings.merge(setting_opts)
|
217
390
|
store = Wovnrb::Store.instance
|
218
391
|
store.update_settings(settings)
|
219
392
|
|
220
393
|
headers = Wovnrb::Headers.new(
|
221
|
-
Wovnrb.get_env('url' =>
|
394
|
+
Wovnrb.get_env('url' => url),
|
222
395
|
store.settings
|
223
396
|
)
|
224
397
|
|