fix: add more testsx

This commit is contained in:
master 2025-01-31 08:01:26 +08:00
parent c9d0066d64
commit 28da493462
17 changed files with 2144 additions and 128 deletions

1
.gitignore vendored
View File

@ -55,3 +55,4 @@ debug.log
/playwright-report/
/blob-report/
/playwright/.cache/
/.vitest

View File

@ -6,7 +6,8 @@
"style": {
"noNonNullAssertion": "off",
"noParameterAssign": "off",
"useFilenamingConvention": "warn"
"useFilenamingConvention": "warn",
"noParameterProperties": "off"
},
"suspicious": {
"noExplicitAny": "off"
@ -21,7 +22,8 @@
}
},
"nursery": {
"noEnum": "off"
"noEnum": "off",
"useConsistentMemberAccessibility": "off"
}
}
},

View File

@ -26,14 +26,15 @@
"scripts": {
"build": "rslib build",
"dev": "rslib build --watch",
"test": "vitest --code-coverage",
"test-ci": "vitest --watch=false --browsers=ChromeHeadlessNoSandbox --code-coverage",
"test": "vitest --browser.headless",
"test-ci": "vitest --watch=false --browser.headless --coverage",
"pack": "npm run build && npm pack ./dist",
"publish": "npm run build && npm publish ./dist",
"coverage": "vitest run --coverage",
"lint": "ultracite lint",
"format": "ultracite format",
"cli": "tsx scripts/cli.ts"
"cli": "tsx scripts/cli.ts",
"test:browser": "vitest --workspace=vitest.workspace.ts"
},
"dependencies": {
"@ngify/http": "^2.0.4",
@ -52,17 +53,21 @@
"@rslib/core": "^0.3.1",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.12.0",
"@vitest/coverage-v8": "^3.0.1",
"@vitest/browser": "^3.0.4",
"@vitest/coverage-v8": "^3.0.4",
"commander": "^13.1.0",
"lodash-es": "^4.17.21",
"oxc-parser": "^0.48.1",
"oxc-walker": "^0.2.2",
"playwright": "^1.50.0",
"rfc4648": "^1.5.0",
"rxjs": "^7.4.0",
"tsx": "^4.19.2",
"typescript": "^5.7.3",
"ultracite": "^4.1.15",
"vitest": "^3.0.1"
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.4",
"webdriverio": "^9.7.2"
},
"keywords": [
"rxjs",

2089
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
import { TestBed } from '@/testing';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { TestBed, mockRouterProvider } from '@/testing';
import { AbstractRouter } from 'oidc-client-rx/router';
import { vi } from 'vitest';
import { StoragePersistenceService } from '../storage/storage-persistence.service';
import { mockProvider } from '../testing/mock';
@ -9,14 +8,18 @@ import { AutoLoginService } from './auto-login.service';
describe('AutoLoginService ', () => {
let autoLoginService: AutoLoginService;
let storagePersistenceService: StoragePersistenceService;
let router: Router;
let router: AbstractRouter;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
providers: [AutoLoginService, mockProvider(StoragePersistenceService)],
imports: [],
providers: [
mockRouterProvider(),
AutoLoginService,
mockProvider(StoragePersistenceService),
],
});
router = TestBed.inject(Router);
router = TestBed.inject(AbstractRouter);
autoLoginService = TestBed.inject(AutoLoginService);
storagePersistenceService = TestBed.inject(StoragePersistenceService);
});

View File

