wovnrb 3.8.0 → 3.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,422 +1,501 @@
1
- require 'test_helper'
2
-
3
- module Wovnrb
4
- class HtmlConverterTest < WovnMiniTest
5
- test 'build API compatible html' do
6
- converter = prepare_html_converter('<html><body><a class="test">hello</a></body></html>', supported_langs: %w[en vi])
7
- converted_html, = converter.build_api_compatible_html
8
-
9
- 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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><a class=\"test\">hello</a></body></html>"
10
- assert_equal(expected_html, converted_html)
11
- end
12
-
13
- test 'build API compatible html - with custom lang param name' do
14
- settings = {
15
- supported_langs: %w[en vi],
16
- url_lang_pattern: 'query',
17
- lang_param_name: 'lang'
18
- }
19
- converter = prepare_html_converter('<html><body><a class="test">hello</a></body></html>', settings)
20
- converted_html, = converter.build_api_compatible_html
21
-
22
- 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=lang&amp;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/?lang=vi\"></head><body><a class=\"test\">hello</a></body></html>"
23
- assert_equal(expected_html, converted_html)
24
- end
25
-
26
- test 'build API compatible html - excessively large HTML' do
27
- long_string = 'a' * 60_000
28
- converter = prepare_html_converter("<html><body><p>#{long_string}</p></body></html>", supported_langs: %w[en vi])
29
- converted_html, = converter.build_api_compatible_html
30
-
31
- 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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
- assert_equal(expected_html, converted_html)
33
- end
34
-
35
- test 'build API compatible html - ignored content should not be sent' do
36
- html = [
37
- '<html><body>',
38
- '<p>Hello <span wovn-ignore>WOVN</span><p>',
39
- '<p>Hello <span data-wovn-ignore>WOVN</span><p>',
40
- '<div><span class="ignore-me">should be ignored</span></div>',
41
- '<span>Have a nice day!</span>',
42
- '</body></html>'
43
- ].join
44
-
45
- converter = prepare_html_converter(html, ignore_class: ['ignore-me'])
46
- converted_html, = converter.build_api_compatible_html
47
-
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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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
- assert_equal(expected_convert_html, converted_html)
50
- end
51
-
52
- test 'build API compatible html - do not send html form' do
53
- html = [
54
- '<html><body>',
55
- '<form action="/test" method="POST">',
56
- '<input id="name" type="text">',
57
- '<button type="submit">Submit</button>',
58
- '</form>',
59
- '</body></html>'
60
- ].join
61
-
62
- converter = prepare_html_converter(html, ignore_class: [])
63
- converted_html, = converter.build_api_compatible_html
64
-
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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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
- assert_equal(expected_convert_html, converted_html)
67
- end
68
-
69
- test 'build API compatible html - do not send hidden form input' do
70
- html = [
71
- '<html><body>',
72
- '<input id="user-id" type="hidden" value="secret-id">',
73
- '<input id="password" type="hidden" value="secret-password">',
74
- '<input id="something" type="hidden" value="">',
75
- '<input id="name" type="text" value="wovn.io">',
76
- '</body></html>'
77
- ].join
78
-
79
- converter = prepare_html_converter(html, ignore_class: [])
80
- converted_html, = converter.build_api_compatible_html
81
-
82
- expected_convert_html = [
83
- '<html lang="en"><head>',
84
- "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"https://j.wovn.io/1\" async=\"true\" data-wovnio=\"key=123456&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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>",
85
- '<input id="user-id" type="hidden" value="__wovn-backend-ignored-key-0">',
86
- '<input id="password" type="hidden" value="__wovn-backend-ignored-key-1">',
87
- '<input id="something" type="hidden" value="__wovn-backend-ignored-key-2">',
88
- '<input id="name" type="text" value="wovn.io">',
89
- '</body></html>'
90
- ].join
91
- assert_equal(expected_convert_html, converted_html)
92
- end
93
-
94
- test 'Transform HTML' do
95
- converter = prepare_html_converter('<html><body><a>hello</a></body></html>', supported_langs: %w[en vi])
96
- translated_html = converter.build
97
-
98
- 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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><a>hello</a></body></html>"
99
- assert_equal(expected_html, translated_html)
100
- end
101
-
102
- test 'Transform HTML - with empty supported langs' do
103
- converter = prepare_html_converter('<html><body><a>hello</a></body></html>', supported_langs: [])
104
- translated_html = converter.build
105
-
106
- 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script></head><body><a>hello</a></body></html>"
107
- assert_equal(expected_html, translated_html)
108
- end
109
-
110
- test 'Transform HTML - with head tag' do
111
- converter = prepare_html_converter('<html><head><title>TITLE</title></head><body><a>hello</a></body></html>', supported_langs: %w[en vi])
112
- translated_html = converter.build
113
-
114
- 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script><title>TITLE</title><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/?wovn=vi\"></head><body><a>hello</a></body></html>"
115
- assert_equal(expected_html, translated_html)
116
- end
117
-
118
- test 'Transform HTML - without body' do
119
- converter = prepare_html_converter('<html>hello<a>world</a></html>', supported_langs: [])
120
- translated_html = converter.build
121
-
122
- 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script></head><body>hello<a>world</a></body></html>"
123
- assert_equal(expected_html, translated_html)
124
- end
125
-
126
- test 'Transform HTML - default lang - with query pattern and supported langs defined' do
127
- dom = get_dom('<html>hello<a>world</a></html>')
128
- settings = {
129
- 'default_lang' => 'en',
130
- 'supported_langs' => %w[en ja vi],
131
- 'url_pattern' => 'query'
132
- }
133
- store, headers = store_headers_factory(settings)
134
- url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
135
- converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
136
- translated_html = converter.build
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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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>"
139
- assert_equal(expected_html, translated_html)
140
- end
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&amp;backend=true&amp;currentLang=vi&amp;defaultLang=en&amp;urlPattern=path&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=path&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={&quot;en&quot;:&quot;english&quot;}&amp;langParamName=wovn&amp;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&amp;backend=true&amp;currentLang=vi&amp;defaultLang=en&amp;urlPattern=path&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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
229
- dom = get_dom('<html>hello<a>world</a></html>')
230
- settings = {
231
- 'default_lang' => 'en',
232
- 'supported_langs' => %w[en ja vi],
233
- 'url_pattern' => 'path'
234
- }
235
- store, headers = store_headers_factory(settings)
236
- url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
237
- converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
238
- translated_html = converter.build
239
-
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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=path&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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>"
241
- assert_equal(expected_html, translated_html)
242
- end
243
-
244
- test 'replace_snippet' do
245
- converter = prepare_html_converter('<html><head>
246
- <script src="/a"></script>
247
- <script src="//j.wovn.io/1" async="true">
248
- <script src="//j.wovn.io/1" data-wovnio="key=2wpv0n" async></script>
249
- <script src="https//cdn.wovn.io/" data-wovnio="key=2wpv0n async></script>
250
- <script src="https://wovn.global.ssl.fastly.net/widget/abcdef></script>
251
- </head></html>')
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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script>"
257
- assert_equal(expected_wovn_script, scripts.first.to_html)
258
- end
259
-
260
- test 'replace_hreflangs' do
261
- converter = prepare_html_converter('<html><head><link rel="alternate" hreflang="en" href="https://wovn.io/en/"></head></html>')
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
289
- end
290
-
291
- test 'inject_lang_html_tag - with no lang in HTML tag - should inject' do
292
- settings = default_store_settings
293
- store = Wovnrb::Store.instance
294
- store.update_settings(settings)
295
-
296
- headers = Wovnrb::Headers.new(
297
- Wovnrb.get_env('url' => 'http://my-site.com/'),
298
- Wovnrb.get_settings(settings),
299
- UrlLanguageSwitcher.new(store)
300
- )
301
- url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
302
- converter = HtmlConverter.new(get_dom('<html><body>hello</body></html>'), store, headers, url_lang_switcher)
303
- translated_html = converter.build
304
- dom = Helpers::NokogumboHelper.parse_html(translated_html)
305
- assert_equal('en', dom.at_css('html')['lang'])
306
- end
307
-
308
- test 'inject_lang_html_tag - with lang in HTML tag - do not override' do
309
- settings = default_store_settings
310
- store = Wovnrb::Store.instance
311
- store.update_settings(settings)
312
-
313
- headers = Wovnrb::Headers.new(
314
- Wovnrb.get_env('url' => 'http://my-site.com/'),
315
- Wovnrb.get_settings(settings),
316
- UrlLanguageSwitcher.new(store)
317
- )
318
- url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
319
- converter = HtmlConverter.new(get_dom('<html lang="th"><body>hello</body></html>'), store, headers, url_lang_switcher)
320
- translated_html = converter.build
321
- dom = Helpers::NokogumboHelper.parse_html(translated_html)
322
- assert_equal('th', dom.at_css('html')['lang'])
323
- end
324
-
325
- test 'translate_canonical_tag' do
326
- settings = default_store_settings
327
- store = Wovnrb::Store.instance
328
- store.update_settings(settings)
329
-
330
- headers = Wovnrb::Headers.new(
331
- Wovnrb.get_env('url' => 'http://my-site.com/?wovn=fr'),
332
- store.settings,
333
- UrlLanguageSwitcher.new(store)
334
- )
335
- url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
336
- 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)
337
- translated_html = converter.build
338
- dom = Helpers::NokogumboHelper.parse_html(translated_html)
339
- canonical_tag = dom.at_css('link[rel="canonical"]')
340
- assert_not_nil(canonical_tag)
341
- assert_equal('http://my-site.com?wovn=fr', canonical_tag['href'])
342
- end
343
-
344
- test 'translate_canonical_tag - path pattern' do
345
- settings = default_store_settings
346
- settings['url_pattern'] = 'path'
347
- store = Wovnrb::Store.instance
348
- store.update_settings(settings)
349
-
350
- headers = Wovnrb::Headers.new(
351
- Wovnrb.get_env('url' => 'http://my-site.com/fr/'),
352
- store.settings,
353
- UrlLanguageSwitcher.new(store)
354
- )
355
- url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
356
- 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)
357
- translated_html = converter.build
358
- dom = Helpers::NokogumboHelper.parse_html(translated_html)
359
- canonical_tag = dom.at_css('link[rel="canonical"]')
360
- assert_not_nil(canonical_tag)
361
- assert_equal('http://my-site.com/fr/', canonical_tag['href'])
362
- end
363
-
364
- test 'translate_canonical_tag - canonical tag is already translated' do
365
- # NOTE: this behavior is not correct, but it is the same as html-swapper
366
- settings = default_store_settings
367
- settings['url_pattern'] = 'path'
368
- store = Wovnrb::Store.instance
369
- store.update_settings(settings)
370
-
371
- headers = Wovnrb::Headers.new(
372
- Wovnrb.get_env('url' => 'http://my-site.com/fr/'),
373
- store.settings,
374
- UrlLanguageSwitcher.new(store)
375
- )
376
- url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
377
- 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)
378
- translated_html = converter.build
379
- dom = Helpers::NokogumboHelper.parse_html(translated_html)
380
- canonical_tag = dom.at_css('link[rel="canonical"]')
381
- assert_not_nil(canonical_tag)
382
- assert_equal('http://my-site.com/fr/fr/', canonical_tag['href'])
383
- end
384
-
385
- private
386
-
387
- def prepare_html_converter(input_html, store_options = {})
388
- store, headers = store_headers_factory(store_options)
389
- url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
390
- HtmlConverter.new(get_dom(input_html), store, headers, url_lang_switcher)
391
- end
392
-
393
- def store_headers_factory(setting_opts = {}, url = 'http://my-site.com')
394
- settings = default_store_settings.merge(setting_opts)
395
- store = Wovnrb::Store.instance
396
- store.update_settings(settings)
397
-
398
- headers = Wovnrb::Headers.new(
399
- Wovnrb.get_env('url' => url),
400
- store.settings,
401
- UrlLanguageSwitcher.new(store)
402
- )
403
-
404
- [store, headers]
405
- end
406
-
407
- def default_store_settings
408
- {
409
- 'project_token' => '123456',
410
- 'custom_lang_aliases' => {},
411
- 'default_lang' => 'en',
412
- 'url_pattern' => 'query',
413
- 'url_pattern_reg' => '((\?.*&)|\?)wovn=(?<lang>[^&]+)(&|)',
414
- 'supported_langs' => %w[en fr ja vi]
415
- }
416
- end
417
-
418
- def get_dom(html)
419
- Helpers::NokogumboHelper.parse_html(html)
420
- end
421
- end
422
- end
1
+ require 'test_helper'
2
+
3
+ module Wovnrb
4
+ class HtmlConverterTest < WovnMiniTest
5
+ test 'build API compatible html' do
6
+ converter = prepare_html_converter('<html><body><a class="test">hello</a></body></html>', supported_langs: %w[en vi])
7
+ converted_html, = converter.build_api_compatible_html
8
+
9
+ 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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><a class=\"test\">hello</a></body></html>"
10
+ assert_equal(expected_html, converted_html)
11
+ end
12
+
13
+ test 'build API compatible html - with custom lang param name' do
14
+ settings = {
15
+ supported_langs: %w[en vi],
16
+ url_lang_pattern: 'query',
17
+ lang_param_name: 'lang'
18
+ }
19
+ converter = prepare_html_converter('<html><body><a class="test">hello</a></body></html>', settings)
20
+ converted_html, = converter.build_api_compatible_html
21
+
22
+ 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=lang&amp;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/?lang=vi\"></head><body><a class=\"test\">hello</a></body></html>"
23
+ assert_equal(expected_html, converted_html)
24
+ end
25
+
26
+ test 'build API compatible html - excessively large HTML' do
27
+ long_string = 'a' * 60_000
28
+ converter = prepare_html_converter("<html><body><p>#{long_string}</p></body></html>", supported_langs: %w[en vi])
29
+ converted_html, = converter.build_api_compatible_html
30
+
31
+ 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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
+ assert_equal(expected_html, converted_html)
33
+ end
34
+
35
+ test 'build API compatible html - ignored content should not be sent' do
36
+ html = [
37
+ '<html><body>',
38
+ '<p>Hello <span wovn-ignore>WOVN</span><p>',
39
+ '<p>Hello <span data-wovn-ignore>WOVN</span><p>',
40
+ '<div><span class="ignore-me">should be ignored</span></div>',
41
+ '<span>Have a nice day!</span>',
42
+ '</body></html>'
43
+ ].join
44
+
45
+ converter = prepare_html_converter(html, ignore_class: ['ignore-me'])
46
+ converted_html, = converter.build_api_compatible_html
47
+
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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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
+ assert_equal(expected_convert_html, converted_html)
50
+ end
51
+
52
+ test 'build API compatible html - do not send html form' do
53
+ html = [
54
+ '<html><body>',
55
+ '<form action="/test" method="POST">',
56
+ '<input id="name" type="text">',
57
+ '<button type="submit">Submit</button>',
58
+ '</form>',
59
+ '</body></html>'
60
+ ].join
61
+
62
+ converter = prepare_html_converter(html, ignore_class: [])
63
+ converted_html, = converter.build_api_compatible_html
64
+
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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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
+ assert_equal(expected_convert_html, converted_html)
67
+ end
68
+
69
+ test 'build API compatible html - do not send hidden form input' do
70
+ html = [
71
+ '<html><body>',
72
+ '<input id="user-id" type="hidden" value="secret-id">',
73
+ '<input id="password" type="hidden" value="secret-password">',
74
+ '<input id="something" type="hidden" value="">',
75
+ '<input id="name" type="text" value="wovn.io">',
76
+ '</body></html>'
77
+ ].join
78
+
79
+ converter = prepare_html_converter(html, ignore_class: [])
80
+ converted_html, = converter.build_api_compatible_html
81
+
82
+ expected_convert_html = [
83
+ '<html lang="en"><head>',
84
+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><script src=\"https://j.wovn.io/1\" async=\"true\" data-wovnio=\"key=123456&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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>",
85
+ '<input id="user-id" type="hidden" value="__wovn-backend-ignored-key-0">',
86
+ '<input id="password" type="hidden" value="__wovn-backend-ignored-key-1">',
87
+ '<input id="something" type="hidden" value="__wovn-backend-ignored-key-2">',
88
+ '<input id="name" type="text" value="wovn.io">',
89
+ '</body></html>'
90
+ ].join
91
+ assert_equal(expected_convert_html, converted_html)
92
+ end
93
+
94
+ test 'Transform HTML' do
95
+ converter = prepare_html_converter('<html><body><a>hello</a></body></html>', supported_langs: %w[en vi])
96
+ translated_html = converter.build
97
+
98
+ 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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><a>hello</a></body></html>"
99
+ assert_equal(expected_html, translated_html)
100
+ end
101
+
102
+ test 'Transform HTML - with empty supported langs' do
103
+ converter = prepare_html_converter('<html><body><a>hello</a></body></html>', supported_langs: [])
104
+ translated_html = converter.build
105
+
106
+ 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script></head><body><a>hello</a></body></html>"
107
+ assert_equal(expected_html, translated_html)
108
+ end
109
+
110
+ test 'Transform HTML - with head tag' do
111
+ converter = prepare_html_converter('<html><head><title>TITLE</title></head><body><a>hello</a></body></html>', supported_langs: %w[en vi])
112
+ translated_html = converter.build
113
+
114
+ 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script><title>TITLE</title><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"vi\" href=\"http://my-site.com/?wovn=vi\"></head><body><a>hello</a></body></html>"
115
+ assert_equal(expected_html, translated_html)
116
+ end
117
+
118
+ test 'Transform HTML - without body' do
119
+ converter = prepare_html_converter('<html>hello<a>world</a></html>', supported_langs: [])
120
+ translated_html = converter.build
121
+
122
+ 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script></head><body>hello<a>world</a></body></html>"
123
+ assert_equal(expected_html, translated_html)
124
+ end
125
+
126
+ test 'Transform HTML - default lang - with query pattern and supported langs defined' do
127
+ dom = get_dom('<html>hello<a>world</a></html>')
128
+ settings = {
129
+ 'default_lang' => 'en',
130
+ 'supported_langs' => %w[en ja vi],
131
+ 'url_pattern' => 'query'
132
+ }
133
+ store, headers = store_headers_factory(settings)
134
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
135
+ converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
136
+ translated_html = converter.build
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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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>"
139
+ assert_equal(expected_html, translated_html)
140
+ end
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&amp;backend=true&amp;currentLang=vi&amp;defaultLang=en&amp;urlPattern=path&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=path&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={&quot;en&quot;:&quot;english&quot;}&amp;langParamName=wovn&amp;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&amp;backend=true&amp;currentLang=vi&amp;defaultLang=en&amp;urlPattern=path&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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
229
+ dom = get_dom('<html>hello<a>world</a></html>')
230
+ settings = {
231
+ 'default_lang' => 'en',
232
+ 'supported_langs' => %w[en ja vi],
233
+ 'url_pattern' => 'path'
234
+ }
235
+ store, headers = store_headers_factory(settings)
236
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
237
+ converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
238
+ translated_html = converter.build
239
+
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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=path&amp;langCodeAliases={}&amp;langParamName=wovn&amp;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>"
241
+ assert_equal(expected_html, translated_html)
242
+ end
243
+
244
+ test 'Transform HTML - custom domain langs' do
245
+ dom = get_dom('<html><body><a>hello</a></body></html>')
246
+ settings = {
247
+ 'default_lang' => 'en',
248
+ 'supported_langs' => %w[en fr],
249
+ 'custom_domain_langs' => { 'en' => { 'url' => 'my-site.com' }, 'fr' => { 'url' => 'french.com/fr' } },
250
+ 'url_pattern' => 'custom_domain'
251
+ }
252
+ store, headers = store_headers_factory(settings)
253
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
254
+ converter = HtmlConverter.new(dom, store, headers, url_lang_switcher)
255
+ translated_html = converter.build
256
+
257
+ 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=custom_domain&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}&amp;customDomainLangs={&quot;my-site.com&quot;:&quot;en&quot;,&quot;french.com/fr&quot;:&quot;fr&quot;}\" data-wovnio-type=\"fallback_snippet\"></script><link rel=\"alternate\" hreflang=\"en\" href=\"http://my-site.com/\"><link rel=\"alternate\" hreflang=\"fr\" href=\"http://french.com/fr/\"></head><body><a>hello</a></body></html>"
258
+ assert_equal(expected_html, translated_html)
259
+ end
260
+
261
+ test 'replace_snippet' do
262
+ converter = prepare_html_converter('<html><head>
263
+ <script src="/a"></script>
264
+ <script src="//j.wovn.io/1" async="true">
265
+ <script src="//j.wovn.io/1" data-wovnio="key=2wpv0n" async></script>
266
+ <script src="https//cdn.wovn.io/" data-wovnio="key=2wpv0n async></script>
267
+ <script src="https://wovn.global.ssl.fastly.net/widget/abcdef></script>
268
+ </head></html>')
269
+ translated_html = converter.build
270
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
271
+ scripts = dom.css('script')
272
+ assert_equal(2, scripts.length)
273
+ expected_wovn_script = "<script src=\"https://j.wovn.io/1\" async=\"true\" data-wovnio=\"key=123456&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script>"
274
+ assert_equal(expected_wovn_script, scripts.first.to_html)
275
+ end
276
+
277
+ test 'replace_hreflangs' do
278
+ converter = prepare_html_converter('<html><head><link rel="alternate" hreflang="en" href="https://wovn.io/en/"></head></html>')
279
+ translated_html = converter.build
280
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
281
+ href_langs = dom.css('link[rel="alternate"]')
282
+ assert_equal(4, href_langs.length)
283
+ expected_href_langs = {
284
+ 'en' =>
285
+ {
286
+ 'href' => 'http://my-site.com/'
287
+ },
288
+ 'fr' =>
289
+ {
290
+ 'href' => 'http://my-site.com/?wovn=fr'
291
+ },
292
+ 'ja' =>
293
+ {
294
+ 'href' => 'http://my-site.com/?wovn=ja'
295
+ },
296
+ 'vi' =>
297
+ {
298
+ 'href' => 'http://my-site.com/?wovn=vi'
299
+ }
300
+ }
301
+ href_langs.each do |node|
302
+ assertions = expected_href_langs[node['hreflang']]
303
+ assert_not_nil(assertions)
304
+ assert_equal(assertions['href'], node['href'])
305
+ end
306
+ end
307
+
308
+ test 'inject_lang_html_tag - with no lang in HTML tag - should inject' do
309
+ settings = default_store_settings
310
+ store = Wovnrb::Store.instance
311
+ store.update_settings(settings)
312
+
313
+ headers = Wovnrb::Headers.new(
314
+ Wovnrb.get_env('url' => 'http://my-site.com/'),
315
+ Wovnrb.get_settings(settings),
316
+ UrlLanguageSwitcher.new(store)
317
+ )
318
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
319
+ converter = HtmlConverter.new(get_dom('<html><body>hello</body></html>'), store, headers, url_lang_switcher)
320
+ translated_html = converter.build
321
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
322
+ assert_equal('en', dom.at_css('html')['lang'])
323
+ end
324
+
325
+ test 'inject_lang_html_tag - with lang in HTML tag - do not override' do
326
+ settings = default_store_settings
327
+ store = Wovnrb::Store.instance
328
+ store.update_settings(settings)
329
+
330
+ headers = Wovnrb::Headers.new(
331
+ Wovnrb.get_env('url' => 'http://my-site.com/'),
332
+ Wovnrb.get_settings(settings),
333
+ UrlLanguageSwitcher.new(store)
334
+ )
335
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
336
+ converter = HtmlConverter.new(get_dom('<html lang="th"><body>hello</body></html>'), store, headers, url_lang_switcher)
337
+ translated_html = converter.build
338
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
339
+ assert_equal('th', dom.at_css('html')['lang'])
340
+ end
341
+
342
+ test 'translate_canonical_tag' do
343
+ settings = default_store_settings
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/?wovn=fr'),
349
+ store.settings,
350
+ UrlLanguageSwitcher.new(store)
351
+ )
352
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
353
+ 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)
354
+ translated_html = converter.build
355
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
356
+ canonical_tag = dom.at_css('link[rel="canonical"]')
357
+ assert_not_nil(canonical_tag)
358
+ assert_equal('http://my-site.com?wovn=fr', canonical_tag['href'])
359
+ end
360
+
361
+ test 'translate_canonical_tag - path pattern' do
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
+ UrlLanguageSwitcher.new(store)
371
+ )
372
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
373
+ 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)
374
+ translated_html = converter.build
375
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
376
+ canonical_tag = dom.at_css('link[rel="canonical"]')
377
+ assert_not_nil(canonical_tag)
378
+ assert_equal('http://my-site.com/fr/', canonical_tag['href'])
379
+ end
380
+
381
+ test 'translate_canonical_tag - canonical tag is already translated' do
382
+ # NOTE: this behavior is not correct, but it is the same as html-swapper
383
+ settings = default_store_settings
384
+ settings['url_pattern'] = 'path'
385
+ store = Wovnrb::Store.instance
386
+ store.update_settings(settings)
387
+
388
+ headers = Wovnrb::Headers.new(
389
+ Wovnrb.get_env('url' => 'http://my-site.com/fr/'),
390
+ store.settings,
391
+ UrlLanguageSwitcher.new(store)
392
+ )
393
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
394
+ 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)
395
+ translated_html = converter.build
396
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
397
+ canonical_tag = dom.at_css('link[rel="canonical"]')
398
+ assert_not_nil(canonical_tag)
399
+ assert_equal('http://my-site.com/fr/fr/', canonical_tag['href'])
400
+ end
401
+
402
+ test 'build_api_compatible_html - backend-wovn-ignore comment - should be removed' do
403
+ store = Wovnrb::Store.instance
404
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
405
+ headers = Wovnrb::Headers.new(
406
+ Wovnrb.get_env('url' => 'http://my-site.com/'),
407
+ store.settings,
408
+ url_lang_switcher
409
+ )
410
+
411
+ html = '<html><body>hello<!-- backend-wovn-ignore -->ignored<!--/backend-wovn-ignore--> world</body></html>'
412
+ dom = get_dom(html)
413
+ sut = HtmlConverter.new(dom, store, headers, url_lang_switcher)
414
+
415
+ translated_html, marker = sut.build_api_compatible_html
416
+
417
+ assert_equal(1, marker.keys.count)
418
+ assert(translated_html.include?("hello<!-- backend-wovn-ignore -->#{marker.keys[0]}<!--/backend-wovn-ignore--> world</body></html>"))
419
+ end
420
+
421
+ test 'build_api_compatible_html - multiple backend-wovn-ignore comments - should be removed' do
422
+ store = Wovnrb::Store.instance
423
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
424
+ headers = Wovnrb::Headers.new(
425
+ Wovnrb.get_env('url' => 'http://my-site.com/'),
426
+ store.settings,
427
+ url_lang_switcher
428
+ )
429
+
430
+ html = <<~HTML
431
+ <html><body>hello<!-- backend-wovn-ignore -->ignored <!--/backend-wovn-ignore--> world
432
+ line break
433
+ <!-- backend-wovn-ignore -->
434
+ ignored2
435
+ <!--/backend-wovn-ignore-->
436
+ bye
437
+ </body></html>
438
+ HTML
439
+ dom = get_dom(html)
440
+ sut = HtmlConverter.new(dom, store, headers, url_lang_switcher)
441
+
442
+ translated_html, marker = sut.build_api_compatible_html
443
+
444
+ expected_html = <<~HTML
445
+ hello<!-- backend-wovn-ignore -->#{marker.keys[0]}<!--/backend-wovn-ignore--> world
446
+ line break
447
+ <!-- backend-wovn-ignore -->#{marker.keys[1]}<!--/backend-wovn-ignore-->
448
+ bye
449
+ HTML
450
+
451
+ assert_equal(2, marker.keys.count)
452
+ assert(translated_html.include?(expected_html))
453
+ end
454
+
455
+ private
456
+
457
+ def prepare_html_converter(input_html, store_options = {})
458
+ store, headers = store_headers_factory(store_options)
459
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
460
+ HtmlConverter.new(get_dom(input_html), store, headers, url_lang_switcher)
461
+ end
462
+
463
+ def store_headers_factory(setting_opts = {}, url = 'http://my-site.com')
464
+ settings = default_store_settings.merge(setting_opts)
465
+ store = Wovnrb::Store.instance
466
+ store.update_settings(settings)
467
+
468
+ headers = Wovnrb::Headers.new(
469
+ Wovnrb.get_env('url' => url),
470
+ store.settings,
471
+ UrlLanguageSwitcher.new(store)
472
+ )
473
+
474
+ [store, headers]
475
+ end
476
+
477
+ test 'build API compatible html - with insert_hreflangs: false' do
478
+ settings = { insert_hreflangs: false }
479
+ converter = prepare_html_converter('<html><body><a class="test">hello</a></body></html>', settings)
480
+ converted_html, = converter.build_api_compatible_html
481
+
482
+ 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&amp;backend=true&amp;currentLang=en&amp;defaultLang=en&amp;urlPattern=query&amp;langCodeAliases={}&amp;langParamName=wovn&amp;version=WOVN.rb_#{VERSION}\" data-wovnio-type=\"fallback_snippet\"></script></head><body><a class=\"test\">hello</a></body></html>"
483
+ assert_equal(expected_html, converted_html)
484
+ end
485
+
486
+ def default_store_settings
487
+ {
488
+ 'project_token' => '123456',
489
+ 'custom_lang_aliases' => {},
490
+ 'default_lang' => 'en',
491
+ 'url_pattern' => 'query',
492
+ 'url_pattern_reg' => '((\?.*&)|\?)wovn=(?<lang>[^&]+)(&|)',
493
+ 'supported_langs' => %w[en fr ja vi]
494
+ }
495
+ end
496
+
497
+ def get_dom(html)
498
+ Helpers::NokogumboHelper.parse_html(html)
499
+ end
500
+ end
501
+ end