wovnrb 3.11.0 → 3.11.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,217 +1,217 @@
1
- require 'test_helper'
2
-
3
- module Wovnrb
4
- REQUEST_UUID = 'ABCD'.freeze
5
-
6
- class ApiTranslatorTest < WovnMiniTest
7
- def test_translate
8
- assert_translation('test.html', 'test_translated.html', true)
9
- end
10
-
11
- def test_translate_falls_back_to_original_body_if_exception
12
- Net::HTTP.any_instance.expects(:request).raises
13
- assert_translation('test.html', 'test_translated.html', false, response: nil)
14
- end
15
-
16
- def test_translate_falls_back_to_original_body_if_api_error
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)
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 })
26
- end
27
-
28
- def test_translate_accepts_uncompressed_response_from_api_in_dev_mode
29
- Wovnrb::Store.instance.update_settings('wovn_dev_mode' => true)
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
- 'translate_canonical_tag' => true,
58
- 'insert_hreflangs' => true,
59
- 'product' => 'WOVN.rb',
60
- 'version' => VERSION,
61
- 'body' => 'foo',
62
- 'custom_lang_aliases' => { 'ja' => 'Japanese' }.to_json
63
- }.to_json,
64
- times: 1
65
- end
66
-
67
- def test_api_timeout_is_search_engine_user_higher_default
68
- settings = {
69
- 'project_token' => '123456',
70
- 'custom_lang_aliases' => { 'ja' => 'Japanese' },
71
- 'default_lang' => 'en',
72
- 'url_pattern' => 'subdomain',
73
- 'url_pattern_reg' => '^(?<lang>[^.]+)\.',
74
- 'lang_param_name' => 'lang'
75
- }
76
- store = Wovnrb::Store.instance
77
- store.update_settings(settings)
78
- headers = Wovnrb::Headers.new(
79
- 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)'),
80
- Wovnrb.get_settings(settings),
81
- UrlLanguageSwitcher.new(store)
82
- )
83
- api_translator = ApiTranslator.new(store, headers, REQUEST_UUID)
84
- assert_equal(5.0, api_translator.send(:api_timeout))
85
- end
86
-
87
- def test_api_timeout_no_user_agent_use_normal_default
88
- settings = {
89
- 'project_token' => '123456',
90
- 'custom_lang_aliases' => { 'ja' => 'Japanese' },
91
- 'default_lang' => 'en',
92
- 'url_pattern' => 'subdomain',
93
- 'url_pattern_reg' => '^(?<lang>[^.]+)\.',
94
- 'lang_param_name' => 'lang'
95
- }
96
- store = Wovnrb::Store.instance
97
- store.update_settings(settings)
98
- env = Wovnrb.get_env('url' => 'http://fr.wovn.io/test')
99
- env.delete('HTTP_USER_AGENT')
100
- headers = Wovnrb::Headers.new(
101
- env,
102
- Wovnrb.get_settings(settings),
103
- UrlLanguageSwitcher.new(store)
104
- )
105
- api_translator = ApiTranslator.new(store, headers, REQUEST_UUID)
106
- assert_equal(1.0, api_translator.send(:api_timeout))
107
- end
108
-
109
- private
110
-
111
- def assert_translation(original_html_fixture, translated_html_fixture, success_expected, response: { encoding: 'gzip', status_code: 200 }, compress_data: true)
112
- original_html = File.read("test/fixtures/html/#{original_html_fixture}")
113
- translated_html = File.read("test/fixtures/html/#{translated_html_fixture}")
114
- actual_translated_html = translate(original_html, translated_html, response, compress_data: compress_data)
115
-
116
- if success_expected
117
- assert_equal(actual_translated_html, translated_html)
118
- else
119
- assert_equal(actual_translated_html, original_html)
120
- end
121
- end
122
-
123
- def translate(original_html, translated_html, response, compress_data: true)
124
- api_translator, store, _headers = create_sut
125
- translation_request_stub = stub_translation_api_request(store, original_html, translated_html, response, compress_data: compress_data)
126
-
127
- expected_api_timeout = store.settings['api_timeout_seconds']
128
- assert_equal(expected_api_timeout, api_translator.send(:api_timeout))
129
- actual_translated_html = api_translator.translate(original_html)
130
- assert_requested(translation_request_stub, times: 1) if translation_request_stub
131
- actual_translated_html
132
- end
133
-
134
- def create_sut
135
- settings = {
136
- 'project_token' => '123456',
137
- 'custom_lang_aliases' => { 'ja' => 'Japanese' },
138
- 'default_lang' => 'en',
139
- 'url_pattern' => 'subdomain',
140
- 'url_pattern_reg' => '^(?<lang>[^.]+)\.',
141
- 'lang_param_name' => 'lang'
142
- }
143
- store = Wovnrb::Store.instance
144
- store.update_settings(settings)
145
- headers = Wovnrb::Headers.new(
146
- Wovnrb.get_env('url' => 'http://fr.wovn.io/test'),
147
- Wovnrb.get_settings(settings),
148
- UrlLanguageSwitcher.new(store)
149
- )
150
- api_translator = ApiTranslator.new(store, headers, REQUEST_UUID)
151
-
152
- [api_translator, store, headers]
153
- end
154
-
155
- def stub_translation_api_request(store, original_html, translated_html, response, compress_data: true)
156
- if response
157
- cache_key = generate_cache_key(store, original_html)
158
- api_host = if store.dev_mode?
159
- 'dev-wovn.io:3001'
160
- else
161
- 'wovn.global.ssl.fastly.net'
162
- end
163
- api_url = "http://#{api_host}/v0/translation?cache_key=#{cache_key}"
164
- compressed_data = compress(generate_data(original_html))
165
- headers = {
166
- 'Accept' => '*/*',
167
- 'Accept-Encoding' => 'gzip',
168
- 'Content-Length' => compressed_data.bytesize,
169
- 'Content-Type' => 'application/json',
170
- 'Content-Encoding' => 'gzip',
171
- 'User-Agent' => 'Ruby'
172
- }
173
- stub_response_json = "{\"body\":\"#{translated_html.gsub("\n", '\n')}\"}"
174
- stub_response = if compress_data
175
- compress(stub_response_json)
176
- else
177
- stub_response_json
178
- end
179
- response_headers = { 'Content-Encoding' => response[:encoding] || 'gzip' }
180
- stub_request(:post, api_url)
181
- .with(body: compressed_data, headers: headers)
182
- .to_return(status: response[:status_code] || 200, body: stub_response, headers: response_headers)
183
-
184
- end
185
- end
186
-
187
- def generate_cache_key(store, original_html)
188
- settings_hash = Digest::MD5.hexdigest(JSON.dump(store.settings))
189
- body_hash = Digest::MD5.hexdigest(original_html)
190
- escaped_key = CGI.escape("token=123456&settings_hash=#{settings_hash}&body_hash=#{body_hash}&path=/test&lang=fr&version=wovnrb_#{VERSION}")
191
-
192
- "(#{escaped_key})"
193
- end
194
-
195
- def generate_data(original_html)
196
- data = {
197
- 'url' => 'http://wovn.io/test',
198
- 'token' => '123456',
199
- 'lang_code' => 'fr',
200
- 'url_pattern' => 'subdomain',
201
- 'lang_param_name' => 'lang',
202
- 'translate_canonical_tag' => true,
203
- 'insert_hreflangs' => true,
204
- 'product' => 'WOVN.rb',
205
- 'version' => VERSION,
206
- 'body' => original_html,
207
- 'custom_lang_aliases' => '{"ja":"Japanese"}'
208
- }
209
-
210
- data.to_json
211
- end
212
-
213
- def compress(string)
214
- ActiveSupport::Gzip.compress(string)
215
- end
216
- end
217
- end
1
+ require 'test_helper'
2
+
3
+ module Wovnrb
4
+ REQUEST_UUID = 'ABCD'.freeze
5
+
6
+ class ApiTranslatorTest < WovnMiniTest
7
+ def test_translate
8
+ assert_translation('test.html', 'test_translated.html', true)
9
+ end
10
+
11
+ def test_translate_falls_back_to_original_body_if_exception
12
+ Net::HTTP.any_instance.expects(:request).raises
13
+ assert_translation('test.html', 'test_translated.html', false, response: nil)
14
+ end
15
+
16
+ def test_translate_falls_back_to_original_body_if_api_error
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)
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 })
26
+ end
27
+
28
+ def test_translate_accepts_uncompressed_response_from_api_in_dev_mode
29
+ Wovnrb::Store.instance.update_settings('wovn_dev_mode' => true)
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
+ 'translate_canonical_tag' => true,
58
+ 'insert_hreflangs' => true,
59
+ 'product' => 'WOVN.rb',
60
+ 'version' => VERSION,
61
+ 'body' => 'foo',
62
+ 'custom_lang_aliases' => { 'ja' => 'Japanese' }.to_json
63
+ }.to_json,
64
+ times: 1
65
+ end
66
+
67
+ def test_api_timeout_is_search_engine_user_higher_default
68
+ settings = {
69
+ 'project_token' => '123456',
70
+ 'custom_lang_aliases' => { 'ja' => 'Japanese' },
71
+ 'default_lang' => 'en',
72
+ 'url_pattern' => 'subdomain',
73
+ 'url_pattern_reg' => '^(?<lang>[^.]+)\.',
74
+ 'lang_param_name' => 'lang'
75
+ }
76
+ store = Wovnrb::Store.instance
77
+ store.update_settings(settings)
78
+ headers = Wovnrb::Headers.new(
79
+ 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)'),
80
+ Wovnrb.get_settings(settings),
81
+ UrlLanguageSwitcher.new(store)
82
+ )
83
+ api_translator = ApiTranslator.new(store, headers, REQUEST_UUID)
84
+ assert_equal(5.0, api_translator.send(:api_timeout))
85
+ end
86
+
87
+ def test_api_timeout_no_user_agent_use_normal_default
88
+ settings = {
89
+ 'project_token' => '123456',
90
+ 'custom_lang_aliases' => { 'ja' => 'Japanese' },
91
+ 'default_lang' => 'en',
92
+ 'url_pattern' => 'subdomain',
93
+ 'url_pattern_reg' => '^(?<lang>[^.]+)\.',
94
+ 'lang_param_name' => 'lang'
95
+ }
96
+ store = Wovnrb::Store.instance
97
+ store.update_settings(settings)
98
+ env = Wovnrb.get_env('url' => 'http://fr.wovn.io/test')
99
+ env.delete('HTTP_USER_AGENT')
100
+ headers = Wovnrb::Headers.new(
101
+ env,
102
+ Wovnrb.get_settings(settings),
103
+ UrlLanguageSwitcher.new(store)
104
+ )
105
+ api_translator = ApiTranslator.new(store, headers, REQUEST_UUID)
106
+ assert_equal(1.0, api_translator.send(:api_timeout))
107
+ end
108
+
109
+ private
110
+
111
+ def assert_translation(original_html_fixture, translated_html_fixture, success_expected, response: { encoding: 'gzip', status_code: 200 }, compress_data: true)
112
+ original_html = File.read("test/fixtures/html/#{original_html_fixture}")
113
+ translated_html = File.read("test/fixtures/html/#{translated_html_fixture}")
114
+ actual_translated_html = translate(original_html, translated_html, response, compress_data: compress_data)
115
+
116
+ if success_expected
117
+ assert_equal(actual_translated_html, translated_html)
118
+ else
119
+ assert_equal(actual_translated_html, original_html)
120
+ end
121
+ end
122
+
123
+ def translate(original_html, translated_html, response, compress_data: true)
124
+ api_translator, store, _headers = create_sut
125
+ translation_request_stub = stub_translation_api_request(store, original_html, translated_html, response, compress_data: compress_data)
126
+
127
+ expected_api_timeout = store.settings['api_timeout_seconds']
128
+ assert_equal(expected_api_timeout, api_translator.send(:api_timeout))
129
+ actual_translated_html = api_translator.translate(original_html)
130
+ assert_requested(translation_request_stub, times: 1) if translation_request_stub
131
+ actual_translated_html
132
+ end
133
+
134
+ def create_sut
135
+ settings = {
136
+ 'project_token' => '123456',
137
+ 'custom_lang_aliases' => { 'ja' => 'Japanese' },
138
+ 'default_lang' => 'en',
139
+ 'url_pattern' => 'subdomain',
140
+ 'url_pattern_reg' => '^(?<lang>[^.]+)\.',
141
+ 'lang_param_name' => 'lang'
142
+ }
143
+ store = Wovnrb::Store.instance
144
+ store.update_settings(settings)
145
+ headers = Wovnrb::Headers.new(
146
+ Wovnrb.get_env('url' => 'http://fr.wovn.io/test'),
147
+ Wovnrb.get_settings(settings),
148
+ UrlLanguageSwitcher.new(store)
149
+ )
150
+ api_translator = ApiTranslator.new(store, headers, REQUEST_UUID)
151
+
152
+ [api_translator, store, headers]
153
+ end
154
+
155
+ def stub_translation_api_request(store, original_html, translated_html, response, compress_data: true)
156
+ if response
157
+ cache_key = generate_cache_key(store, original_html)
158
+ api_host = if store.dev_mode?
159
+ 'dev-wovn.io:3001'
160
+ else
161
+ 'wovn.global.ssl.fastly.net'
162
+ end
163
+ api_url = "http://#{api_host}/v0/translation?cache_key=#{cache_key}"
164
+ compressed_data = compress(generate_data(original_html))
165
+ headers = {
166
+ 'Accept' => '*/*',
167
+ 'Accept-Encoding' => 'gzip',
168
+ 'Content-Length' => compressed_data.bytesize,
169
+ 'Content-Type' => 'application/json',
170
+ 'Content-Encoding' => 'gzip',
171
+ 'User-Agent' => 'Ruby'
172
+ }
173
+ stub_response_json = "{\"body\":\"#{translated_html.gsub("\n", '\n')}\"}"
174
+ stub_response = if compress_data
175
+ compress(stub_response_json)
176
+ else
177
+ stub_response_json
178
+ end
179
+ response_headers = { 'Content-Encoding' => response[:encoding] || 'gzip' }
180
+ stub_request(:post, api_url)
181
+ .with(body: compressed_data, headers: headers)
182
+ .to_return(status: response[:status_code] || 200, body: stub_response, headers: response_headers)
183
+
184
+ end
185
+ end
186
+
187
+ def generate_cache_key(store, original_html)
188
+ settings_hash = Digest::MD5.hexdigest(JSON.dump(store.settings))
189
+ body_hash = Digest::MD5.hexdigest(original_html)
190
+ escaped_key = CGI.escape("token=123456&settings_hash=#{settings_hash}&body_hash=#{body_hash}&path=/test&lang=fr&version=wovnrb_#{VERSION}")
191
+
192
+ "(#{escaped_key})"
193
+ end
194
+
195
+ def generate_data(original_html)
196
+ data = {
197
+ 'url' => 'http://wovn.io/test',
198
+ 'token' => '123456',
199
+ 'lang_code' => 'fr',
200
+ 'url_pattern' => 'subdomain',
201
+ 'lang_param_name' => 'lang',
202
+ 'translate_canonical_tag' => true,
203
+ 'insert_hreflangs' => true,
204
+ 'product' => 'WOVN.rb',
205
+ 'version' => VERSION,
206
+ 'body' => original_html,
207
+ 'custom_lang_aliases' => '{"ja":"Japanese"}'
208
+ }
209
+
210
+ data.to_json
211
+ end
212
+
213
+ def compress(string)
214
+ ActiveSupport::Gzip.compress(string)
215
+ end
216
+ end
217
+ end
@@ -1,59 +1,59 @@
1
- require 'test_helper'
2
-
3
- module Wovnrb
4
- class LangTest < WovnMiniTest
5
- def test_langs_exist
6
- refute_nil(Wovnrb::Lang::LANG)
7
- end
8
-
9
- def test_keys_exist
10
- Wovnrb::Lang::LANG.each do |k, l|
11
- assert(l.key?(:name))
12
- assert(l.key?(:code))
13
- assert(l.key?(:en))
14
- assert_equal(k, l[:code])
15
- end
16
- end
17
-
18
- def test_iso_639_1_normalization
19
- Wovnrb::Lang::LANG.each do |_, l|
20
- case l[:code]
21
- when 'zh-CHS'
22
- assert_equal('zh-Hans', Lang.iso_639_1_normalization('zh-CHS'))
23
- when 'zh-CHT'
24
- assert_equal('zh-Hant', Lang.iso_639_1_normalization('zh-CHT'))
25
- else
26
- assert_equal(l[:code], Lang.iso_639_1_normalization(l[:code]))
27
- end
28
- end
29
- end
30
-
31
- def test_get_code_with_valid_code
32
- assert_equal('ms', Wovnrb::Lang.get_code('ms'))
33
- end
34
-
35
- def test_get_code_with_capital_letters
36
- assert_equal('zh-CHT', Wovnrb::Lang.get_code('zh-cht'))
37
- end
38
-
39
- def test_get_code_with_valid_english_name
40
- assert_equal('pt', Wovnrb::Lang.get_code('Portuguese'))
41
- end
42
-
43
- def test_get_code_with_valid_native_name
44
- assert_equal('hi', Wovnrb::Lang.get_code('हिन्दी'))
45
- end
46
-
47
- def test_get_code_with_invalid_name
48
- assert_nil(Wovnrb::Lang.get_code('WOVN4LYFE'))
49
- end
50
-
51
- def test_get_code_with_empty_string
52
- assert_nil(Wovnrb::Lang.get_code(''))
53
- end
54
-
55
- def test_get_code_with_nil
56
- assert_nil(Wovnrb::Lang.get_code(nil))
57
- end
58
- end
59
- end
1
+ require 'test_helper'
2
+
3
+ module Wovnrb
4
+ class LangTest < WovnMiniTest
5
+ def test_langs_exist
6
+ refute_nil(Wovnrb::Lang::LANG)
7
+ end
8
+
9
+ def test_keys_exist
10
+ Wovnrb::Lang::LANG.each do |k, l|
11
+ assert(l.key?(:name))
12
+ assert(l.key?(:code))
13
+ assert(l.key?(:en))
14
+ assert_equal(k, l[:code])
15
+ end
16
+ end
17
+
18
+ def test_iso_639_1_normalization
19
+ Wovnrb::Lang::LANG.each do |_, l|
20
+ case l[:code]
21
+ when 'zh-CHS'
22
+ assert_equal('zh-Hans', Lang.iso_639_1_normalization('zh-CHS'))
23
+ when 'zh-CHT'
24
+ assert_equal('zh-Hant', Lang.iso_639_1_normalization('zh-CHT'))
25
+ else
26
+ assert_equal(l[:code], Lang.iso_639_1_normalization(l[:code]))
27
+ end
28
+ end
29
+ end
30
+
31
+ def test_get_code_with_valid_code
32
+ assert_equal('ms', Wovnrb::Lang.get_code('ms'))
33
+ end
34
+
35
+ def test_get_code_with_capital_letters
36
+ assert_equal('zh-CHT', Wovnrb::Lang.get_code('zh-cht'))
37
+ end
38
+
39
+ def test_get_code_with_valid_english_name
40
+ assert_equal('pt', Wovnrb::Lang.get_code('Portuguese'))
41
+ end
42
+
43
+ def test_get_code_with_valid_native_name
44
+ assert_equal('hi', Wovnrb::Lang.get_code('हिन्दी'))
45
+ end
46
+
47
+ def test_get_code_with_invalid_name
48
+ assert_nil(Wovnrb::Lang.get_code('WOVN4LYFE'))
49
+ end
50
+
51
+ def test_get_code_with_empty_string
52
+ assert_nil(Wovnrb::Lang.get_code(''))
53
+ end
54
+
55
+ def test_get_code_with_nil
56
+ assert_nil(Wovnrb::Lang.get_code(nil))
57
+ end
58
+ end
59
+ end