diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 000000000..0002e04a8 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,26 @@ +import type { Config } from 'jest'; + +const config: Config = { + preset: 'jest-preset-angular', + testEnvironment: 'jsdom', + setupFilesAfterEnv: ['/setup-jest.ts'], + testMatch: ['**/?(*.)+(spec).ts'], + transform: { + '^.+\\.(ts|mjs|js)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + }, + ], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + moduleNameMapper: { + '^@app/(.*)$': '/src/app/$1', + }, + testPathIgnorePatterns: ['/node_modules/', '/dist/'], + reporters: ['default'], +}; + +export default config; + + diff --git a/package.json b/package.json index 0cd7ccce8..12aae9d80 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "ng": "ng", "start": "ng serve", "build": "ng build", - "test": "ng test", + "test": "jest", "lint": "ng lint --force", "prepare": "husky install" }, @@ -34,10 +34,14 @@ "@angular/build": "^20.0.0", "@angular/cli": "^20.0.0", "@angular/compiler-cli": "20.0.0", + "@types/jest": "^29.5.12", "@types/marked": "^6.0.0", + "jest": "^29.7.0", + "jest-preset-angular": "^14.0.0", "husky": "^8.0.3", "lint-staged": "^16.1.2", "prettier": "^3.1.1", + "ts-node": "^10.9.2", "typescript": "~5.8.3" }, "lint-staged": { diff --git a/setup-jest.ts b/setup-jest.ts new file mode 100644 index 000000000..5c1d3caa2 --- /dev/null +++ b/setup-jest.ts @@ -0,0 +1,6 @@ +import 'jest-preset-angular/setup-jest'; + +// Optional: mock for window.scrollTo etc. add minimal DOM APIs if needed +Object.defineProperty(window, 'scrollTo', { value: () => {}, writable: true }); + + diff --git a/src/app/core/auth/services/jwt.service.spec.ts b/src/app/core/auth/services/jwt.service.spec.ts new file mode 100644 index 000000000..1cb71bd2a --- /dev/null +++ b/src/app/core/auth/services/jwt.service.spec.ts @@ -0,0 +1,25 @@ +import { TestBed } from "@angular/core/testing"; +import { JwtService } from "./jwt.service"; + +describe("JwtService", () => { + let service: JwtService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(JwtService); + window.localStorage.clear(); + }); + + it("should save and get token", () => { + service.saveToken("abc123"); + expect(service.getToken()).toBe("abc123"); + }); + + it("should remove token on destroy", () => { + service.saveToken("xyz"); + service.destroyToken(); + expect(service.getToken()).toBeUndefined(); + }); +}); + + diff --git a/src/app/shared/components/list-errors.component.spec.ts b/src/app/shared/components/list-errors.component.spec.ts new file mode 100644 index 000000000..c0cae81f4 --- /dev/null +++ b/src/app/shared/components/list-errors.component.spec.ts @@ -0,0 +1,17 @@ +import { ListErrorsComponent } from "./list-errors.component"; + +describe("ListErrorsComponent", () => { + it("should build errorList from Errors input", () => { + const cmp = new ListErrorsComponent(); + cmp.errors = { errors: { email: "is invalid", password: "is too short" } }; + expect(cmp.errorList).toEqual(["email is invalid", "password is too short"]); + }); + + it("should handle null input as empty list", () => { + const cmp = new ListErrorsComponent(); + cmp.errors = null; + expect(cmp.errorList).toEqual([]); + }); +}); + + diff --git a/src/app/shared/pipes/markdown.pipe.spec.ts b/src/app/shared/pipes/markdown.pipe.spec.ts new file mode 100644 index 000000000..e3ddc221f --- /dev/null +++ b/src/app/shared/pipes/markdown.pipe.spec.ts @@ -0,0 +1,19 @@ +import { TestBed } from "@angular/core/testing"; +import { MarkdownPipe } from "./markdown.pipe"; +import { DomSanitizer } from "@angular/platform-browser"; + +jest.mock("marked", () => ({ + marked: { + parse: (content: string) => `

${content}

`, + }, +})); + +describe("MarkdownPipe", () => { + it("should render markdown to sanitized HTML", async () => { + const pipe = TestBed.runInInjectionContext(() => new MarkdownPipe()); + const result = await pipe.transform("Hello"); + expect(result).toBe("

Hello

"); + }); +}); + + diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 47e3dd755..1b1d13e41 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", - "types": ["jasmine"] + "types": ["jest", "node"] }, "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] }