mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 09:01:03 -08:00
feat: add Jest configuration and tests for category content view component
This commit is contained in:
1 parent
02c773170e
commit
eef18dea68
8 files changed
+280
-1
No files matched your search
@@ -0,0 +1,21 @@
|
||||
export default {
|
||||
displayName: 'portal-catalog-feature',
|
||||
preset: '../../../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
coverageDirectory: '../../../../coverage/libs/portal/catalog/feature',
|
||||
transform: {
|
||||
'^.+\\.(ts|mjs|js|html)$': [
|
||||
'jest-preset-angular',
|
||||
{
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||
},
|
||||
],
|
||||
},
|
||||
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment',
|
||||
],
|
||||
};
|
||||
@@ -6,6 +6,14 @@
|
||||
"projectType": "library",
|
||||
"tags": ["scope:portal", "domain:portal-shared", "type:feature"],
|
||||
"targets": {
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "libs/portal/catalog/feature/jest.config.ts",
|
||||
"tsConfig": "libs/portal/catalog/feature/tsconfig.spec.json"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
}
|
||||
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
import { Component, input, output, signal } from '@angular/core';
|
||||
import { NgComponentOutlet } from '@angular/common';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { MatIconButton } from '@angular/material/button';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
||||
import { of } from 'rxjs';
|
||||
import {
|
||||
PORTAL_CATALOG_DETAIL_COMPONENT,
|
||||
PORTAL_CATALOG_FACADE,
|
||||
PortalCatalogSortMode,
|
||||
} from '@iptvnator/portal/shared/util';
|
||||
import { CategoryContentViewComponent } from './category-content-view.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-grid-list',
|
||||
standalone: true,
|
||||
template: '',
|
||||
})
|
||||
class MockGridListComponent {
|
||||
readonly isLoading = input<boolean>();
|
||||
readonly items = input<unknown[]>();
|
||||
readonly pageIndex = input<number>();
|
||||
readonly totalPages = input<number>();
|
||||
readonly limit = input<number>();
|
||||
readonly pageSizeOptions = input<number[]>();
|
||||
readonly showPaginator = input(true);
|
||||
readonly itemClicked = output<unknown>();
|
||||
readonly pageChange = output<unknown>();
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-playlist-error-view',
|
||||
standalone: true,
|
||||
template: '',
|
||||
})
|
||||
class MockPlaylistErrorViewComponent {
|
||||
readonly title = input('');
|
||||
readonly description = input('');
|
||||
readonly showActionButtons = input(true);
|
||||
readonly viewType = input('');
|
||||
}
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
template: '',
|
||||
})
|
||||
class MockDetailComponent {}
|
||||
|
||||
describe('CategoryContentViewComponent', () => {
|
||||
let fixture: ComponentFixture<CategoryContentViewComponent>;
|
||||
const isPaginatedContentLoading = signal(true);
|
||||
const categoryItemCount = signal(0);
|
||||
const contentSortMode = signal<PortalCatalogSortMode | null>(null);
|
||||
const catalog = {
|
||||
provider: 'xtream' as const,
|
||||
pageSizeOptions: [10, 25, 50],
|
||||
contentType: signal('vod'),
|
||||
limit: signal(25),
|
||||
pageIndex: signal(0),
|
||||
selectedCategory: signal({ id: 1 }),
|
||||
paginatedContent: signal<unknown[]>([]),
|
||||
selectedCategoryTitle: signal('Movies'),
|
||||
categoryItemCount,
|
||||
selectedItem: signal(null),
|
||||
totalPages: signal(0),
|
||||
contentSortMode,
|
||||
playlist: signal(null),
|
||||
isPaginatedContentLoading,
|
||||
initialize: jest.fn(),
|
||||
clearSelectedItem: jest.fn(),
|
||||
setPage: jest.fn(),
|
||||
setLimit: jest.fn(),
|
||||
setContentSortMode: jest.fn(),
|
||||
selectItem: jest.fn().mockReturnValue(null),
|
||||
getItemProgress: jest.fn().mockReturnValue({}),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
isPaginatedContentLoading.set(true);
|
||||
categoryItemCount.set(0);
|
||||
contentSortMode.set(null);
|
||||
catalog.initialize.mockClear();
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [CategoryContentViewComponent, NoopAnimationsModule],
|
||||
providers: [
|
||||
{
|
||||
provide: TranslateService,
|
||||
useValue: {
|
||||
instant: (key: string) =>
|
||||
key === 'WORKSPACE.SHELL.XTREAM_IMPORT_LOADING'
|
||||
? 'Fetching playlist data from source...'
|
||||
: key,
|
||||
get: (key: string) =>
|
||||
of(
|
||||
key === 'WORKSPACE.SHELL.XTREAM_IMPORT_LOADING'
|
||||
? 'Fetching playlist data from source...'
|
||||
: key
|
||||
),
|
||||
stream: (key: string) =>
|
||||
of(
|
||||
key === 'WORKSPACE.SHELL.XTREAM_IMPORT_LOADING'
|
||||
? 'Fetching playlist data from source...'
|
||||
: key
|
||||
),
|
||||
onLangChange: of(null),
|
||||
onTranslationChange: of(null),
|
||||
onDefaultLangChange: of(null),
|
||||
currentLang: 'en',
|
||||
defaultLang: 'en',
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: PORTAL_CATALOG_FACADE,
|
||||
useValue: catalog,
|
||||
},
|
||||
{
|
||||
provide: PORTAL_CATALOG_DETAIL_COMPONENT,
|
||||
useValue: MockDetailComponent,
|
||||
},
|
||||
{
|
||||
provide: ActivatedRoute,
|
||||
useValue: {
|
||||
snapshot: {
|
||||
params: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: Router,
|
||||
useValue: {
|
||||
navigate: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
.overrideComponent(CategoryContentViewComponent, {
|
||||
set: {
|
||||
imports: [
|
||||
NgComponentOutlet,
|
||||
MockGridListComponent,
|
||||
MockPlaylistErrorViewComponent,
|
||||
MatIcon,
|
||||
MatIconButton,
|
||||
MatMenuModule,
|
||||
MatPaginatorModule,
|
||||
MatTooltip,
|
||||
TranslatePipe,
|
||||
],
|
||||
},
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(CategoryContentViewComponent);
|
||||
});
|
||||
|
||||
it('shows loading copy in the subtitle instead of 0 items while xtream content is still warming up', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const subtitle = fixture.nativeElement.querySelector(
|
||||
'.category-subtitle'
|
||||
) as HTMLElement | null;
|
||||
|
||||
expect(catalog.initialize).toHaveBeenCalledWith(null);
|
||||
expect(subtitle?.textContent?.trim()).toBe(
|
||||
'Fetching playlist data from source...'
|
||||
);
|
||||
});
|
||||
});
|
||||
+13
-1
@@ -6,7 +6,7 @@ import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatPaginatorModule, PageEvent } from '@angular/material/paginator';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
||||
import {
|
||||
GridListComponent,
|
||||
PlaylistErrorViewComponent,
|
||||
@@ -50,6 +50,7 @@ interface CategoryContentItem {
|
||||
export class CategoryContentViewComponent implements OnInit {
|
||||
private readonly activatedRoute = inject(ActivatedRoute);
|
||||
private readonly router = inject(Router);
|
||||
private readonly translate = inject(TranslateService);
|
||||
private readonly catalog = inject(PORTAL_CATALOG_FACADE) as PortalCatalogFacade<
|
||||
CategoryContentItem,
|
||||
CategoryContentItem,
|
||||
@@ -70,7 +71,18 @@ export class CategoryContentViewComponent implements OnInit {
|
||||
readonly contentSortMode = this.catalog.contentSortMode;
|
||||
readonly isPaginatedContentLoading =
|
||||
this.catalog.isPaginatedContentLoading;
|
||||
readonly isXtreamLoadingSubtitle = computed(
|
||||
() =>
|
||||
this.catalog.provider === 'xtream' &&
|
||||
this.isPaginatedContentLoading()
|
||||
);
|
||||
readonly categoryItemSubtitle = computed(() => {
|
||||
if (this.isXtreamLoadingSubtitle()) {
|
||||
return this.translate.instant(
|
||||
'WORKSPACE.SHELL.XTREAM_IMPORT_LOADING'
|
||||
);
|
||||
}
|
||||
|
||||
const itemCount = this.categoryItemCount();
|
||||
return `${itemCount} ${itemCount === 1 ? 'item' : 'items'}`;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
|
||||
|
||||
setupZoneTestEnv({
|
||||
errorOnUnknownElements: true,
|
||||
errorOnUnknownProperties: true,
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"isolatedModules": true,
|
||||
"target": "es2022",
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"emitDecoratorMetadata": false,
|
||||
"module": "preserve"
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": []
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"target": "es2016",
|
||||
"types": ["jest", "node"],
|
||||
"moduleResolution": "node10"
|
||||
},
|
||||
"files": ["src/test-setup.ts"],
|
||||
"include": [
|
||||
"jest.config.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user