@ -1,6 +1,7 @@
import { inject, Injectable } from 'injection-js';
import { Router } from '@angular/router';
import { Injectable, inject } from 'injection-js';
import type { OpenIdConfiguration } from '../config/openid-configuration';
import { injectAbstractType } from '../injection';
import { AbstractRouter } from '../router';
import { StoragePersistenceService } from '../storage/storage-persistence.service';
const STORAGE_KEY = 'redirect';
@ -9,7 +10,7 @@ const STORAGE_KEY = 'redirect';
export class AutoLoginService {
private readonly storageService = inject(StoragePersistenceService);
private readonly router = inject(Router);
private readonly router = injectAbstractType(AbstractRouter);
checkSavedRedirectRouteAndNavigate(config: OpenIdConfiguration | null): void {
if (!config) {

View File

@ -1,4 +1,3 @@
import { Router } from '@angular/router';
import { Injectable, inject } from 'injection-js';
import { type Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
@ -6,13 +5,15 @@ import type { OpenIdConfiguration } from '../config/openid-configuration';
import type { CallbackContext } from '../flows/callback-context';
import { FlowsDataService } from '../flows/flows-data.service';
import { FlowsService } from '../flows/flows.service';
import { injectAbstractType } from '../injection';
import { AbstractRouter } from '../router';
import { IntervalService } from './interval.service';
@Injectable()
export class CodeFlowCallbackService {
private readonly flowsService = inject(FlowsService);
private readonly router = inject(Router);
private readonly router = injectAbstractType(AbstractRouter);
private readonly flowsDataService = inject(FlowsDataService);

View File

@ -1,4 +1,3 @@
import { Router } from '@angular/router';
import { Injectable, inject } from 'injection-js';
import { type Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
@ -6,13 +5,15 @@ import type { OpenIdConfiguration } from '../config/openid-configuration';
import type { CallbackContext } from '../flows/callback-context';
import { FlowsDataService } from '../flows/flows-data.service';
import { FlowsService } from '../flows/flows.service';
import { injectAbstractType } from '../injection';
import { AbstractRouter } from '../router';
import { IntervalService } from './interval.service';
@Injectable()
export class ImplicitFlowCallbackService {
private readonly flowsService = inject(FlowsService);
private readonly router = inject(Router);
private readonly router = injectAbstractType(AbstractRouter);
private readonly flowsDataService = inject(FlowsDataService);

View File

@ -1,6 +1,6 @@
import { Injectable, inject } from 'injection-js';
import { DOCUMENT } from '../../dom';
import type { OpenIdConfiguration } from '../config/openid-configuration';
import { DOCUMENT } from '../dom';
import { LoggerService } from '../logging/logger.service';
@Injectable()

View File

@ -70,9 +70,8 @@ export class SilentRenewService {
config: OpenIdConfiguration,
allConfigs: OpenIdConfiguration[]
): Observable<CallbackContext> {
const params = new HttpParams({
fromString: urlParts[1],
});
// TODO: fix @ngify/http
const params = new HttpParams(urlParts[1] || undefined);
const errorParam = params.get('error');

View File

@ -1,5 +1,4 @@
import { TestBed } from '@/testing';
import { CommonModule } from '@angular/common';
import { lastValueFrom, of } from 'rxjs';
import { vi } from 'vitest';
import { StoragePersistenceService } from '../storage/storage-persistence.service';
@ -21,7 +20,7 @@ describe('LoginService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [CommonModule],
imports: [],
providers: [
LoginService,
mockProvider(ParLoginService),

View File

@ -1,5 +1,4 @@
import { Injectable, inject } from 'injection-js';
import { toSignal } from 'injection-js/rxjs-interop';
import type { Observable } from 'rxjs';
import { concatMap, map, shareReplay } from 'rxjs/operators';
import type { AuthOptions, LogoutAuthOptions } from './auth-options';
@ -62,14 +61,6 @@ export class OidcSecurityService {
return this.userService.userData$;
}
/**
* Provides information about the user after they have logged in.
*
* @returns Returns an object containing either the user data directly (single config) or
* the user data per config in case you are running with multiple configs
*/
userData = toSignal(this.userData$, { requireSync: true });
/**
* Emits each time an authorization event occurs.
*
@ -83,17 +74,6 @@ export class OidcSecurityService {
return this.authStateService.authenticated$;
}
/**
* Emits each time an authorization event occurs.
*
* @returns Returns an object containing if you are authenticated or not.
* Single Config: true if config is authenticated, false if not.
* Multiple Configs: true is all configs are authenticated, false if only one of them is not
*
* The `allConfigsAuthenticated` property contains the auth information _per config_.
*/
authenticated = toSignal(this.isAuthenticated$, { requireSync: true });
/**
* Emits each time the server sends a CheckSession event and the value changed. This property will always return
* true.

View File

@ -10,22 +10,28 @@ export interface RouterStateSnapshot {
url: string;
}
export abstract class AbstractRouter {
navigateByUrl(_url: string): void {
// TODO
// Implementation of navigating to a URL
}
getCurrentNavigation(): any {
// TODO
// Implementation of getting the current navigation
return null;
}
// TODO
parseUrl(_url: string): any {
// TODO
// Implementation of getting the current navigation
return null;
}
export interface UrlTree {
toString(): string;
}
export interface NavigationExtras {
[key: string]: any;
}
export interface Navigation {
id: number;
initialUrl: UrlTree;
extractedUrl: UrlTree;
finalUrl?: UrlTree | undefined;
trigger: 'imperative' | 'popstate' | 'hashchange';
previousNavigation: Navigation | null;
extras?: NavigationExtras;
}
export abstract class AbstractRouter {
abstract navigateByUrl(url: string): void;
abstract getCurrentNavigation(): Navigation;
abstract parseUrl(_url: string): any;
}

View File

@ -1,8 +1,34 @@
import type { Provider } from 'injection-js';
import { AbstractRouter } from 'oidc-client-rx';
import { AbstractRouter, type Navigation, type UrlTree } from 'oidc-client-rx';
// TODO
export class MockRouter extends AbstractRouter {}
export class MockRouter extends AbstractRouter {
navigation: Navigation = {
id: 1,
extras: {},
initialUrl: new URL('https://localhost/'),
extractedUrl: new URL('https://localhost/'),
trigger: 'imperative',
previousNavigation: null,
};
navigateByUrl(url: string): void {
const prevNavigation = this.navigation;
this.navigation = {
id: prevNavigation.id + 1,
extras: {},
initialUrl: prevNavigation.initialUrl,
extractedUrl: new URL(url),
trigger: prevNavigation.trigger,
previousNavigation: prevNavigation,
};
}
getCurrentNavigation(): Navigation {
return this.navigation;
}
parseUrl(url: string): UrlTree {
return new URL(url);
}
}
export function mockRouterProvider(): Provider {
return {

View File

@ -1,6 +1,5 @@
import { TestBed } from '@/testing';
import { PLATFORM_ID } from '@angular/core';
import { PlatformProvider } from './platform.provider';
import { PLATFORM_ID, PlatformProvider } from './platform.provider';
describe('PlatformProvider Tests', () => {
it('should create', () => {

View File

@ -873,7 +873,8 @@ export class UrlService {
private createHttpParams(existingParams?: string): HttpParams {
existingParams = existingParams ?? '';
return new HttpParams(existingParams, {
// @TODO @ngify/http
return new HttpParams(existingParams || undefined, {
encoder: new UriEncoder(),
});
}

17
vitest.config.ts Normal file
View File

@ -0,0 +1,17 @@
import tsconfigPaths from 'vite-tsconfig-paths';
import { defineConfig } from 'vitest/config';
export default defineConfig({
cacheDir: '.vitest',
test: {
include: ['src/**/*.spec.ts', 'tests-examples'],
globals: true,
browser: {
provider: 'playwright', // or 'webdriverio'
enabled: true,
// at least one instance is required
instances: [{ browser: 'chromium' }],
},
},
plugins: [tsconfigPaths({})],
});