@@ -3,15 +3,14 @@ import {
3
3
arrayify ,
4
4
generateUuid ,
5
5
getFirstString ,
6
- getOptions ,
7
6
logError ,
8
7
plural ,
9
8
resolveBase ,
10
9
split ,
11
10
trimSlashes ,
12
11
normalize ,
13
12
} from "../../src/common/util"
14
- import { createLoggerMock } from "../utils/helpers"
13
+ import { createLoggerMock , spyOnConsole } from "../utils/helpers"
15
14
16
15
const dom = new JSDOM ( )
17
16
global . document = dom . window . document
@@ -122,7 +121,15 @@ describe("util", () => {
122
121
} )
123
122
124
123
describe ( "getOptions" , ( ) => {
124
+ let getOptions : typeof import ( "../../src/common/util" ) . getOptions
125
+
125
126
beforeEach ( ( ) => {
127
+ // Reset and re-import since the options are cached.
128
+ jest . resetModules ( )
129
+ getOptions = require ( "../../src/common/util" ) . getOptions
130
+
131
+ spyOnConsole ( )
132
+
126
133
const location : LocationLike = {
127
134
pathname : "/healthz" ,
128
135
origin : "http://localhost:8080" ,
@@ -146,44 +153,63 @@ describe("util", () => {
146
153
base : "" ,
147
154
csStaticBase : "" ,
148
155
} )
156
+ expect ( console . error ) . toBeCalledTimes ( 1 )
149
157
} )
150
158
151
159
it ( "should return options when they do exist" , ( ) => {
160
+ const expected = {
161
+ base : "." ,
162
+ csStaticBase : "./static/development/Users/jp/Dev/code-server" ,
163
+ logLevel : 2 ,
164
+ disableTelemetry : false ,
165
+ disableUpdateCheck : false ,
166
+ }
167
+
152
168
// Mock getElementById
153
169
const spy = jest . spyOn ( document , "getElementById" )
154
- // Create a fake element and set the attribute
170
+ // Create a fake element and set the attribute. Options are expected to be
171
+ // stringified JSON.
155
172
const mockElement = document . createElement ( "div" )
156
- mockElement . setAttribute (
157
- "data-settings" ,
158
- '{"base":".","csStaticBase":"./static/development/Users/jp/Dev/code-server","logLevel":2,"disableTelemetry":false,"disableUpdateCheck":false}' ,
159
- )
173
+ mockElement . setAttribute ( "data-settings" , JSON . stringify ( expected ) )
160
174
// Return mockElement from the spy
161
175
// this way, when we call "getElementById"
162
176
// it returns the element
163
177
spy . mockImplementation ( ( ) => mockElement )
164
178
165
179
expect ( getOptions ( ) ) . toStrictEqual ( {
180
+ ...expected ,
181
+ // The two bases should get resolved. The rest should be unchanged.
166
182
base : "" ,
167
183
csStaticBase : "/static/development/Users/jp/Dev/code-server" ,
168
- disableTelemetry : false ,
169
- disableUpdateCheck : false ,
184
+ } )
185
+ expect ( console . error ) . toBeCalledTimes ( 0 )
186
+ } )
187
+
188
+ it ( "should merge options in the query" , ( ) => {
189
+ // Options provided in the query will override any options provided in the
190
+ // HTML. Options are expected to be stringified JSON (same as the
191
+ // element).
192
+ const expected = {
170
193
logLevel : 2 ,
194
+ }
195
+ location . search = `?options=${ JSON . stringify ( expected ) } `
196
+ expect ( getOptions ( ) ) . toStrictEqual ( {
197
+ ...expected ,
198
+ base : "" ,
199
+ csStaticBase : "" ,
171
200
} )
201
+ // Once for the element.
202
+ expect ( console . error ) . toBeCalledTimes ( 1 )
172
203
} )
173
204
174
- it ( "should include queryOpts" , ( ) => {
175
- // Trying to understand how the implementation works
176
- // 1. It grabs the search params from location.search (i.e. ?)
177
- // 2. it then grabs the "options" param if it exists
178
- // 3. then it creates a new options object
179
- // spreads the original options
180
- // then parses the queryOpts
181
- location . search = '?options={"logLevel":2}'
205
+ it ( "should skip bad query options" , ( ) => {
206
+ location . search = "?options=invalidJson"
182
207
expect ( getOptions ( ) ) . toStrictEqual ( {
183
208
base : "" ,
184
209
csStaticBase : "" ,
185
- logLevel : 2 ,
186
210
} )
211
+ // Once for the element, once for the query.
212
+ expect ( console . error ) . toBeCalledTimes ( 2 )
187
213
} )
188
214
} )
189
215
0 commit comments