Как проверить окно: popstate в angular 8? - PullRequest
1 голос
/ 24 февраля 2020

Я пытаюсь проверить следующий метод, и я не могу go дальше, чем эти ошибки:

  1. Ошибка AfterAll: Uncaught (в обещании) : TypeError: Невозможно прочитать свойство 'result' неопределенного типа. TypeError: Невозможно прочитать свойство 'result' неопределенного значения в результате

  2. 'ERROR', TypeError: this.modalService .dismissAll не является функцией TypeError: this.modalService.dismissAll не является функцией

Компонент:

@HostListener('window:popstate')
  onPopState() {
    this.router.navigate(['stoebern']);
    this.modalService.dismissAll();
  }

Это то, что я пробовал до сейчас:

class MockModalService {
  dismissAll(): void {}
}

 beforeEach(() => {
    component = fixture.componentInstance;
    fixture.detectChanges();
    mockModalService = TestBed.get(ModalService as Type<ModalService>);
    spyOn(mockModalService, 'dismissAll').and.callThrough();
  });

 it('should do something on window popstate', () => {
    window.dispatchEvent(new Event('popstate'));
    expect(router.navigate).toHaveBeenCalledWith(['stoebern']);
    expect(mockModalService.dismissAll).toHaveBeenCalled();
  });

У вас есть идеи, откуда появляются эти ошибки?

1 Ответ

0 голосов
/ 24 февраля 2020

@ PierreDu c

Вот тестовый файл:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {
  AuthService,
  CmsService,
  ConfigurableRoutesService,
  defaultOccConfig,
  OccConfig,
  Page,
  RoutingService,
  UserToken
} from '@spartacus/core';
import { StoreModule } from '@ngrx/store';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ReactiveFormsModule } from '@angular/forms';
import { AokCuContentBlockerPopupComponent } from './aok-cu-content-blocker-popup.component';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { Renderer2, Type } from '@angular/core';
import { AokCuLoginPopupWindowService } from '@aok-core';
import { EffectsModule } from '@ngrx/effects';
import { ModalService } from '@spartacus/storefront';
import createSpy = jasmine.createSpy;

class MockModalService {
  dismissAll(): void {}
}


describe('AokCuContentBlockerPopupComponent', () => {
  let component: AokCuContentBlockerPopupComponent;
  let fixture: ComponentFixture<AokCuContentBlockerPopupComponent>;
  // let service: AokCuLoginPopupWindowService;
  // let modalService: NgbModal;
  let mockModalService: MockModalService;

  let router = {
    navigate: jasmine.createSpy('navigate')
  };


  class MockActivatedRoute {
    params = of({
      url: '/courses'
    });
  }

  class MockCmsService {
    static getCurrentPage(): Observable<Page> {
      return of();
    }
    refreshLatestPage() {}
    refreshComponent() {}
  }

  class MockConfigurableRoutesService {
    init() {}
    translateRouterConfig() {}
  }

  class MockAuthService {
    authorize = createSpy();

    getUserToken(): Observable<UserToken> {
      return of({ access_token: 'test' } as UserToken);
    }
  }

  class MockRoutingService {
    static isNavigating(): Observable<boolean> {
      return of();
    }
  }

  const mockNgbModal = {
    open: () => {}
  };

  const mockRenderer2 = {
    addClass: () => {},
    removeClass: () => {}
  };

  const mockAokCuLoginPopupWindowService = {
    private: '/test',
    width: '940',
    height: '640'
  };

  // const mockModalOptions = {
  //   centered: true,
  //   windowClass: 'regular-modal regular-modal--regular-mobile',
  //   backdropClass: 'backdrop--transparent',
  //   backdrop: 'static',
  //   keyboard: false
  // };

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        EffectsModule.forRoot([]),
        StoreModule.forRoot(
          {},
          {
            runtimeChecks: {
              strictStateImmutability: true,
              strictActionImmutability: true
            }
          }
        ),
        RouterTestingModule.withRoutes([
          {
            path: 'aok-cu-content-blocker-popup',
            component: AokCuContentBlockerPopupComponent
          }
        ]),
        HttpClientTestingModule,
        ReactiveFormsModule
      ],
      declarations: [AokCuContentBlockerPopupComponent],
      providers: [
        {
          provide: ConfigurableRoutesService,
          useClass: MockConfigurableRoutesService
        },
        {
          provide: NgbModal,
          useValue: mockNgbModal
        },
        {
          provide: Renderer2,
          useValue: mockRenderer2
        },
        {
          provide: AokCuLoginPopupWindowService,
          useValue: mockAokCuLoginPopupWindowService
        },
        { provide: ActivatedRoute, useClass: MockActivatedRoute },
        { provide: OccConfig, useValue: defaultOccConfig },
        { provide: CmsService, useClass: MockCmsService },
        {
          provide: ConfigurableRoutesService,
          useClass: MockConfigurableRoutesService
        },
        {
          provide: RoutingService,
          useClass: MockRoutingService
        },
        {
          provide: AuthService,
          useClass: MockAuthService
        },
        {
          provide: Router,
          useValue: router
        },
        {
          provide: ModalService,
          useClass: MockModalService,
        },
      ]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AokCuContentBlockerPopupComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    mockModalService = TestBed.get(ModalService as Type<ModalService>);
    spyOn(mockModalService, 'dismissAll').and.callThrough();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should do something on window popstate', () => {
    window.dispatchEvent(new Event('popstate'));
    expect(router.navigate).toHaveBeenCalledWith(['stoebern']);
    expect(mockModalService.dismissAll).toHaveBeenCalled();
  });

  it('should router to stoebern page onPopState event', () => {
    const event = new PopStateEvent('popstate', {
      state: {foo: 'bar'}
    });

    spyOn(window, 'addEventListener').and.callThrough();
    spyOn(component, 'onPopState');
    component.onPopState();
    window.dispatchEvent(event);
    expect(component.onPopState).toHaveBeenCalled();
    expect(router.navigate).toHaveBeenCalledWith(['stoebern']);
  });
});

