ohayolibs
Version:
Ohayo is a set of essential modules for ohayojp.
176 lines (163 loc) • 6.07 kB
text/typescript
import { APP_BASE_HREF, DOCUMENT } from '@angular/common';
import { Component, CUSTOM_ELEMENTS_SCHEMA, DebugElement, ViewChild } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { ActivationEnd, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { BehaviorSubject } from 'rxjs';
import { FullContentComponent } from './full-content.component';
import { FullContentModule } from './full-content.module';
import { FullContentService } from './full-content.service';
describe('components: full-content', () => {
let fixture: ComponentFixture<TestComponent>;
let dl: DebugElement;
let context: TestComponent;
let doc: Document;
let el: HTMLElement;
let bodyEl: HTMLBodyElement;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [FullContentModule, RouterTestingModule.withRoutes([])],
declarations: [TestComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }],
});
});
function createComp(): void {
fixture = TestBed.createComponent(TestComponent);
dl = fixture.debugElement;
context = fixture.componentInstance;
fixture.detectChanges();
doc = TestBed.inject(DOCUMENT);
bodyEl = document.querySelector('body') as HTMLBodyElement;
el = dl.query(By.css('full-content')).nativeElement as HTMLElement;
}
afterEach(() => context && context.comp && context.comp.ngOnDestroy());
describe('#fullscreen', () => {
beforeEach(() => createComp());
it('with true', () => {
context.fullscreen = true;
fixture.detectChanges();
expect(doc.body.classList.contains('full-content__opened')).toBe(true);
});
it('with false', () => {
context.fullscreen = false;
fixture.detectChanges();
expect(doc.body.classList.contains('full-content__opened')).toBe(false);
});
});
describe('#hideTitle', () => {
beforeEach(() => createComp());
describe('#with [true]', () => {
beforeEach(() => (context.hideTitle = true));
it('when fullscreen', () => {
context.fullscreen = true;
fixture.detectChanges();
expect(doc.body.classList.contains('full-content__hidden-title')).toBe(true);
});
it('when not fullscreen', () => {
context.fullscreen = false;
fixture.detectChanges();
expect(doc.body.classList.contains('full-content__hidden-title')).toBe(false);
});
});
describe('#with [false]', () => {
beforeEach(() => (context.hideTitle = false));
it('when fullscreen', () => {
context.fullscreen = true;
fixture.detectChanges();
expect(doc.body.classList.contains('full-content__hidden-title')).toBe(false);
});
it('when not fullscreen', () => {
context.fullscreen = false;
fixture.detectChanges();
expect(doc.body.classList.contains('full-content__hidden-title')).toBe(false);
});
});
});
describe('logic', () => {
it('should be switch fullscreen via directive', () => {
createComp();
expect(context.fullscreen).toBe(false);
(dl.query(By.css('button')).nativeElement as HTMLButtonElement).click();
fixture.detectChanges();
expect(context.fullscreen).toBe(true);
(dl.query(By.css('button')).nativeElement as HTMLButtonElement).click();
fixture.detectChanges();
expect(context.fullscreen).toBe(false);
});
it('should be switch fullscreen via service', () => {
createComp();
const srv = TestBed.inject(FullContentService);
expect(context.fullscreen).toBe(false);
srv.toggle();
fixture.detectChanges();
expect(context.fullscreen).toBe(true);
srv.toggle();
fixture.detectChanges();
expect(context.fullscreen).toBe(false);
});
it('should be recalculate height when trigger resize', fakeAsync(() => {
createComp();
const bodyHeight = 10;
spyOn(bodyEl, 'getBoundingClientRect').and.returnValue({
height: bodyHeight,
} as any);
expect(bodyEl.getBoundingClientRect).not.toHaveBeenCalled();
window.dispatchEvent(new Event('resize'));
fixture.detectChanges();
tick(210);
expect(bodyEl.getBoundingClientRect).toHaveBeenCalled();
expect(context.comp._height).toBe(bodyHeight - el.getBoundingClientRect().top - context.padding);
}));
it('should be clear class when go to other route', () => {
const eventsSub = new BehaviorSubject<any>(null);
class MockRouter {
events = eventsSub;
}
TestBed.overrideProvider(Router, {
useFactory: () => {
return new MockRouter();
},
deps: [],
});
createComp();
// mock component destroy
(dl.nativeElement as HTMLElement).innerHTML = ``;
eventsSub.next(new ActivationEnd(null!));
eventsSub.complete();
expect(bodyEl.classList.contains('full-content')).toBe(false);
});
it('should be attach class when back route', () => {
const eventsSub = new BehaviorSubject<any>(null);
class MockRouter {
events = eventsSub;
}
TestBed.overrideProvider(Router, {
useFactory: () => {
return new MockRouter();
},
deps: [],
});
createComp();
bodyEl.classList.remove('full-content__body');
eventsSub.next(new ActivationEnd(null!));
eventsSub.complete();
expect(bodyEl.classList.contains('full-content__body')).toBe(true);
});
});
});
({
template: `
<full-content #comp [(fullscreen)]="fullscreen" [hideTitle]="hideTitle" [padding]="padding" (fullscreenChange)="change()">
<button full-toggle>Full</button>
</full-content>
`,
})
class TestComponent {
('comp', { static: true }) comp: FullContentComponent;
fullscreen: boolean = false;
hideTitle: boolean;
padding = 24;
change(): void { }
}