diff --git a/templates/app/angular/angular.json b/templates/app/angular/angular.json index 0a99a4c08a..81d536178a 100644 --- a/templates/app/angular/angular.json +++ b/templates/app/angular/angular.json @@ -163,17 +163,7 @@ } }, "test": { - "builder": "@angular/build:karma", - "options": { - "browser": "src/test.ts", - "polyfills": ["src/polyfills.ts"], - "tsConfig": "tsconfig.spec.json", - "karmaConfig": "karma.conf.js", - "inlineStyleLanguage": "scss", - "assets": ["src/favicon.ico", "src/assets"], - "styles": ["src/styles.scss"], - "scripts": [] - } + "builder": "@angular/build:unit-test" }, "lint": { "builder": "@angular-eslint/builder:lint", diff --git a/templates/app/angular/karma.conf.js b/templates/app/angular/karma.conf.js deleted file mode 100644 index b06ddef227..0000000000 --- a/templates/app/angular/karma.conf.js +++ /dev/null @@ -1,44 +0,0 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html - -module.exports = function (config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], - plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage'), - - ], - client: { - jasmine: { - // you can add configuration options for Jasmine here - // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html - // for example, you can disable the random execution with `random: false` - // or set a specific seed with `seed: 4321` - }, - clearContext: false // leave Jasmine Spec Runner output visible in browser - }, - jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces - }, - coverageReporter: { - dir: require('path').join(__dirname, './coverage/MyProjectName'), - subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false, - restartOnFileChange: true - }); -}; diff --git a/templates/app/angular/package.json b/templates/app/angular/package.json index 9b318eb19b..9695146bd7 100644 --- a/templates/app/angular/package.json +++ b/templates/app/angular/package.json @@ -47,17 +47,12 @@ "@angular/cli": "~21.0.0", "@angular/compiler-cli": "~21.0.0", "@angular/language-service": "~21.0.0", - "@types/jasmine": "~3.6.0", "@types/node": "~20.11.0", "@typescript-eslint/eslint-plugin": "7.16.0", "@typescript-eslint/parser": "7.16.0", "eslint": "^8.0.0", - "jasmine-core": "~4.0.0", - "karma": "~6.4.4", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage": "~2.1.0", - "karma-jasmine": "~4.0.0", - "karma-jasmine-html-reporter": "^1.7.0", - "typescript": "~5.9.3" + "jsdom": "^27.1.0", + "typescript": "~5.9.3", + "vitest": "^4.0.8" } } \ No newline at end of file diff --git a/templates/app/angular/src/app/home/home.component.html b/templates/app/angular/src/app/home/home.component.html index edcdc66bc0..e3e73e48ae 100644 --- a/templates/app/angular/src/app/home/home.component.html +++ b/templates/app/angular/src/app/home/home.component.html @@ -1,5 +1,4 @@
-
diff --git a/templates/app/angular/src/app/home/home.component.spec.ts b/templates/app/angular/src/app/home/home.component.spec.ts index 2243bfca92..7d0ddb0952 100644 --- a/templates/app/angular/src/app/home/home.component.spec.ts +++ b/templates/app/angular/src/app/home/home.component.spec.ts @@ -1,39 +1,43 @@ import { CoreTestingModule } from "@abp/ng.core/testing"; import { ThemeSharedTestingModule } from "@abp/ng.theme.shared/testing"; -import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; import { NgxValidateCoreModule } from "@ngx-validate/core"; import { HomeComponent } from "./home.component"; import { OAuthService } from 'angular-oauth2-oidc'; import { AuthService } from '@abp/ng.core'; +import { vi } from 'vitest'; describe("HomeComponent", () => { let fixture: ComponentFixture; - const mockOAuthService = jasmine.createSpyObj('OAuthService', ['hasValidAccessToken']) - const mockAuthService = jasmine.createSpyObj('AuthService', ['navigateToLogin']) - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [], - imports: [ - CoreTestingModule.withConfig(), - ThemeSharedTestingModule.withConfig(), - NgxValidateCoreModule, - HomeComponent - ], - providers: [ - /* mock providers here */ - { - provide: OAuthService, - useValue: mockOAuthService - }, - { - provide: AuthService, - useValue: mockAuthService - } - ], - }).compileComponents(); - }) - ); + const mockOAuthService = { + hasValidAccessToken: vi.fn() + }; + const mockAuthService = { + navigateToLogin: vi.fn() + }; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [], + imports: [ + CoreTestingModule.withConfig(), + ThemeSharedTestingModule.withConfig(), + NgxValidateCoreModule, + HomeComponent + ], + providers: [ + /* mock providers here */ + { + provide: OAuthService, + useValue: mockOAuthService + }, + { + provide: AuthService, + useValue: mockAuthService + } + ], + }).compileComponents(); + }); beforeEach(() => { fixture = TestBed.createComponent(HomeComponent); @@ -44,55 +48,49 @@ describe("HomeComponent", () => { expect(fixture.componentInstance).toBeTruthy(); }); - - describe('when login state is true', () => { beforeAll(() => { - mockOAuthService.hasValidAccessToken.and.returnValue(true) + mockOAuthService.hasValidAccessToken.mockReturnValue(true); }); it("hasLoggedIn should be true", () => { - - expect(fixture.componentInstance.hasLoggedIn).toBeTrue(); - expect(mockOAuthService.hasValidAccessToken).toHaveBeenCalled() - }) + expect(fixture.componentInstance.hasLoggedIn).toBe(true); + expect(mockOAuthService.hasValidAccessToken).toHaveBeenCalled(); + }); it("button should not be exists", () => { - const element = fixture.nativeElement - const button = element.querySelector('[role="button"]') - expect(button).toBeNull() - }) - - }) + const element = fixture.nativeElement; + const button = element.querySelector('[role="button"]'); + expect(button).toBeNull(); + }); + }); describe('when login state is false', () => { beforeAll(() => { - mockOAuthService.hasValidAccessToken.and.returnValue(false) + mockOAuthService.hasValidAccessToken.mockReturnValue(false); }); it("hasLoggedIn should be false", () => { - - expect(fixture.componentInstance.hasLoggedIn).toBeFalse(); - expect(mockOAuthService.hasValidAccessToken).toHaveBeenCalled() - }) + expect(fixture.componentInstance.hasLoggedIn).toBe(false); + expect(mockOAuthService.hasValidAccessToken).toHaveBeenCalled(); + }); it("button should be exists", () => { - const element = fixture.nativeElement - const button = element.querySelector('[role="button"]') - expect(button).toBeDefined() - }) - describe('when button clicked', () => { + const element = fixture.nativeElement; + const button = element.querySelector('[role="button"]'); + expect(button).toBeDefined(); + }); + describe('when button clicked', () => { beforeEach(() => { - const element = fixture.nativeElement - const button = element.querySelector('[role="button"]') - button.click() + const element = fixture.nativeElement; + const button = element.querySelector('[role="button"]'); + button.click(); }); it("navigateToLogin have been called", () => { - expect(mockAuthService.navigateToLogin).toHaveBeenCalled() - }) - }) - }) - + expect(mockAuthService.navigateToLogin).toHaveBeenCalled(); + }); + }); + }); }); diff --git a/templates/app/angular/src/app/home/home.component.ts b/templates/app/angular/src/app/home/home.component.ts index ee6bd838c9..7d65148a11 100644 --- a/templates/app/angular/src/app/home/home.component.ts +++ b/templates/app/angular/src/app/home/home.component.ts @@ -1,89 +1,16 @@ -import {AuthService, LocalizationPipe} from '@abp/ng.core'; +import { AuthService, LocalizationPipe } from '@abp/ng.core'; import { Component, inject } from '@angular/core'; -import {NgTemplateOutlet} from "@angular/common"; -import {DynamicFormComponent, FormFieldConfig} from "@abp/ng.components/dynamic-form"; +import { NgTemplateOutlet } from "@angular/common"; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.scss'], - imports: [NgTemplateOutlet, LocalizationPipe, DynamicFormComponent] + imports: [NgTemplateOutlet, LocalizationPipe] }) export class HomeComponent { private authService = inject(AuthService); - formFields: FormFieldConfig[] = [ - { - key: 'firstName', - type: 'text', - label: 'First Name', - placeholder: 'Enter first name', - value: 'erdemc', - required: true, - validators: [ - { type: 'required', message: 'First name is required' }, - { type: 'minLength', value: 2, message: 'Minimum 2 characters required' } - ], - gridSize: 6, - order: 1 - }, - { - key: 'lastName', - type: 'text', - label: 'Last Name', - placeholder: 'Enter last name', - required: true, - validators: [ - { type: 'required', message: 'Last name is required' } - ], - gridSize: 12, - order: 3 - }, - { - key: 'email', - type: 'email', - label: 'Email Address', - placeholder: 'Enter email', - required: true, - validators: [ - { type: 'required', message: 'Email is required' }, - { type: 'email', message: 'Please enter a valid email' } - ], - gridSize: 6, - order: 2 - }, - { - key: 'userType', - type: 'select', - label: 'User Type', - required: true, - options: [ - { key: 'admin', value: 'Administrator' }, - { key: 'user', value: 'Regular User' }, - { key: 'guest', value: 'Guest User' } - ], - validators: [ - { type: 'required', message: 'Please select user type' } - ], - order: 4 - }, - { - key: 'adminNotes', - type: 'textarea', - label: 'Admin Notes', - placeholder: 'Enter admin-specific notes', - conditionalLogic: [ - { - dependsOn: 'userType', - condition: 'equals', - value: 'admin', - action: 'show' - } - ], - order: 5 - } - ]; - get hasLoggedIn(): boolean { return this.authService.isAuthenticated; } diff --git a/templates/app/angular/src/test.ts b/templates/app/angular/src/test.ts deleted file mode 100644 index 3b701bbfa0..0000000000 --- a/templates/app/angular/src/test.ts +++ /dev/null @@ -1,13 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files -import 'zone.js/testing'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting, -} from '@angular/platform-browser-dynamic/testing'; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); diff --git a/templates/app/angular/tsconfig.spec.json b/templates/app/angular/tsconfig.spec.json index 092345b02e..d38370633f 100644 --- a/templates/app/angular/tsconfig.spec.json +++ b/templates/app/angular/tsconfig.spec.json @@ -1,18 +1,15 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", "types": [ - "jasmine" + "vitest/globals" ] }, - "files": [ - "src/test.ts", - "src/polyfills.ts" - ], "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" + "src/**/*.d.ts", + "src/**/*.spec.ts" ] }