А вот машинный текст компонента:

import {
  AfterViewInit,
  Component,
  ElementRef,
  HostListener,
  Inject,
  Renderer2,
  ViewChild
} from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { AuthService, RoutingService } from '@spartacus/core';
import { DOCUMENT } from '@angular/common';
import { Router } from '@angular/router';
import { AokCuLoginPopupWindowService } from '@aok-core';

@Component({
  selector: 'aok-cu-content-blocker-popup',
  templateUrl: './aok-cu-content-blocker-popup.component.html'
})
export class AokCuContentBlockerPopupComponent implements AfterViewInit {
  redirectUrl: string;
  code: string;
  popup;

  @ViewChild('modal', { static: false }) modal: ElementRef;

  private onLoginSuccess;
  private onLoginAbort;

  constructor(
    private readonly modalService: NgbModal,
    private readonly renderer: Renderer2,
    private readonly loginPopupWindowService: AokCuLoginPopupWindowService,
    private readonly authService: AuthService,
    private readonly routingService: RoutingService,
    protected readonly router: Router,
    @Inject(DOCUMENT) private readonly document: any
  ) {}

  ngAfterViewInit() {
    this.router.navigate(['stoebern']);
    Promise.resolve(null).then(() => {
      const modalClass = 'blurry-overlay';
      this.renderer.addClass(this.document.body, modalClass);
      const modal = this.modalService.open(this.modal, {
        centered: true,
        windowClass: 'regular-modal regular-modal--regular-mobile',
        backdropClass: 'backdrop--transparent',
        backdrop: 'static',
        keyboard: false
      });
      modal.result.then(
        () => {},
        () => {
          this.renderer.removeClass(this.document.body, modalClass);
        }
      );

      this.onLoginSuccess = newUserToken => {
        this.authService.authorizeWithToken(newUserToken);
        if (this.redirectUrl) {
          this.routingService.go([this.redirectUrl]);
        }
        this.modalService.dismissAll();
      };
      this.onLoginAbort = () => {};
    });
  }

  @HostListener('window:popstate')
  onPopState() {
    this.router.navigate(['stoebern']);
    this.modalService.dismissAll();
  }

  login() {
    this.loginPopupWindowService.open(this.onLoginSuccess, this.onLoginAbort);
  }
}
...