1+ import { JSDOM } from "jsdom"
12// Note: we need to import logger from the root
23// because this is the logger used in logError in ../src/common/util
34import { logger } from "../node_modules/@coder/logger"
45import {
56 arrayify ,
67 getFirstString ,
8+ getOptions ,
79 logError ,
810 normalize ,
911 plural ,
@@ -12,6 +14,10 @@ import {
1214 trimSlashes ,
1315} from "../src/common/util"
1416
17+ const dom = new JSDOM ( )
18+ global . document = dom . window . document
19+ // global.window = (dom.window as unknown) as Window & typeof globalThis
20+
1521type LocationLike = Pick < Location , "pathname" | "origin" >
1622
1723describe ( "util" , ( ) => {
@@ -103,6 +109,76 @@ describe("util", () => {
103109 } )
104110 } )
105111
112+ describe ( "getOptions" , ( ) => {
113+ // Things to mock
114+ // logger
115+ // location
116+ // document
117+ beforeEach ( ( ) => {
118+ const location : LocationLike = {
119+ pathname : "/healthz" ,
120+ origin : "http://localhost:8080" ,
121+ // search: "?environmentId=600e0187-0909d8a00cb0a394720d4dce",
122+ }
123+
124+ // Because resolveBase is not a pure function
125+ // and relies on the global location to be set
126+ // we set it before all the tests
127+ // and tell TS that our location should be looked at
128+ // as Location (even though it's missing some properties)
129+ global . location = location as Location
130+ } )
131+
132+ afterEach ( ( ) => {
133+ jest . restoreAllMocks ( )
134+ } )
135+
136+ it ( "should return options with base and cssStaticBase even if it doesn't exist" , ( ) => {
137+ expect ( getOptions ( ) ) . toStrictEqual ( {
138+ base : "" ,
139+ csStaticBase : "" ,
140+ } )
141+ } )
142+
143+ it ( "should return options when they do exist" , ( ) => {
144+ // Mock getElementById
145+ const spy = jest . spyOn ( document , "getElementById" )
146+ // Create a fake element and set the attribute
147+ const mockElement = document . createElement ( "div" )
148+ mockElement . setAttribute (
149+ "data-settings" ,
150+ '{"base":".","csStaticBase":"./static/development/Users/jp/Dev/code-server","logLevel":2,"disableTelemetry":false,"disableUpdateCheck":false}' ,
151+ )
152+ // Return mockElement from the spy
153+ // this way, when we call "getElementById"
154+ // it returns the element
155+ spy . mockImplementation ( ( ) => mockElement )
156+
157+ expect ( getOptions ( ) ) . toStrictEqual ( {
158+ base : "" ,
159+ csStaticBase : "/static/development/Users/jp/Dev/code-server" ,
160+ disableTelemetry : false ,
161+ disableUpdateCheck : false ,
162+ logLevel : 2 ,
163+ } )
164+ } )
165+
166+ it ( "should include queryOpts" , ( ) => {
167+ // Trying to understand how the implementation works
168+ // 1. It grabs the search params from location.search (i.e. ?)
169+ // 2. it then grabs the "options" param if it exists
170+ // 3. then it creates a new options object
171+ // spreads the original options
172+ // then parses the queryOpts
173+ location . search = '?options={"logLevel":2}'
174+ expect ( getOptions ( ) ) . toStrictEqual ( {
175+ base : "" ,
176+ csStaticBase : "" ,
177+ logLevel : 2 ,
178+ } )
179+ } )
180+ } )
181+
106182 describe ( "arrayify" , ( ) => {
107183 it ( "should return value it's already an array" , ( ) => {
108184 expect ( arrayify ( [ "hello" , "world" ] ) ) . toStrictEqual ( [ "hello" , "world" ] )
0 commit comments