Page MenuHomeSealhub

form.test.ts
No OneTemporary

form.test.ts

import Router from "@koa/router";
import axios from "axios";
import Koa, { BaseContext } from "koa";
import { Browser, firefox, Page } from "playwright";
import { Controls, Fields, Form, Mountable } from "../index";
import { mount } from "../mount";
import { assertThrowsAsync } from "../utils/utils";
const fields = {
text: new Fields.SimpleFormField(true),
};
export function form_factory(
canAccessFun?: Mountable["canAccess"]
): Form<typeof fields, void> {
const result = new (class extends Form<typeof fields, void> {
fields = fields;
submitButtonText = "Submit";
controls = [
new Controls.SimpleInput(fields.text, {
label: "This is a test:",
type: "password",
}),
];
async onSubmit() {
return;
}
})();
if (canAccessFun) result.canAccess = canAccessFun;
return result;
}
describe("form test", () => {
let browser: Browser;
let page: Page;
before(async () => {
browser = await firefox.launch();
const context = await browser.newContext();
page = await context.newPage();
});
after(async () => {
await browser.close();
});
describe("basic tests", async () => {
let server: ReturnType<Koa["listen"]>;
before(async () => {
const app = new Koa();
const router = new Router();
mount(router, "/", form_factory(), true);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(8080);
await page.goto("http://localhost:8080");
});
after(async () => {
server.close();
});
it("does not allow to submit an empty form when there's a required field", async () => {
await page
.getByRole("button", { name: "Submit", exact: true })
.click();
await assertThrowsAsync(async () => {
return page.getByText("Done").click({ timeout: 500 });
});
});
it("allows to submit a form when all required fields have a value", async () => {
await page.getByPlaceholder("password").click();
await page.getByPlaceholder("password").fill("testpasswd");
await page
.getByRole("button", { name: "Submit", exact: true })
.click();
await page.getByText("Done").click();
});
it("does not allow submitting an empty form by circumventing HTML-based validation", async () => {
const res_axios = await axios.post(
"http://localhost:8080",
{
text: "",
},
{
validateStatus: (status: number) => {
if (status == 422) return true;
return false;
},
}
);
if (!res_axios.data.includes("Some fields are invalid")) {
throw new Error(
"when sending a empty request with axios, the error didnt appear"
);
}
});
});
describe("canAccess tests", async () => {
let server: ReturnType<Koa["listen"]>;
afterEach(async () => {
server.close();
});
it("allows visit when configured when canAccess returns true", async () => {
const app = new Koa();
const router = new Router();
mount(
router,
"/",
form_factory(
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return { canAccess: true, message: "" };
}
),
true
);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(8080);
const response = await page.goto("http://localhost:8080");
if (response?.status() != 200) {
throw new Error(
`Should return 200 status and it returns ${response?.status()}`
);
}
});
describe("declines access when canAccess returns false", async () => {
const app = new Koa();
const router = new Router();
before(async () => {
mount(
router,
"/",
form_factory(
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return { canAccess: false, message: "" };
}
),
true
);
app.use(router.routes()).use(router.allowedMethods());
});
beforeEach(async () => {
server = app.listen(8080);
});
it("prevents the form from rendering", async () => {
const response = await page.goto("http://localhost:8080");
if (response?.status() != 403) {
throw new Error(
`Should return 403 status and it returns ${response?.status()}`
);
}
});
it("does not allow submitting of the form through axios", async () => {
await axios.post(
"http://localhost:8080",
{
text: "sample",
},
{
validateStatus: (status: number) => {
if (status == 403) return true;
return false;
},
}
);
});
});
it("passes the context to canAccess (false case)", async () => {
const app = new Koa();
const router = new Router();
mount(
router,
"/",
form_factory(
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return ctx.$context && ctx.$context.user_id
? { canAccess: true, message: "" }
: { canAccess: false, message: "" };
}
),
true
);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(8080);
const response = await page.goto("http://localhost:8080");
if (response?.status() != 403) {
throw new Error(
`Should return 403 status and it returns ${response?.status()}`
);
}
});
it("passes the context to canAccess (true case)", async () => {
const app = new Koa();
const router = new Router();
router.use(async (ctx: BaseContext, next: any) => {
ctx.$context = {
user_id: "miguel",
} as any;
await next();
});
mount(
router,
"/",
form_factory(
async (
ctx: Koa.Context
): Promise<{ canAccess: boolean; message: string }> => {
return ctx.$context && ctx.$context.user_id
? { canAccess: true, message: "" }
: { canAccess: false, message: "" };
}
),
true
);
app.use(router.routes()).use(router.allowedMethods());
server = app.listen(8080);
const response = await page.goto("http://localhost:8080");
if (response?.status() != 200) {
throw new Error(
`Should return 200 status and it returns ${response?.status()}`
);
}
});
});
});

File Metadata

Mime Type
text/x-java
Expires
Sun, Nov 2, 18:47 (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1030486
Default Alt Text
form.test.ts (5 KB)

Event Timeline