1
1
/**
2
2
* @prettier
3
3
*/
4
-
5
4
import { expect } from "chai" ;
6
5
import { Pollman } from "./pollman" ;
7
6
import sinon from "sinon" ;
8
7
9
8
describe ( "Pollman" , ( ) => {
10
9
describe ( "#requestUrl" , ( ) => {
10
+ beforeEach ( ( ) => {
11
+ // Mock window.location.origin for the host validation
12
+ global . window = {
13
+ location : {
14
+ origin : "https://example.com"
15
+ }
16
+ } ;
17
+ global . URL = class URL {
18
+ constructor ( url , base ) {
19
+ if ( url . startsWith ( '/' ) ) {
20
+ this . href = base + url ;
21
+ this . origin = base ;
22
+ } else {
23
+ this . href = url ;
24
+ // Extract origin from full URL
25
+ const match = url . match ( / ^ ( h t t p s ? : \/ \/ [ ^ \/ ] + ) / ) ;
26
+ this . origin = match ? match [ 1 ] : base ;
27
+ }
28
+ }
29
+ } ;
30
+ } ) ;
31
+
11
32
it ( "returns the URL from where to fetch the updated HTML node" , ( ) => {
12
33
let node_mock = {
13
34
attributes : [
@@ -23,33 +44,62 @@ describe("Pollman", () => {
23
44
return attribute . value ;
24
45
} ,
25
46
} ;
47
+ expect ( Pollman . requestUrl ( node_mock ) ) . to . equal (
48
+ "https://example.com/resources/get?page=1&color=green&state=passed"
49
+ ) ;
50
+ } ) ;
51
+
52
+ it ( "throws error for external domain" , ( ) => {
53
+ let node_mock = {
54
+ attributes : [
55
+ { name : "data-poll-href" , value : "https://malicious.com/script.js" } ,
56
+ ] ,
57
+ getAttribute : function ( name ) {
58
+ let attribute = this . attributes . find (
59
+ ( attribute ) => attribute . name === name
60
+ ) ;
61
+ return attribute . value ;
62
+ } ,
63
+ } ;
64
+ expect ( ( ) => Pollman . requestUrl ( node_mock ) ) . to . throw (
65
+ "Invalid or unauthorized data-poll-href URL"
66
+ ) ;
67
+ } ) ;
26
68
69
+ it ( "allows same origin with full URL" , ( ) => {
70
+ let node_mock = {
71
+ attributes : [
72
+ { name : "data-poll-href" , value : "https://example.com/api/poll" } ,
73
+ { name : "data-poll-param-id" , value : "123" } ,
74
+ ] ,
75
+ getAttribute : function ( name ) {
76
+ let attribute = this . attributes . find (
77
+ ( attribute ) => attribute . name === name
78
+ ) ;
79
+ return attribute . value ;
80
+ } ,
81
+ } ;
27
82
expect ( Pollman . requestUrl ( node_mock ) ) . to . equal (
28
- "/resources/get?page=1&color=green&state=passed "
83
+ "https://example.com/api/poll?id=123 "
29
84
) ;
30
85
} ) ;
31
86
} ) ;
32
87
33
88
describe ( "#elementsToRefresh" , ( ) => {
34
89
before ( function ( ) {
35
90
Pollman . init ( { startLooper : false } ) ;
36
-
37
91
document . body . innerHTML = `
38
92
<div data-poll-background="" data-poll-href="/resources/1" data-poll-state="poll"></div>
39
93
<div data-poll-href="/resources/2" data-poll-state="poll"></div>
40
94
` ;
41
95
} ) ;
42
-
43
96
afterEach ( function ( ) {
44
97
if ( Pollman . pageIsVisible && Pollman . pageIsVisible . restore )
45
98
Pollman . pageIsVisible . restore ( ) ;
46
99
} ) ;
47
-
48
100
it ( "returns correct elements for visible page" , ( ) => {
49
101
sinon . stub ( Pollman , "pageIsVisible" ) . returns ( true ) ;
50
-
51
102
let elements = Pollman . elementsToRefresh ( ) ;
52
-
53
103
expect ( elements . length ) . to . equal ( 2 ) ;
54
104
expect ( elements [ 0 ] . outerHTML ) . to . equal (
55
105
`<div data-poll-background="" data-poll-href="/resources/1" data-poll-state="poll"></div>`
@@ -58,10 +108,8 @@ describe("Pollman", () => {
58
108
`<div data-poll-href="/resources/2" data-poll-state="poll"></div>`
59
109
) ;
60
110
} ) ;
61
-
62
111
it ( "returns correct elements for visible page when forced to" , ( ) => {
63
112
sinon . stub ( Pollman , "pageIsVisible" ) . returns ( true ) ;
64
-
65
113
let elements = Pollman . elementsToRefresh ( { forceRefresh : true } ) ;
66
114
expect ( elements . length ) . to . equal ( 2 ) ;
67
115
expect ( elements [ 0 ] . outerHTML ) . to . equal (
@@ -71,20 +119,16 @@ describe("Pollman", () => {
71
119
`<div data-poll-href="/resources/2" data-poll-state="poll"></div>`
72
120
) ;
73
121
} ) ;
74
-
75
122
it ( "returns correct elements for not active tab" , ( ) => {
76
123
sinon . stub ( Pollman , "pageIsVisible" ) . returns ( false ) ;
77
-
78
124
let elements = Pollman . elementsToRefresh ( ) ;
79
125
expect ( elements . length ) . to . equal ( 1 ) ;
80
126
expect ( elements [ 0 ] . outerHTML ) . to . equal (
81
127
`<div data-poll-background="" data-poll-href="/resources/1" data-poll-state="poll"></div>`
82
128
) ;
83
129
} ) ;
84
-
85
130
it ( "returns correct elements for not active tab when forced to " , ( ) => {
86
131
sinon . stub ( Pollman , "pageIsVisible" ) . returns ( false ) ;
87
-
88
132
let elements = Pollman . elementsToRefresh ( { forceRefresh : true } ) ;
89
133
expect ( elements . length ) . to . equal ( 2 ) ;
90
134
expect ( elements [ 0 ] . outerHTML ) . to . equal (
0 commit comments