@jetshop/core 5.13.3-beta.0 → 5.13.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,732 +0,0 @@
1
- import {
2
- createSelectedChannel,
3
- getSelectedAndRecommendedChannel
4
- } from './channelUtils';
5
- import { MockLink } from 'apollo-link-mock';
6
- import {
7
- InMemoryCache,
8
- IntrospectionFragmentMatcher
9
- } from 'apollo-cache-inmemory';
10
- import ApolloClient from 'apollo-client';
11
- import gql from 'graphql-tag';
12
- import { ChannelHandler } from './ChannelHandler';
13
- import {
14
- groupedChannels as channels,
15
- groupedSingleDomainChannels as singleDomainChannels
16
- } from '../test-utils/variables';
17
- import { Cookies } from 'react-cookie';
18
- import { primaryRouteForPathFetcher } from './redirectUtils';
19
- import PreserveRedirectRouteQuery from './PreserveRedirectRouteQuery.gql';
20
- import fragmentTypes from '@jetshop/core/data/fragmentTypes';
21
-
22
- const startPagePathnameRedirectQuery = gql`
23
- query StartPagePathnameRedirectQuery($id: Int!) {
24
- StartPage: startPage(id: $id) {
25
- id
26
- primaryRoute {
27
- id
28
- path
29
- __typename
30
- }
31
- __typename
32
- }
33
- }
34
- `;
35
-
36
- const startPagePathnameRedirectRequest = {
37
- request: {
38
- query: startPagePathnameRedirectQuery,
39
- variables: { id: 44 }
40
- },
41
- result: {
42
- data: {
43
- StartPage: {
44
- id: 44,
45
- primaryRoute: {
46
- id: '/',
47
- path: '/',
48
- __typename: 'Route'
49
- },
50
- __typename: 'StartPage'
51
- }
52
- }
53
- }
54
- };
55
-
56
- const productPathnameRedirectQuery = gql`
57
- query ProductPathnameRedirectQuery($id: Int!) {
58
- Product: product(id: $id) {
59
- id
60
- primaryRoute {
61
- id
62
- path
63
- __typename
64
- }
65
- __typename
66
- }
67
- }
68
- `;
69
-
70
- const redirectQueryMocks = [
71
- {
72
- request: {
73
- query: PreserveRedirectRouteQuery,
74
- variables: {
75
- path: '/'
76
- }
77
- },
78
- result: {
79
- data: {
80
- route: {
81
- id: '/',
82
- object: {
83
- id: 44,
84
- __typename: 'StartPage'
85
- },
86
- __typename: 'Route'
87
- },
88
- __typename: 'Query'
89
- }
90
- }
91
- },
92
- startPagePathnameRedirectRequest,
93
- startPagePathnameRedirectRequest,
94
- startPagePathnameRedirectRequest,
95
- startPagePathnameRedirectRequest,
96
- {
97
- request: {
98
- query: PreserveRedirectRouteQuery,
99
- variables: {
100
- path: '/accessories/orchid-peach-bag'
101
- }
102
- },
103
- result: {
104
- data: {
105
- route: {
106
- id: '/accessories/orchid-peach-bag',
107
- object: {
108
- id: 522,
109
- __typename: 'Product'
110
- },
111
- __typename: 'Route'
112
- }
113
- }
114
- }
115
- },
116
- {
117
- request: {
118
- query: productPathnameRedirectQuery,
119
- variables: { id: 522 }
120
- },
121
- result: {
122
- data: {
123
- Product: {
124
- id: 522,
125
- primaryRoute: {
126
- id: '/accessories/bags/orchid-peach-bag-uk',
127
- path: '/accessories/bags/orchid-peach-bag-uk',
128
- __typename: 'Route'
129
- },
130
- __typename: 'Product'
131
- }
132
- }
133
- }
134
- },
135
- {
136
- request: {
137
- query: productPathnameRedirectQuery,
138
- variables: { id: 522 }
139
- },
140
- result: {
141
- data: {
142
- Product: {
143
- id: 522,
144
- primaryRoute: {
145
- id: '/accessories/orchid-peach-bag',
146
- path: '/accessories/orchid-peach-bag',
147
- __typename: 'Route'
148
- },
149
- __typename: 'Product'
150
- }
151
- }
152
- }
153
- }
154
- ];
155
-
156
- function createClient(mocks) {
157
- return new ApolloClient({
158
- cache: new InMemoryCache({
159
- addTypename: true,
160
- fragmentMatcher: new IntrospectionFragmentMatcher({
161
- introspectionQueryResultData: {
162
- __schema: {
163
- types: fragmentTypes
164
- }
165
- }
166
- })
167
- }),
168
- link: new MockLink(mocks)
169
- });
170
- }
171
-
172
- const client = createClient(redirectQueryMocks);
173
- const getPrimaryRoutePath = primaryRouteForPathFetcher(client);
174
-
175
- const selectedChannelSingleDomain = createSelectedChannel(
176
- singleDomainChannels[0]
177
- );
178
-
179
- describe('Channel grouping', () => {
180
- beforeEach(() => {
181
- // Workaround changes in universal-cookie
182
- Object.defineProperty(document, 'cookie', {
183
- value: null
184
- });
185
- });
186
- });
187
-
188
- describe('Grouped channels', () => {
189
- beforeEach(() => {
190
- // Workaround changes in universal-cookie
191
- Object.defineProperty(document, 'cookie', {
192
- value: null
193
- });
194
- });
195
- describe('Single domain', () => {
196
- it('Only have channels from within the group based on url', () => {
197
- const cookies = new Cookies();
198
- const { selectedChannel, channels } = getSelectedAndRecommendedChannel({
199
- url: singleDomainChannels[0].url,
200
- singleDomainMode: true,
201
- channels: singleDomainChannels,
202
- cookies
203
- });
204
-
205
- expect(selectedChannel.groupName).toBe('Brand-1');
206
- channels.forEach((c) => expect(c.groupName).toBe('Brand-1'));
207
- });
208
- it('Only have channels from within the group based on cookie', () => {
209
- const cookies = new Cookies();
210
- cookies.set('channel', singleDomainChannels[0].name);
211
- const { selectedChannel, channels } = getSelectedAndRecommendedChannel({
212
- url: singleDomainChannels[0].url,
213
- singleDomainMode: true,
214
- channels: singleDomainChannels,
215
- cookies
216
- });
217
-
218
- expect(selectedChannel.groupName).toBe('Brand-1');
219
- channels.forEach((c) => expect(c.groupName).toBe('Brand-1'));
220
- });
221
- it('Recommend channel from within current group based on GEO-IP', () => {
222
- const cookies = new Cookies();
223
- const { recommendedChannel, selectedChannel, redirect, channels } =
224
- getSelectedAndRecommendedChannel({
225
- url: singleDomainChannels[0].url,
226
- geoipCountry: 'SE',
227
- singleDomainMode: true,
228
- disableGeoRedirect: false,
229
- channels: singleDomainChannels,
230
- cookies
231
- });
232
-
233
- expect(selectedChannel.name).toBe('INT');
234
-
235
- channels.forEach((c) => expect(c.groupName).toBe('Brand-1'));
236
-
237
- expect(redirect).toBe(true);
238
- expect(recommendedChannel.name).toBe('SE');
239
- expect(recommendedChannel.groupName).toBe('Brand-1');
240
- });
241
- });
242
- describe('Non single domain', () => {
243
- /**
244
- * Non single domain
245
- */
246
- it('Only have channels from within the group based on url', () => {
247
- const cookies = new Cookies();
248
- const { selectedChannel, channels: availableChannels } =
249
- getSelectedAndRecommendedChannel({
250
- url: channels[1].url,
251
- singleDomainMode: false,
252
- channels: channels,
253
- cookies
254
- });
255
-
256
- expect(selectedChannel.groupName).toBe('Brand-1');
257
- availableChannels.forEach((c) => expect(c.groupName).toBe('Brand-1'));
258
- });
259
- it('Only have channels from within the group based on cookie', () => {
260
- const cookies = new Cookies();
261
- cookies.set('channel', channels[0].name);
262
- const { selectedChannel, channels: availableChannels } =
263
- getSelectedAndRecommendedChannel({
264
- url: channels[0].url,
265
- singleDomainMode: false,
266
- channels: channels,
267
- cookies
268
- });
269
-
270
- expect(selectedChannel.groupName).toBe('Brand-1');
271
- availableChannels.forEach((c) => expect(c.groupName).toBe('Brand-1'));
272
- });
273
- it('Recommend channel from within current group based on GEO-IP', () => {
274
- const cookies = new Cookies();
275
- const {
276
- recommendedChannel,
277
- selectedChannel,
278
- redirect,
279
- channels: availableChannels
280
- } = getSelectedAndRecommendedChannel({
281
- url: channels[0].url,
282
- geoipCountry: 'SE',
283
- singleDomainMode: false,
284
- disableGeoRedirect: false,
285
- channels: channels,
286
- cookies
287
- });
288
-
289
- expect(selectedChannel.name).toBe('INT');
290
-
291
- availableChannels.forEach((c) => expect(c.groupName).toBe('Brand-1'));
292
-
293
- expect(redirect).toBe(true);
294
- expect(recommendedChannel.name).toBe('SE');
295
- expect(recommendedChannel.groupName).toBe('Brand-1');
296
- });
297
- it('Respects change of channel and group using url', () => {
298
- const cookies = new Cookies();
299
- const prevSelectedChannel = createSelectedChannel(channels[2]);
300
-
301
- expect(prevSelectedChannel.name).toBe('UK');
302
- expect(prevSelectedChannel.groupName).toBe('Brand-2');
303
-
304
- const {
305
- selectedChannel,
306
- redirect,
307
- channels: availableChannels
308
- } = getSelectedAndRecommendedChannel({
309
- url: channels[1].url,
310
- singleDomainMode: false,
311
- channels: channels,
312
- cookies
313
- });
314
-
315
- expect(redirect).toBe(false);
316
- expect(selectedChannel.name).toBe('SE');
317
- expect(selectedChannel.groupName).toBe('Brand-1');
318
- availableChannels.forEach((c) => expect(c.groupName).toBe('Brand-1'));
319
- });
320
- });
321
- describe('Redirects', () => {
322
- it('Does not redirect to channel outside of current group', () => {
323
- const cookies = new Cookies();
324
- const selectedChannel = createSelectedChannel(channels[2]);
325
- cookies.set('channel', selectedChannel.name);
326
-
327
- const recommendedChannel = createSelectedChannel(channels[0]);
328
-
329
- const { redirect, channels: availableChannel } =
330
- getSelectedAndRecommendedChannel({
331
- url: recommendedChannel.url,
332
- singleDomainMode: false,
333
- channels,
334
- cookies
335
- });
336
-
337
- availableChannel.forEach((channel) =>
338
- expect(channel.groupName).toBe('Brand-1')
339
- );
340
- expect(redirect).toBe(false);
341
- });
342
-
343
- it('Can redirect to channel within group', () => {
344
- const cookies = new Cookies();
345
- const selectedChannel = createSelectedChannel(channels[1]);
346
- cookies.set('channel', selectedChannel.name);
347
-
348
- const recommendedChannel = createSelectedChannel(channels[0]);
349
-
350
- const { redirect, channels: availableChannel } =
351
- getSelectedAndRecommendedChannel({
352
- url: recommendedChannel.url,
353
- singleDomainMode: false,
354
- channels,
355
- cookies
356
- });
357
-
358
- availableChannel.forEach((channel) =>
359
- expect(channel.groupName).toBe('Brand-1')
360
- );
361
- expect(redirect).toBe(true);
362
- });
363
- });
364
- });
365
-
366
- describe('Channel utils with grouped channels', () => {
367
- beforeEach(() => {
368
- // Workaround changes in universal-cookie
369
- Object.defineProperty(document, 'cookie', {
370
- value: null
371
- });
372
- });
373
-
374
- it('successfully redirect to the appropriate channel', () => {
375
- const recommendedChannel = createSelectedChannel(channels[1]);
376
- const selectedChannel = createSelectedChannel(channels[0]);
377
- const channelHandler = new ChannelHandler({
378
- selectedChannel,
379
- recommendedChannel,
380
- getPrimaryRoutePath,
381
- channels
382
- });
383
-
384
- const redirectUrl = channelHandler.getRedirectUrl({
385
- client,
386
- url: selectedChannel.url,
387
- newChannel: recommendedChannel
388
- });
389
- expect(redirectUrl).resolves.toBe(
390
- 'https://flight-m2.jetshop.se/?culture=sv-SE&channelCountry=SE&channel=SE'
391
- );
392
- });
393
-
394
- it('Will not redirect when there is a channel in the cookie', () => {
395
- const cookies = new Cookies();
396
- cookies.set('channel', channels[0].name);
397
- const { redirect } = getSelectedAndRecommendedChannel({
398
- url: channels[0].url,
399
- singleDomainMode: false,
400
- channels,
401
- cookies
402
- });
403
-
404
- expect(redirect).toBeFalsy();
405
- });
406
-
407
- it('Will not redirect when there is a channel in the query string', () => {
408
- const cookies = new Cookies();
409
- cookies.set('channel', channels[0].name);
410
- const { redirect } = getSelectedAndRecommendedChannel({
411
- url: channels[0].url + '?channelCountry="US"',
412
- singleDomainMode: false,
413
- channels,
414
- cookies
415
- });
416
- expect(redirect).toBeFalsy();
417
- });
418
-
419
- it('Will not geo redirect when there is a channel in the query string', () => {
420
- const cookies = new Cookies();
421
- cookies.set('channel', channels[0].name);
422
- const { redirect } = getSelectedAndRecommendedChannel({
423
- url: channels[0].url + '?channelCountry="US"',
424
- geoipCountry: 'SE',
425
- singleDomainMode: false,
426
- channels,
427
- cookies
428
- });
429
- expect(redirect).toBeFalsy();
430
- });
431
-
432
- it('Will not redirect when the url is already correct', () => {
433
- const cookies = new Cookies();
434
- const { recommendedChannel, redirect } = getSelectedAndRecommendedChannel({
435
- url: channels[0].url,
436
- geoipCountry: 'US',
437
- singleDomainMode: false,
438
- channels,
439
- cookies
440
- });
441
- expect(redirect).toBeFalsy();
442
- expect(recommendedChannel).toBeFalsy();
443
- });
444
-
445
- it('Will redirect to the channel that has the country set as the default country', () => {
446
- const cookies = new Cookies();
447
- channels[0].countries.push({
448
- name: 'Sweden',
449
- code: 'SE',
450
- isDefault: false
451
- });
452
- const { recommendedChannel, redirect } = getSelectedAndRecommendedChannel({
453
- url: channels[0].url,
454
- geoipCountry: 'SE',
455
- singleDomainMode: false,
456
- channels,
457
- cookies
458
- });
459
- expect(redirect).toBeTruthy();
460
- expect(recommendedChannel.name).toBe('SE');
461
- });
462
-
463
- it('Will not redirect when the channel is from an unkown country', () => {
464
- const cookies = new Cookies();
465
- const { recommendedChannel, redirect } = getSelectedAndRecommendedChannel({
466
- url: channels[0].url,
467
- geoipCountry: 'CO',
468
- singleDomainMode: false,
469
- channels,
470
- cookies
471
- });
472
- expect(redirect).toBeFalsy();
473
- expect(recommendedChannel).toBeFalsy();
474
- });
475
- describe('Single domain mode', () => {
476
- it('Will not redirect when the channel is default, and the selected channel is also default', () => {
477
- const cookies = new Cookies();
478
- const { recommendedChannel, redirect } = getSelectedAndRecommendedChannel(
479
- {
480
- url: selectedChannelSingleDomain.url,
481
- singleDomainMode: true,
482
- channels: singleDomainChannels,
483
- cookies
484
- }
485
- );
486
- expect(redirect).toBeFalsy();
487
- expect(recommendedChannel).toBeFalsy();
488
- });
489
-
490
- it('Will redirect when the url is at the wrong channel and the channel is default', () => {
491
- const cookies = new Cookies();
492
- const { recommendedChannel, redirect } = getSelectedAndRecommendedChannel(
493
- {
494
- url: channels[0].url,
495
- singleDomainMode: true,
496
- channels: singleDomainChannels,
497
- cookies
498
- }
499
- );
500
- expect(redirect).toBe(true);
501
- expect(recommendedChannel.url).toBe(selectedChannelSingleDomain.url);
502
- });
503
-
504
- it('Will not redirect when the redirect is disabled', () => {
505
- const cookies = new Cookies();
506
- const { redirect } = getSelectedAndRecommendedChannel({
507
- url: channels[0].url + '?redirectDisabled=true',
508
- singleDomainMode: true,
509
- channels: singleDomainChannels,
510
- cookies
511
- });
512
- expect(redirect).toBe(false);
513
- });
514
-
515
- it('Will not when the url is at the right channel', () => {
516
- const cookies = new Cookies();
517
- const { redirect } = getSelectedAndRecommendedChannel({
518
- url: selectedChannelSingleDomain.url,
519
- singleDomainMode: true,
520
- channels: singleDomainChannels,
521
- cookies
522
- });
523
- expect(redirect).toBe(false);
524
- });
525
-
526
- it('Will redirect when the url is at the wrong channel but in same group', () => {
527
- const cookies = new Cookies();
528
- cookies.set('channel', singleDomainChannels[1].name);
529
- const { redirect, recommendedChannel } = getSelectedAndRecommendedChannel(
530
- {
531
- url: selectedChannelSingleDomain.url,
532
- singleDomainMode: true,
533
- channels: singleDomainChannels,
534
- cookies
535
- }
536
- );
537
-
538
- expect(redirect).toBe(true);
539
- expect(recommendedChannel.url).toBe('https://flight-m2.jetshop.se/se');
540
- });
541
-
542
- it('Georedirect will respect single domain mode', () => {
543
- const cookies = new Cookies();
544
- const { redirect, recommendedChannel } = getSelectedAndRecommendedChannel(
545
- {
546
- url: selectedChannelSingleDomain.url,
547
- singleDomainMode: true,
548
- channels: singleDomainChannels,
549
- cookies,
550
- geoipCountry: 'SE'
551
- }
552
- );
553
- expect(redirect).toBe(true);
554
- expect(recommendedChannel.url).toBe('https://flight-m2.jetshop.se/se');
555
- });
556
-
557
- it('Georedirect will respect single domain mode when there is a domain path', async () => {
558
- const urlToPreserve = '/accessories/orchid-peach-bag';
559
- const cookies = new Cookies();
560
- const { redirect, recommendedChannel, selectedChannel } =
561
- getSelectedAndRecommendedChannel({
562
- url: selectedChannelSingleDomain.url + urlToPreserve,
563
- singleDomainMode: true,
564
- channels: singleDomainChannels,
565
- cookies,
566
- geoipCountry: 'SE'
567
- });
568
- expect(redirect).toBe(true);
569
- expect(recommendedChannel.url).toBe('https://flight-m2.jetshop.se/se');
570
- const channelHandler = new ChannelHandler({
571
- selectedChannel,
572
- recommendedChannel,
573
- getPrimaryRoutePath,
574
- channels
575
- });
576
-
577
- const redirectUrl = channelHandler.getRedirectUrl({
578
- client,
579
- url: selectedChannelSingleDomain.url + urlToPreserve,
580
- newChannel: channelHandler.recommendedChannel,
581
- preserveRedirect: true
582
- });
583
-
584
- await expect(redirectUrl).resolves.toBe(
585
- 'https://flight-m2.jetshop.se/se/accessories/bags/orchid-peach-bag-uk?culture=sv-SE&channelCountry=SE&channel=SE'
586
- );
587
- });
588
-
589
- it('Redirect on single domain mode when the basename shows up in the url', async () => {
590
- const urlToPreserve = '/accessories/int/orchid-peach-bag';
591
- const cookies = new Cookies();
592
- const { redirect, recommendedChannel, selectedChannel } =
593
- getSelectedAndRecommendedChannel({
594
- url: channels[0].url + urlToPreserve,
595
- singleDomainMode: true,
596
- channels: singleDomainChannels,
597
- cookies,
598
- geoipCountry: 'SE'
599
- });
600
- expect(redirect).toBe(true);
601
- const channelHandler = new ChannelHandler({
602
- selectedChannel,
603
- recommendedChannel,
604
- getPrimaryRoutePath,
605
- channels
606
- });
607
-
608
- const redirectUrl = channelHandler.getRedirectUrl({
609
- client,
610
- url: channels[0].url + urlToPreserve,
611
- newChannel: channelHandler.recommendedChannel,
612
- preserveRedirect: false
613
- });
614
- await expect(redirectUrl).resolves.toBe(
615
- `https://flight-m2.jetshop.se/se${urlToPreserve}?culture=sv-SE&channelCountry=SE&channel=SE`
616
- );
617
- });
618
-
619
- it('Redirect on single domain mode when there is a domain path but no basename', async () => {
620
- const urlToPreserve = '/accessories/orchid-peach-bag';
621
- const cookies = new Cookies();
622
- const {
623
- redirect,
624
- recommendedChannel,
625
- selectedChannel,
626
- channels: groupedChannels
627
- } = getSelectedAndRecommendedChannel({
628
- url: channels[0].url + urlToPreserve,
629
- singleDomainMode: true,
630
- channels: singleDomainChannels,
631
- cookies
632
- });
633
-
634
- expect(redirect).toBe(true);
635
- expect(recommendedChannel.url).toBe('https://flight-m2.jetshop.se/int');
636
-
637
- const channelHandler = new ChannelHandler({
638
- selectedChannel,
639
- recommendedChannel,
640
- getPrimaryRoutePath,
641
- channels: groupedChannels
642
- });
643
-
644
- const redirectUrl = channelHandler.getRedirectUrl({
645
- client,
646
- url: channels[0].url + urlToPreserve,
647
- newChannel: channelHandler.recommendedChannel,
648
- preserveRedirect: true
649
- });
650
-
651
- await expect(redirectUrl).resolves.toBe(
652
- `https://flight-m2.jetshop.se/int${urlToPreserve}?culture=en-GB&channelCountry=US&channel=INT`
653
- );
654
- });
655
-
656
- it('Will set the appropriate language based on basename', async () => {
657
- const cookies = new Cookies();
658
- const { selectedChannel } = getSelectedAndRecommendedChannel({
659
- url: channels[1].url + '/en',
660
- channels,
661
- cookies
662
- });
663
- expect(selectedChannel.language.culture).toBe('en-GB');
664
- });
665
-
666
- it('Will set the appropriate language based on basename in singledomain mode', async () => {
667
- const cookies = new Cookies();
668
- const { selectedChannel } = getSelectedAndRecommendedChannel({
669
- url: singleDomainChannels[1].url + '/en',
670
- channels: singleDomainChannels,
671
- cookies,
672
- singleDomainMode: true
673
- });
674
- expect(selectedChannel.language.culture).toBe('en-GB');
675
- });
676
-
677
- it('Will redirect to a new language basename based on cookies', async () => {
678
- const cookies = new Cookies();
679
- cookies.set('culture', 'en-GB');
680
- const { selectedChannel, recommendedChannel, redirect } =
681
- getSelectedAndRecommendedChannel({
682
- url: channels[1].url,
683
- channels,
684
- cookies
685
- });
686
- expect(redirect).toBe(true);
687
- expect(recommendedChannel.language.culture).toBe('en-GB');
688
- const channelHandler = new ChannelHandler({
689
- selectedChannel,
690
- recommendedChannel,
691
- getPrimaryRoutePath,
692
- channels
693
- });
694
- const redirectUrl = channelHandler.getRedirectUrl({
695
- client,
696
- url: selectedChannel.url,
697
- newChannel: recommendedChannel
698
- });
699
- expect(redirectUrl).resolves.toBe(
700
- 'https://flight-m2.jetshop.se/en/?culture=en-GB&channelCountry=SE&channel=SE'
701
- );
702
- });
703
-
704
- it('Will redirect to a new language basename based on cookies in single domain mode', async () => {
705
- const cookies = new Cookies();
706
- cookies.set('culture', 'en-GB');
707
- const { selectedChannel, recommendedChannel, redirect } =
708
- getSelectedAndRecommendedChannel({
709
- url: singleDomainChannels[1].url,
710
- channels: singleDomainChannels,
711
- cookies,
712
- singleDomainMode: true
713
- });
714
- expect(redirect).toBe(true);
715
- expect(recommendedChannel.language.culture).toBe('en-GB');
716
- const channelHandler = new ChannelHandler({
717
- selectedChannel,
718
- recommendedChannel,
719
- getPrimaryRoutePath,
720
- channels
721
- });
722
- const redirectUrl = channelHandler.getRedirectUrl({
723
- client,
724
- url: selectedChannel.url,
725
- newChannel: recommendedChannel
726
- });
727
- expect(redirectUrl).resolves.toBe(
728
- 'https://flight-m2.jetshop.se/se/en/?culture=en-GB&channelCountry=SE&channel=SE'
729
- );
730
- });
731
- });
732
- });