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 ,
7+ generateUuid ,
68 getFirstString ,
9+ getOptions ,
710 logError ,
811 normalize ,
912 plural ,
@@ -12,6 +15,10 @@ import {
1215 trimSlashes ,
1316} from "../src/common/util"
1417
18+ const dom = new JSDOM ( )
19+ global . document = dom . window . document
20+ // global.window = (dom.window as unknown) as Window & typeof globalThis
21+
1522type LocationLike = Pick < Location , "pathname" | "origin" >
1623
1724describe ( "util" , ( ) => {
@@ -49,6 +56,20 @@ describe("util", () => {
4956 } )
5057 } )
5158
59+ describe ( "generateUuid" , ( ) => {
60+ it ( "should generate a unique uuid" , ( ) => {
61+ const uuid = generateUuid ( )
62+ const uuid2 = generateUuid ( )
63+ expect ( uuid ) . toHaveLength ( 24 )
64+ expect ( typeof uuid ) . toBe ( "string" )
65+ expect ( uuid ) . not . toBe ( uuid2 )
66+ } )
67+ it ( "should generate a uuid of a specific length" , ( ) => {
68+ const uuid = generateUuid ( 10 )
69+ expect ( uuid ) . toHaveLength ( 10 )
70+ } )
71+ } )
72+
5273 describe ( "trimSlashes" , ( ) => {
5374 it ( "should remove leading slashes" , ( ) => {
5475 expect ( trimSlashes ( "/hello-world" ) ) . toBe ( "hello-world" )
@@ -103,6 +124,76 @@ describe("util", () => {
103124 } )
104125 } )
105126
127+ describe ( "getOptions" , ( ) => {
128+ // Things to mock
129+ // logger
130+ // location
131+ // document
132+ beforeEach ( ( ) => {
133+ const location : LocationLike = {
134+ pathname : "/healthz" ,
135+ origin : "http://localhost:8080" ,
136+ // search: "?environmentId=600e0187-0909d8a00cb0a394720d4dce",
137+ }
138+
139+ // Because resolveBase is not a pure function
140+ // and relies on the global location to be set
141+ // we set it before all the tests
142+ // and tell TS that our location should be looked at
143+ // as Location (even though it's missing some properties)
144+ global . location = location as Location
145+ } )
146+
147+ afterEach ( ( ) => {
148+ jest . restoreAllMocks ( )
149+ } )
150+
151+ it ( "should return options with base and cssStaticBase even if it doesn't exist" , ( ) => {
152+ expect ( getOptions ( ) ) . toStrictEqual ( {
153+ base : "" ,
154+ csStaticBase : "" ,
155+ } )
156+ } )
157+
158+ it ( "should return options when they do exist" , ( ) => {
159+ // Mock getElementById
160+ const spy = jest . spyOn ( document , "getElementById" )
161+ // Create a fake element and set the attribute
162+ const mockElement = document . createElement ( "div" )
163+ mockElement . setAttribute (
164+ "data-settings" ,
165+ '{"base":".","csStaticBase":"./static/development/Users/jp/Dev/code-server","logLevel":2,"disableTelemetry":false,"disableUpdateCheck":false}' ,
166+ )
167+ // Return mockElement from the spy
168+ // this way, when we call "getElementById"
169+ // it returns the element
170+ spy . mockImplementation ( ( ) => mockElement )
171+
172+ expect ( getOptions ( ) ) . toStrictEqual ( {
173+ base : "" ,
174+ csStaticBase : "/static/development/Users/jp/Dev/code-server" ,
175+ disableTelemetry : false ,
176+ disableUpdateCheck : false ,
177+ logLevel : 2 ,
178+ } )
179+ } )
180+
181+ it ( "should include queryOpts" , ( ) => {
182+ // Trying to understand how the implementation works
183+ // 1. It grabs the search params from location.search (i.e. ?)
184+ // 2. it then grabs the "options" param if it exists
185+ // 3. then it creates a new options object
186+ // spreads the original options
187+ // then parses the queryOpts
188+ location . search = '?options={"logLevel":2}'
189+ expect ( getOptions ( ) ) . toStrictEqual ( {
190+ base : "" ,
191+ csStaticBase : "" ,
192+ logLevel : 2 ,
193+ } )
194+ } )
195+ } )
196+
106197 describe ( "arrayify" , ( ) => {
107198 it ( "should return value it's already an array" , ( ) => {
108199 expect ( arrayify ( [ "hello" , "world" ] ) ) . toStrictEqual ( [ "hello" , "world" ] )
0 commit comments