Skip to content

Commit

Permalink
chore(ftux): full integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
neurosnap committed May 8, 2023
1 parent 27bc6fc commit 19158e9
Show file tree
Hide file tree
Showing 33 changed files with 1,816 additions and 74 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/line-clamp": "^0.4.2",
"@tailwindcss/typography": "^0.5.9",
"@testing-library/dom": "^9.2.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3",
"@types/debug": "^4.1.7",
"@types/node": "^18.11.18",
"@types/react": "^18.0.25",
Expand All @@ -40,6 +42,7 @@
"debug": "^4.3.4",
"history": "^5.3.0",
"jsdom": "^21.1.0",
"msw": "^1.2.1",
"postcss": "^8.4.21",
"qrcode.react": "^3.1.0",
"query-string": "^8.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ftuxRouter, router } from "./router";
import { selectOrigin } from "@app/env";
import { RouterProvider } from "react-router";

const AppRouter = () => {
export const AppRouter = () => {
const origin = useSelector(selectOrigin);
return (
<div className="h-full w-full">
Expand Down
22 changes: 11 additions & 11 deletions src/app/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ import {
} from "@app/ui";
import { ReactRouterErrorElement } from "@app/ui/shared/error-boundary";

const ftuxRoutes: RouteObject[] = [
const errorPatch = (appRoute: RouteObject) => ({
...appRoute,
errorElement: <ReactRouterErrorElement />,
});

export const ftuxRoutes: RouteObject[] = [
{
path: routes.HOME_PATH,
element: <AuthRequired />,
Expand Down Expand Up @@ -188,9 +193,9 @@ const ftuxRoutes: RouteObject[] = [
path: "*",
element: <NotFoundPage />,
},
];
].map(errorPatch);

const appRoutes: RouteObject[] = [
export const appRoutes: RouteObject[] = [
{
path: routes.HOME_PATH,
element: <AuthRequired />,
Expand Down Expand Up @@ -470,12 +475,7 @@ const appRoutes: RouteObject[] = [
path: "*",
element: <NotFoundPage />,
},
];

const errorPatch = (appRoute: RouteObject) => ({
...appRoute,
errorElement: <ReactRouterErrorElement />,
});
].map(errorPatch);

export const ftuxRouter = createBrowserRouter(ftuxRoutes.map(errorPatch));
export const router = createBrowserRouter(appRoutes.map(errorPatch));
export const ftuxRouter = createBrowserRouter(ftuxRoutes);
export const router = createBrowserRouter(appRoutes);
84 changes: 84 additions & 0 deletions src/app/test/create-project.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { act, fireEvent, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import { setupAppIntegrationTest } from "@app/test";

describe("Create project flow", () => {
describe("existing user with ssh keys", () => {
it("should successfully provision resources within an environment", async () => {
const { App } = setupAppIntegrationTest({
initEntries: ["/create"],
});
render(<App />);

// deploy code landing page
const el = await screen.findByRole("button");
expect(el.textContent).toEqual("Deploy your code");
// go to next page
fireEvent.click(el);

// create environment page
const nameInput = await screen.findByRole("textbox", { name: "name" });
await act(async () => {
await userEvent.type(nameInput, "test-project");
});

const btn = await screen.findByRole("button", {
name: /Create Environment/,
});
// go to next page
fireEvent.click(btn);

// push your code page
await screen.findByText(/Push your code to continue/);

// settings page
await screen.findByText(/Review your Settings/);

const banner = await screen.findByRole("status");
expect(banner.textContent).toMatch(/Your code has a Dockerfile/);

const dbBtn = await screen.findByRole("button", {
name: /New Database/,
});
fireEvent.click(dbBtn);

const dbSelector = await screen.findByRole("combobox");
userEvent.selectOptions(dbSelector, "postgres:14");
const dbEnvVar = await screen.findByRole("textbox", { name: "envvar" });
expect(dbEnvVar).toHaveDisplayValue("DATABASE_URL");

const saveBtn = await screen.findByRole("button", {
name: /Save & Deploy/,
});

// go to next page
fireEvent.click(saveBtn);

// status page
await screen.findByRole("button", {
name: "View Environment",
});
const status = await screen.findByText(/Deployed today/);
expect(status).toBeInTheDocument();

await screen.findByText("Initial configuration");
await screen.findByText("App deployment");
await screen.findByText("Database provision test-app-1-postgres");
let ops = await screen.findAllByText("DONE");
expect(ops.length).toEqual(3);

// create https endpoint
await screen.findByText("Which service needs an endpoint?");

const vhostSelector = await screen.findAllByRole("radio");
fireEvent.click(vhostSelector[0]);
const httpBtn = await screen.findByText("Create endpoint");
fireEvent.click(httpBtn);

await screen.findByText("HTTPS endpoint provision");
ops = await screen.findAllByText("DONE");
expect(ops.length).toEqual(4);
});
});
});
35 changes: 33 additions & 2 deletions src/deploy/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ import {
} from "../environment";
import { deserializeImage } from "../image";
import { deserializeDeployOperation, waitForOperation } from "../operation";
import { DeployServiceResponse } from "../service";
import { selectDeploy } from "../slice";

export * from "./utils";

export interface DeployAppResponse {
id: string;
id: number;
handle: string;
git_repo: string;
created_at: string;
Expand All @@ -40,13 +41,43 @@ export interface DeployAppResponse {
};
_embedded: {
// TODO: fill in
services: { id: number }[];
services: DeployServiceResponse[];
current_image: any;
last_deploy_operation: any;
last_operation: any;
};
_type: "app";
}

export const defaultAppResponse = (
p: Partial<DeployAppResponse> = {},
): DeployAppResponse => {
const now = new Date().toISOString();
return {
id: 1,
handle: "",
git_repo: "",
created_at: now,
updated_at: now,
deployment_method: "",
status: "provisioned",
_links: {
account: { href: "" },
current_configuration: { href: "" },
...p._links,
},
_embedded: {
services: [],
current_image: null,
last_deploy_operation: null,
last_operation: null,
...p._embedded,
},
...p,
_type: "app",
};
};

export const deserializeDeployApp = (payload: DeployAppResponse): DeployApp => {
const serviceIds: string[] = payload._embedded.services.map((s) => `${s.id}`);
const links = payload._links;
Expand Down
18 changes: 17 additions & 1 deletion src/deploy/code-scan-result/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,29 @@ export interface DeployCodeScanResponse {
dockerfile_present: boolean;
procfile_present: boolean;
_links: {
self: LinkResponse;
app: LinkResponse;
operation: LinkResponse;
};
_type: "code_scan_result";
}

export const defaultCodeScanResponse = (
c: Partial<DeployCodeScanResponse> = {},
): DeployCodeScanResponse => {
return {
id: 0,
aptible_yml_present: false,
dockerfile_present: false,
procfile_present: false,
_links: {
app: { href: "" },
operation: { href: "" },
},
_type: "code_scan_result",
...c,
};
};

export const fetchCodeScanResult = api.get<{ id: string }>(
"/code_scan_results/:id",
api.cache(),
Expand Down
20 changes: 20 additions & 0 deletions src/deploy/database-images/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,26 @@ export interface DeployDatabaseImageResponse {
_type: "database_image";
}

export const defaultDatabaseImageResponse = (
i: Partial<DeployDatabaseImageResponse> = {},
): DeployDatabaseImageResponse => {
const now = new Date().toISOString();
return {
id: 0,
default: true,
description: "",
discoverable: true,
docker_repo: "",
type: "",
version: "",
visible: true,
created_at: now,
updated_at: now,
_type: "database_image",
...i,
};
};

export const deserializeDeployDatabaseImage = (
payload: DeployDatabaseImageResponse,
): DeployDatabaseImage => {
Expand Down
33 changes: 33 additions & 0 deletions src/deploy/database/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export interface DeployDatabaseResponse {
disk: any;
last_operation: any;
};
_type: "database";
}

export interface BackupResponse {
Expand All @@ -85,6 +86,38 @@ export interface HalBackups {
backups: BackupResponse[];
}

export const defaultDatabaseResponse = (
d: Partial<DeployDatabaseResponse> = {},
): DeployDatabaseResponse => {
const now = new Date().toISOString();
return {
id: 1,
handle: "",
provisioned: true,
type: "",
status: "provisioned",
docker_repo: "",
current_kms_arn: "",
connection_url: "",
created_at: now,
updated_at: now,
_links: {
account: { href: "" },
service: { href: "" },
database_image: { href: "" },
initialize_from: { href: "" },
...d._links,
},
_embedded: {
disk: null,
last_operation: null,
...d._embedded,
},
_type: "database",
...d,
};
};

export const deserializeDeployDatabase = (
payload: DeployDatabaseResponse,
): DeployDatabase => {
Expand Down
Loading

0 comments on commit 19158e9

Please sign in to comment.