mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 07:42:24 +00:00
Merge pull request #25 from zitadel/setup-unit-integration-tests
test: setup unit tests
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
module.exports = {
|
||||
extends: "next/core-web-vitals",
|
||||
extends: ["next/core-web-vitals"],
|
||||
ignorePatterns: ["external/**/*.ts"],
|
||||
};
|
||||
|
||||
57
apps/login/__test__/PasswordComplexity.test.tsx
Normal file
57
apps/login/__test__/PasswordComplexity.test.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import { render, screen, waitFor, within } from "@testing-library/react";
|
||||
import PasswordComplexity from "../ui/PasswordComplexity";
|
||||
// TODO: Why does this not compile?
|
||||
// import { ResourceOwnerType } from '@zitadel/server';
|
||||
|
||||
const matchesTitle = `Matches`;
|
||||
const doesntMatchTitle = `Doesn't match`;
|
||||
|
||||
describe("<PasswordComplexity/>", () => {
|
||||
describe.each`
|
||||
settingsMinLength | password | expectSVGTitle
|
||||
${5} | ${"Password1!"} | ${matchesTitle}
|
||||
${30} | ${"Password1!"} | ${doesntMatchTitle}
|
||||
${0} | ${"Password1!"} | ${matchesTitle}
|
||||
${undefined} | ${"Password1!"} | ${false}
|
||||
`(
|
||||
`With settingsMinLength=$settingsMinLength, password=$password, expectSVGTitle=$expectSVGTitle`,
|
||||
({ settingsMinLength, password, expectSVGTitle }) => {
|
||||
const feedbackElementLabel = /password length/i;
|
||||
beforeEach(() => {
|
||||
render(
|
||||
<PasswordComplexity
|
||||
password={password}
|
||||
equals
|
||||
passwordComplexitySettings={{
|
||||
minLength: settingsMinLength,
|
||||
requiresLowercase: false,
|
||||
requiresUppercase: false,
|
||||
requiresNumber: false,
|
||||
requiresSymbol: false,
|
||||
resourceOwnerType: 0, // ResourceOwnerType.RESOURCE_OWNER_TYPE_UNSPECIFIED,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
if (expectSVGTitle === false) {
|
||||
it(`should not render the feedback element`, async () => {
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.queryByText(feedbackElementLabel)
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
it(`Should show one SVG with title ${expectSVGTitle}`, async () => {
|
||||
await waitFor(async () => {
|
||||
const svg = within(
|
||||
screen.getByText(feedbackElementLabel)
|
||||
.parentElement as HTMLElement
|
||||
).findByRole("img");
|
||||
expect(await svg).toHaveTextContent(expectSVGTitle);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
7
apps/login/__test__/tsconfig.json
Normal file
7
apps/login/__test__/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsxdev",
|
||||
"types": ["node", "jest", "@testing-library/jest-dom"]
|
||||
}
|
||||
}
|
||||
19
apps/login/jest.config.ts
Normal file
19
apps/login/jest.config.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { Config } from "@jest/types";
|
||||
import { pathsToModuleNameMapper } from "ts-jest";
|
||||
import { compilerOptions } from "./tsconfig.json";
|
||||
|
||||
export default async (): Promise<Config.InitialOptions> => {
|
||||
return {
|
||||
preset: "ts-jest",
|
||||
transform: {
|
||||
"^.+\\.tsx?$": ["ts-jest", { tsconfig: "./__test__/tsconfig.json" }],
|
||||
},
|
||||
setupFilesAfterEnv: ["@testing-library/jest-dom/extend-expect"],
|
||||
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
|
||||
prefix: "<rootDir>/",
|
||||
}),
|
||||
testEnvironment: "jsdom",
|
||||
testRegex: "/__test__/.*\\.test\\.tsx?$",
|
||||
modulePathIgnorePatterns: ["cypress"],
|
||||
};
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
// Custom hook to read auth record and user profile doc
|
||||
// Custom hook to read auth record and user profile doc
|
||||
export function useUserData() {
|
||||
const [clientData, setClientData] = useState(null);
|
||||
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
"name": "@zitadel/login",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"dev": "next dev",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"lint": "next lint && prettier --check .",
|
||||
"lint:fix": "prettier --write .",
|
||||
"lint-staged": "lint-staged",
|
||||
"build": "next build",
|
||||
"prestart": "build",
|
||||
"start": "next start",
|
||||
"test": "yarn prettier:check &nexarn lint",
|
||||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
|
||||
},
|
||||
"git": {
|
||||
@@ -39,24 +41,34 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@bufbuild/buf": "^1.14.0",
|
||||
"@jest/types": "^29.5.0",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/ms": "0.7.31",
|
||||
"@types/node": "18.11.9",
|
||||
"@types/react": "18.0.25",
|
||||
"@types/react": "18.2.8",
|
||||
"@types/react-dom": "18.0.9",
|
||||
"@types/testing-library__jest-dom": "^5.14.6",
|
||||
"@types/tinycolor2": "1.4.3",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"@vercel/git-hooks": "1.0.0",
|
||||
"@zitadel/tsconfig": "workspace:*",
|
||||
"autoprefixer": "10.4.13",
|
||||
"del-cli": "5.0.0",
|
||||
"eslint-config-zitadel": "workspace:*",
|
||||
"grpc-tools": "1.11.3",
|
||||
"jest": "^29.5.0",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"lint-staged": "13.0.3",
|
||||
"make-dir-cli": "3.0.0",
|
||||
"postcss": "8.4.21",
|
||||
"prettier-plugin-tailwindcss": "0.1.13",
|
||||
"tailwindcss": "3.2.4",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"ts-proto": "^1.139.0",
|
||||
"typescript": "4.8.4",
|
||||
"typescript": "5.0.4",
|
||||
"zitadel-tailwind-config": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
{
|
||||
"extends": "@zitadel/tsconfig/nextjs.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "preserve",
|
||||
"rootDir": ".",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"#/*": ["./*"]
|
||||
},
|
||||
"plugins": [{ "name": "next" }]
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
|
||||
@@ -20,7 +20,9 @@ const check = (
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="w-6 h-6 las la-check text-green-500 dark:text-green-500 mr-2 text-lg"
|
||||
role="img"
|
||||
>
|
||||
<title>Matches</title>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
@@ -36,7 +38,9 @@ const cross = (
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
role="img"
|
||||
>
|
||||
<title>Doesn't match</title>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
@@ -60,12 +64,16 @@ export default function PasswordComplexity({
|
||||
|
||||
return (
|
||||
<div className="mb-4 grid grid-cols-2 gap-x-8 gap-y-2">
|
||||
<div className="flex flex-row items-center">
|
||||
{hasMinLength ? check : cross}
|
||||
<span className={desc}>
|
||||
Password length {passwordComplexitySettings.minLength}
|
||||
</span>
|
||||
</div>
|
||||
{passwordComplexitySettings.minLength != undefined ? (
|
||||
<div className="flex flex-row items-center">
|
||||
{hasMinLength ? check : cross}
|
||||
<span className={desc}>
|
||||
Password length {passwordComplexitySettings.minLength}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<span />
|
||||
)}
|
||||
<div className="flex flex-row items-center">
|
||||
{hasSymbol ? check : cross}
|
||||
<span className={desc}>has Symbol</span>
|
||||
|
||||
@@ -28,7 +28,9 @@ export default function VerifyEmailForm({ userId, code, submit }: Props) {
|
||||
|
||||
useEffect(() => {
|
||||
if (submit && code && userId) {
|
||||
submitCode({ code });
|
||||
// When we navigate to this page, we always want to be redirected if submit is true and the parameters are valid.
|
||||
// For programmatic verification, the /verifyemail API should be used.
|
||||
submitCodeAndContinue({ code });
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -53,12 +55,11 @@ export default function VerifyEmailForm({ userId, code, submit }: Props) {
|
||||
|
||||
const response = await res.json();
|
||||
|
||||
setLoading(false);
|
||||
if (!res.ok) {
|
||||
setLoading(false);
|
||||
setError(response.details);
|
||||
return Promise.reject(response);
|
||||
} else {
|
||||
setLoading(false);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user