wovnrb 3.11.0 → 3.13.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.
@@ -1,532 +1,570 @@
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
- test 'build API compatible html - with insert_hreflangs: false - hreflangs are not added' do
456
- settings = default_store_settings
457
- settings['insert_hreflangs'] = false
458
- converter = prepare_html_converter('<html><body><a>hello</a></body></html>', settings)
459
- converted_html, = converter.build_api_compatible_html
460
-
461
- 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>"
462
- assert_equal(expected_html, converted_html)
463
- end
464
-
465
- test 'build API compatible html - with insert_hreflangs: false - original hreflangs are not removed' do
466
- settings = default_store_settings
467
- settings['insert_hreflangs'] = false
468
- converter = prepare_html_converter('<html><head><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>', settings)
469
- converted_html, = converter.build_api_compatible_html
470
-
471
- 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>"
472
- assert_equal(expected_html, converted_html)
473
- end
474
-
475
- test 'Transform HTML - with insert_hreflangs: false - hreflangs are not added' do
476
- settings = default_store_settings
477
- settings['insert_hreflangs'] = false
478
- converter = prepare_html_converter('<html><body><a>hello</a></body></html>', settings)
479
- translated_html = converter.build
480
-
481
- 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>"
482
- assert_equal(expected_html, translated_html)
483
- end
484
-
485
- test 'Transform HTML - with insert_hreflangs: false - original hreflangs are not removed' do
486
- settings = default_store_settings
487
- settings['insert_hreflangs'] = false
488
- converter = prepare_html_converter('<html><head><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>', settings)
489
- translated_html = converter.build
490
-
491
- 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>"
492
- assert_equal(expected_html, translated_html)
493
- end
494
-
495
- private
496
-
497
- def prepare_html_converter(input_html, store_options = {})
498
- store, headers = store_headers_factory(store_options)
499
- url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
500
- HtmlConverter.new(get_dom(input_html), store, headers, url_lang_switcher)
501
- end
502
-
503
- def store_headers_factory(setting_opts = {}, url = 'http://my-site.com')
504
- settings = default_store_settings.merge(setting_opts)
505
- store = Wovnrb::Store.instance
506
- store.update_settings(settings)
507
-
508
- headers = Wovnrb::Headers.new(
509
- Wovnrb.get_env('url' => url),
510
- store.settings,
511
- UrlLanguageSwitcher.new(store)
512
- )
513
-
514
- [store, headers]
515
- end
516
-
517
- def default_store_settings
518
- {
519
- 'project_token' => '123456',
520
- 'custom_lang_aliases' => {},
521
- 'default_lang' => 'en',
522
- 'url_pattern' => 'query',
523
- 'url_pattern_reg' => '((\?.*&)|\?)wovn=(?<lang>[^&]+)(&|)',
524
- 'supported_langs' => %w[en fr ja vi]
525
- }
526
- end
527
-
528
- def get_dom(html)
529
- Helpers::NokogumboHelper.parse_html(html)
530
- end
531
- end
532
- 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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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/\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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/\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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/\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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/\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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/\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></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(5, 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
+ 'x-default' =>
301
+ {
302
+ 'href' => 'http://my-site.com/'
303
+ }
304
+ }
305
+ href_langs.each do |node|
306
+ assertions = expected_href_langs[node['hreflang']]
307
+ assert_not_nil(assertions)
308
+ assert_equal(assertions['href'], node['href'])
309
+ if node['hreflang'] == 'x-default'
310
+ assert_equal('true', node['data-wovn'])
311
+ else
312
+ assert_nil(node['data-wovn'])
313
+ end
314
+ end
315
+ end
316
+
317
+ test 'inject_lang_html_tag - with no lang in HTML tag - should inject' do
318
+ settings = default_store_settings
319
+ store = Wovnrb::Store.instance
320
+ store.update_settings(settings)
321
+
322
+ headers = Wovnrb::Headers.new(
323
+ Wovnrb.get_env('url' => 'http://my-site.com/'),
324
+ Wovnrb.get_settings(settings),
325
+ UrlLanguageSwitcher.new(store)
326
+ )
327
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
328
+ converter = HtmlConverter.new(get_dom('<html><body>hello</body></html>'), store, headers, url_lang_switcher)
329
+ translated_html = converter.build
330
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
331
+ assert_equal('en', dom.at_css('html')['lang'])
332
+ end
333
+
334
+ test 'inject_lang_html_tag - with lang in HTML tag - do not override' do
335
+ settings = default_store_settings
336
+ store = Wovnrb::Store.instance
337
+ store.update_settings(settings)
338
+
339
+ headers = Wovnrb::Headers.new(
340
+ Wovnrb.get_env('url' => 'http://my-site.com/'),
341
+ Wovnrb.get_settings(settings),
342
+ UrlLanguageSwitcher.new(store)
343
+ )
344
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
345
+ converter = HtmlConverter.new(get_dom('<html lang="th"><body>hello</body></html>'), store, headers, url_lang_switcher)
346
+ translated_html = converter.build
347
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
348
+ assert_equal('th', dom.at_css('html')['lang'])
349
+ end
350
+
351
+ test 'translate_canonical_tag' do
352
+ settings = default_store_settings
353
+ store = Wovnrb::Store.instance
354
+ store.update_settings(settings)
355
+
356
+ headers = Wovnrb::Headers.new(
357
+ Wovnrb.get_env('url' => 'http://my-site.com/?wovn=fr'),
358
+ store.settings,
359
+ UrlLanguageSwitcher.new(store)
360
+ )
361
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
362
+ 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)
363
+ translated_html = converter.build
364
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
365
+ canonical_tag = dom.at_css('link[rel="canonical"]')
366
+ assert_not_nil(canonical_tag)
367
+ assert_equal('http://my-site.com?wovn=fr', canonical_tag['href'])
368
+ end
369
+
370
+ test 'translate_canonical_tag - path pattern' do
371
+ settings = default_store_settings
372
+ settings['url_pattern'] = 'path'
373
+ store = Wovnrb::Store.instance
374
+ store.update_settings(settings)
375
+
376
+ headers = Wovnrb::Headers.new(
377
+ Wovnrb.get_env('url' => 'http://my-site.com/fr/'),
378
+ store.settings,
379
+ UrlLanguageSwitcher.new(store)
380
+ )
381
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
382
+ 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)
383
+ translated_html = converter.build
384
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
385
+ canonical_tag = dom.at_css('link[rel="canonical"]')
386
+ assert_not_nil(canonical_tag)
387
+ assert_equal('http://my-site.com/fr/', canonical_tag['href'])
388
+ end
389
+
390
+ test 'translate_canonical_tag - canonical tag is already translated' do
391
+ # NOTE: this behavior is not correct, but it is the same as html-swapper
392
+ settings = default_store_settings
393
+ settings['url_pattern'] = 'path'
394
+ store = Wovnrb::Store.instance
395
+ store.update_settings(settings)
396
+
397
+ headers = Wovnrb::Headers.new(
398
+ Wovnrb.get_env('url' => 'http://my-site.com/fr/'),
399
+ store.settings,
400
+ UrlLanguageSwitcher.new(store)
401
+ )
402
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
403
+ 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)
404
+ translated_html = converter.build
405
+ dom = Helpers::NokogumboHelper.parse_html(translated_html)
406
+ canonical_tag = dom.at_css('link[rel="canonical"]')
407
+ assert_not_nil(canonical_tag)
408
+ assert_equal('http://my-site.com/fr/fr/', canonical_tag['href'])
409
+ end
410
+
411
+ test 'build_api_compatible_html - backend-wovn-ignore comment - should be removed' do
412
+ store = Wovnrb::Store.instance
413
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
414
+ headers = Wovnrb::Headers.new(
415
+ Wovnrb.get_env('url' => 'http://my-site.com/'),
416
+ store.settings,
417
+ url_lang_switcher
418
+ )
419
+
420
+ html = '<html><body>hello<!-- backend-wovn-ignore -->ignored<!--/backend-wovn-ignore--> world</body></html>'
421
+ dom = get_dom(html)
422
+ sut = HtmlConverter.new(dom, store, headers, url_lang_switcher)
423
+
424
+ translated_html, marker = sut.build_api_compatible_html
425
+
426
+ assert_equal(1, marker.keys.count)
427
+ assert(translated_html.include?("hello<!-- backend-wovn-ignore -->#{marker.keys[0]}<!--/backend-wovn-ignore--> world</body></html>"))
428
+ end
429
+
430
+ test 'build_api_compatible_html - multiple backend-wovn-ignore comments - should be removed' do
431
+ store = Wovnrb::Store.instance
432
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
433
+ headers = Wovnrb::Headers.new(
434
+ Wovnrb.get_env('url' => 'http://my-site.com/'),
435
+ store.settings,
436
+ url_lang_switcher
437
+ )
438
+
439
+ html = <<~HTML
440
+ <html><body>hello<!-- backend-wovn-ignore -->ignored <!--/backend-wovn-ignore--> world
441
+ line break
442
+ <!-- backend-wovn-ignore -->
443
+ ignored2
444
+ <!--/backend-wovn-ignore-->
445
+ bye
446
+ </body></html>
447
+ HTML
448
+ dom = get_dom(html)
449
+ sut = HtmlConverter.new(dom, store, headers, url_lang_switcher)
450
+
451
+ translated_html, marker = sut.build_api_compatible_html
452
+
453
+ expected_html = <<~HTML
454
+ hello<!-- backend-wovn-ignore -->#{marker.keys[0]}<!--/backend-wovn-ignore--> world
455
+ line break
456
+ <!-- backend-wovn-ignore -->#{marker.keys[1]}<!--/backend-wovn-ignore-->
457
+ bye
458
+ HTML
459
+
460
+ assert_equal(2, marker.keys.count)
461
+ assert(translated_html.include?(expected_html))
462
+ end
463
+
464
+ test 'build API compatible html - with insert_hreflangs: false - hreflangs are not added' do
465
+ settings = default_store_settings
466
+ settings['insert_hreflangs'] = false
467
+ converter = prepare_html_converter('<html><body><a>hello</a></body></html>', settings)
468
+ converted_html, = converter.build_api_compatible_html
469
+
470
+ 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>"
471
+ assert_equal(expected_html, converted_html)
472
+ end
473
+
474
+ test 'build API compatible html - with insert_hreflangs: false - original hreflangs are not removed' do
475
+ settings = default_store_settings
476
+ settings['insert_hreflangs'] = false
477
+ converter = prepare_html_converter('<html><head><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>', settings)
478
+ converted_html, = converter.build_api_compatible_html
479
+
480
+ 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>"
481
+ assert_equal(expected_html, converted_html)
482
+ end
483
+
484
+ test 'Transform HTML - with insert_hreflangs: false - hreflangs are not added' do
485
+ settings = default_store_settings
486
+ settings['insert_hreflangs'] = false
487
+ converter = prepare_html_converter('<html><body><a>hello</a></body></html>', settings)
488
+ translated_html = converter.build
489
+
490
+ 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>"
491
+ assert_equal(expected_html, translated_html)
492
+ end
493
+
494
+ test 'Transform HTML - with insert_hreflangs: false - original hreflangs are not removed' do
495
+ settings = default_store_settings
496
+ settings['insert_hreflangs'] = false
497
+ converter = prepare_html_converter('<html><head><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>', settings)
498
+ translated_html = converter.build
499
+
500
+ 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>"
501
+ assert_equal(expected_html, translated_html)
502
+ end
503
+
504
+ test 'Transform HTML - no x-default hreflang - no config - generates using default lang' do
505
+ settings = default_store_settings
506
+ converter = prepare_html_converter('<html><head></head></html>', settings)
507
+ translated_html = converter.build
508
+
509
+ 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=\"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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/\"></head><body></body></html>"
510
+ assert_equal(expected_html, translated_html)
511
+ end
512
+
513
+ test 'Transform HTML - no x-default hreflang - has config - generates using specified lang' do
514
+ settings = default_store_settings
515
+ settings['hreflang_x_default_lang'] = 'fr'
516
+ converter = prepare_html_converter('<html><head></head></html>', settings)
517
+ translated_html = converter.build
518
+
519
+ 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=\"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\"><link rel=\"alternate\" hreflang=\"x-default\" data-wovn=\"true\" href=\"http://my-site.com/?wovn=fr\"></head><body></body></html>"
520
+ assert_equal(expected_html, translated_html)
521
+ end
522
+
523
+ test 'Transform HTML - has x-default hreflang - does not modify' do
524
+ settings = default_store_settings
525
+ settings['hreflang_x_default_lang'] = 'fr'
526
+ converter = prepare_html_converter('<html><head><link rel="alternate" hreflang="X-Default" href="https://my-site.com/?from=customer"></head></html>', settings)
527
+ translated_html = converter.build
528
+
529
+ 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=\"X-Default\" href=\"https://my-site.com/?from=customer\"><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></body></html>"
530
+ assert_equal(expected_html, translated_html)
531
+ end
532
+
533
+ private
534
+
535
+ def prepare_html_converter(input_html, store_options = {})
536
+ store, headers = store_headers_factory(store_options)
537
+ url_lang_switcher = Wovnrb::UrlLanguageSwitcher.new(store)
538
+ HtmlConverter.new(get_dom(input_html), store, headers, url_lang_switcher)
539
+ end
540
+
541
+ def store_headers_factory(setting_opts = {}, url = 'http://my-site.com')
542
+ settings = default_store_settings.merge(setting_opts)
543
+ store = Wovnrb::Store.instance
544
+ store.update_settings(settings)
545
+
546
+ headers = Wovnrb::Headers.new(
547
+ Wovnrb.get_env('url' => url),
548
+ store.settings,
549
+ UrlLanguageSwitcher.new(store)
550
+ )
551
+
552
+ [store, headers]
553
+ end
554
+
555
+ def default_store_settings
556
+ {
557
+ 'project_token' => '123456',
558
+ 'custom_lang_aliases' => {},
559
+ 'default_lang' => 'en',
560
+ 'url_pattern' => 'query',
561
+ 'url_pattern_reg' => '((\?.*&)|\?)wovn=(?<lang>[^&]+)(&|)',
562
+ 'supported_langs' => %w[en fr ja vi]
563
+ }
564
+ end
565
+
566
+ def get_dom(html)
567
+ Helpers::NokogumboHelper.parse_html(html)
568
+ end
569
+ end
570
+ end