jeudi 11 juin 2020

AngularTesting Fails when adding Router provider

I have a Header Component that is called on the main component, this is because I have a *ngIf to check in which route I'am and render the header differently. The code is working fine and the header renders differently depending where I'am on the app.

I'am trying to test the header depending on which route I'am. The previous tests pass if i dont touch the code, but when i add the Router Provider, all tests fails.

Just by adding the provider all test faills, I don't even need to add my new test.

What might be the cause?

import {async, ComponentFixture, TestBed} from "@angular/core/testing";
import {DatasetMainComponent} from "./dataset-main.component";
import {DatasetHeaderComponent} from "../dataset-header/dataset-header.component";
import {DatasetNavigationComponent} from "../dataset-navigation/dataset-navigation.component";
import {CustomMaterialModule} from "../../shared/customMaterial.module";
import {ActivatedRoute, Router} from "@angular/router";
import {ActivatedRouteStub} from "../../testing/activatedRouteStub";
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
import {RouterTestingModule} from "@angular/router/testing";
import {DatasetVersionService} from "../services/datasetVersion.service.interface";
import {MockDatasetServiceImpl} from "../utils/commonData.spec";
import {HttpClientModule} from "@angular/common/http";
import {Directive, Input, LOCALE_ID} from "@angular/core";
import {MatExpansionPanel} from "@angular/material/expansion";
import {By} from "@angular/platform-browser";
import {ErrorHandlingStubComponent} from "../../testing/error-handling-stub";
import {MatMenuItem} from "@angular/material/menu";
import {MetadataService} from "../../common-metadata/services/metadata.service.interface";
import {MockMetadataImplService} from "../../shared-study-metadata/utils/common-data.spec";
import {AppModule} from "../../app.module";
import {of} from "rxjs";
import {SharedModule} from "../../shared/shared.module";
import {PermissionDirective} from "../../core/utils/permission.directive";
import {ButtonComponent} from "../../shared/components";
import {RouterStub} from "../../testing/routerStub";
import {AuthorizationService, AuthService} from "../../core/services";
import {AuthImplService} from "../../core/services/authImpl.service";
import {MockAuthorizationService} from "../../core/specs/commonData.spec";

const activatedRoute = new ActivatedRouteStub();

@Directive({selector: "[appPermissions]"})
export class StubPermissionDirective {
    @Input() permissions: any[];
}

fdescribe("DatasetMainComponent", () => {
    let component: DatasetMainComponent;
    let componentFixture: ComponentFixture<DatasetMainComponent>;
    let element: any;
    let debugElement: any;
    let datasetVersionService: MockDatasetServiceImpl;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                DatasetMainComponent,
                DatasetHeaderComponent,
                DatasetNavigationComponent,
                ErrorHandlingStubComponent,
                StubPermissionDirective,
            ],
            imports: [
                AppModule,
                SharedModule,
                CustomMaterialModule,
                BrowserAnimationsModule,
                RouterTestingModule,
                HttpClientModule
            ],
            providers: [
                {provide: ActivatedRoute, useValue: activatedRoute},
                {provide: DatasetVersionService, useClass: MockDatasetServiceImpl},
                {provide: MetadataService, useClass: MockMetadataImplService},
                {provide: Router, useClass: RouterStub},
                {provide: AuthService, useClass: AuthImplService},
                {provide: AuthorizationService, useClass: MockAuthorizationService},
                {provide: LOCALE_ID, useValue: "en"},
            ]
        }).overrideModule(SharedModule, {
            remove: {
                exports: [PermissionDirective]
            }
        }).compileComponents().then(() => {
            activatedRoute.setParamMap({datasetVersionId: "1", datasetRefNumber: "1"});
            componentFixture = TestBed.createComponent(DatasetMainComponent);
            component = componentFixture.componentInstance;
            element = componentFixture.nativeElement;
            debugElement = componentFixture.debugElement;
        });

        datasetVersionService = TestBed.get(DatasetVersionService);
    }));

    it("Delete a dataset works", () => {
        componentFixture.detectChanges();
        spyOn(datasetVersionService, "deleteDatasetVersion").and.callThrough();
        spyOn(component.dialogController, "openSimpleDialog").and.returnValue(of(true));
        spyOn(component, "deleteDatasetVersion").and.callThrough();

        // Confirm deletion on DialogControllerStubComponent
        const buttons  = element.getElementsByTagName("button");
        buttons[2].click();
        componentFixture.detectChanges();

        // const menuItems = debugElement.queryAll(By.directive(MatMenuItem));
        const menuItems = debugElement.queryAll(By.directive(ButtonComponent));
        expect(menuItems.length).toBe(4);
        expect(menuItems[3].nativeElement.innerText).toBe("Delete");
        // Use component instance to get isDisabled property
        expect(menuItems[3].componentInstance.isDisabled).toBe(false);
        // app-button wraps a button with click function that triggers the event 'onclick'
        menuItems[3].query(By.css("button")).nativeElement.click();
        componentFixture.detectChanges();

        expect(component.deleteDatasetVersion).toHaveBeenCalled();
        expect(datasetVersionService.deleteDatasetVersion).toHaveBeenCalledWith(1);
    });

    it("navigation menu is shown correctly", () => {
        componentFixture.detectChanges();
        const panels = componentFixture.debugElement.queryAll(By.directive(MatExpansionPanel));
        expect(panels.length).toBe(2);  // Files is not a panel
        panels[0].triggerEventHandler("open", null);
        const links = element.getElementsByTagName("a");
        expect(links.length).toBe(7);  // Files is a link
        expect(links[0].innerText).toBe("Description");
        expect(links[1].innerText).toBe("Archiving");
        expect(links[2].innerText).toBe("Block 1 en");
        expect(links[3].innerText).toBe("Block 2 en");
        expect(links[4].innerText).toBe("Files");
        expect(links[5].innerText).toBe("Deposit contract");
        expect(links[6].innerText).toBe("User contract");
    });
    it("Update a dataset version works", () => {
        componentFixture.detectChanges();
        spyOn(component.dialogController, "openSimpleDialog").and.returnValue(of(true));
        spyOn(datasetVersionService, "updatePublishedDatasetVersion").and.callThrough();
        const buttons  = element.getElementsByTagName("button");
        buttons[1].click();
        componentFixture.detectChanges();
        expect(datasetVersionService.updatePublishedDatasetVersion).toHaveBeenCalledWith(1);
    });

    it("Only displays Title and ref on Catalogue Route", () => {
      const router = TestBed.get(Router);
      router.url = "/catalogue";
      componentFixture.detectChanges();
      const title = element.getElementsByTagName("sub-title-wrapper");
      console.log(title);
});
});

The last test is my new test that I want to check if something being rendered inside the wrapper, but I can't even see the log because of the following error:

  TypeError: Cannot read property 'subscribe' of undefined

This error appears in all tests as soon as I add this:

  {provide: Router, useClass: RouterStub},

Aucun commentaire:

Enregistrer un commentaire