diff --git a/site/src/pages/SetupPage/SetupPage.test.tsx b/site/src/pages/SetupPage/SetupPage.test.tsx
index 7d53fe1dce..90272e00fe 100644
--- a/site/src/pages/SetupPage/SetupPage.test.tsx
+++ b/site/src/pages/SetupPage/SetupPage.test.tsx
@@ -1,7 +1,8 @@
import { fireEvent, screen, waitFor } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { rest } from "msw"
-import { render } from "testHelpers/renderHelpers"
+import { createMemoryRouter } from "react-router-dom"
+import { render, renderWithRouter } from "testHelpers/renderHelpers"
import { server } from "testHelpers/server"
import { SetupPage } from "./SetupPage"
import { Language as PageViewLanguage } from "./SetupPageView"
@@ -35,6 +36,12 @@ describe("Setup Page", () => {
rest.get("/api/v2/users/me", (req, res, ctx) => {
return res(ctx.status(401), ctx.json({ message: "no user here" }))
}),
+ rest.get("/api/v2/users/first", (req, res, ctx) => {
+ return res(
+ ctx.status(404),
+ ctx.json({ message: "no first user has been created" }),
+ )
+ }),
)
})
@@ -63,23 +70,109 @@ describe("Setup Page", () => {
)
}),
)
+
render()
await fillForm()
const errorMessage = await screen.findByText(fieldErrorMessage)
expect(errorMessage).toBeDefined()
})
- it("redirects to workspaces page when success", async () => {
- render()
+ it("redirects to the app when setup is successful", async () => {
+ let userHasBeenCreated = false
+ server.use(
+ rest.get("/api/v2/users/me", (req, res, ctx) => {
+ if (!userHasBeenCreated) {
+ return res(ctx.status(401), ctx.json({ message: "no user here" }))
+ }
+ return res(ctx.status(200), ctx.json(MockUser))
+ }),
+ rest.get("/api/v2/users/first", (req, res, ctx) => {
+ if (!userHasBeenCreated) {
+ return res(
+ ctx.status(404),
+ ctx.json({ message: "no first user has been created" }),
+ )
+ }
+ return res(
+ ctx.status(200),
+ ctx.json({ message: "hooray, someone exists!" }),
+ )
+ }),
+ rest.post("/api/v2/users/first", (req, res, ctx) => {
+ userHasBeenCreated = true
+ return res(
+ ctx.status(200),
+ ctx.json({ data: "user setup was successful!" }),
+ )
+ }),
+ )
+
+ render()
+ await fillForm()
+ await waitFor(() => expect(window.location).toBeAt("/"))
+ })
+
+ it("redirects to login if setup has already completed", async () => {
+ // simulates setup having already been completed
+ server.use(
+ rest.get("/api/v2/users/first", (req, res, ctx) => {
+ return res(
+ ctx.status(200),
+ ctx.json({ message: "hooray, someone exists!" }),
+ )
+ }),
+ )
+
+ renderWithRouter(
+ createMemoryRouter(
+ [
+ {
+ path: "/setup",
+ element: ,
+ },
+ {
+ path: "/login",
+ element:
Login
,
+ },
+ ],
+ { initialEntries: ["/setup"] },
+ ),
+ )
+
+ await screen.findByText("Login")
+ })
+
+ it("redirects to the app when already logged in", async () => {
// simulates the user will be authenticated
server.use(
rest.get("/api/v2/users/me", (req, res, ctx) => {
return res(ctx.status(200), ctx.json(MockUser))
}),
+ rest.get("/api/v2/users/first", (req, res, ctx) => {
+ return res(
+ ctx.status(200),
+ ctx.json({ message: "hooray, someone exists!" }),
+ )
+ }),
)
- await fillForm()
- await waitFor(() => expect(window.location).toBeAt("/workspaces"))
+ renderWithRouter(
+ createMemoryRouter(
+ [
+ {
+ path: "/setup",
+ element: ,
+ },
+ {
+ path: "/",
+ element: Workspaces
,
+ },
+ ],
+ { initialEntries: ["/setup"] },
+ ),
+ )
+
+ await screen.findByText("Workspaces")
})
})
diff --git a/site/src/pages/SetupPage/SetupPage.tsx b/site/src/pages/SetupPage/SetupPage.tsx
index 56c9b9b78f..17aef0f318 100644
--- a/site/src/pages/SetupPage/SetupPage.tsx
+++ b/site/src/pages/SetupPage/SetupPage.tsx
@@ -1,10 +1,11 @@
import { useMachine } from "@xstate/react"
import { useAuth } from "components/AuthProvider/AuthProvider"
-import { FC, useEffect } from "react"
+import { FC } from "react"
import { Helmet } from "react-helmet-async"
import { pageTitle } from "utils/page"
import { setupMachine } from "xServices/setup/setupXService"
import { SetupPageView } from "./SetupPageView"
+import { Navigate } from "react-router-dom"
export const SetupPage: FC = () => {
const [authState, authSend] = useAuth()
@@ -24,11 +25,20 @@ export const SetupPage: FC = () => {
})
const { error } = setupState.context
- useEffect(() => {
- if (authState.matches("signedIn")) {
- window.location.assign("/workspaces")
- }
- }, [authState])
+ const userIsSignedIn = authState.matches("signedIn")
+ const setupIsComplete =
+ !authState.matches("loadingInitialAuthData") &&
+ !authState.matches("configuringTheFirstUser")
+
+ // If the user is logged in, navigate to the app
+ if (userIsSignedIn) {
+ return
+ }
+
+ // If we've already completed setup, navigate to the login page
+ if (setupIsComplete) {
+ return
+ }
return (
<>