-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added truncation to project description cards * Added descriptionHtml to models * Added description input explanation * Fix card component unit tests * Fix home component unit tests * Fixed remaining tests * Fix description styling * Added stripHtml tests Forced all fake models to use a Required version of their interface. This will help track down any changes to the model without associated updates to the generator. * Updated model type definitions * Simplified fake model generators * Removed stripHtml Co-authored-by: Anthony Truskinger <[email protected]>
- Loading branch information
1 parent
7a51095
commit 5b52392
Showing
58 changed files
with
575 additions
and
494 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,219 +1,173 @@ | ||
import { | ||
HttpClientTestingModule, | ||
HttpTestingController, | ||
} from "@angular/common/http/testing"; | ||
import { ComponentFixture, TestBed } from "@angular/core/testing"; | ||
import { RouterTestingModule } from "@angular/router/testing"; | ||
import { ApiErrorDetails } from "@baw-api/api.interceptor.service"; | ||
import { Filters } from "@baw-api/baw-api.service"; | ||
import { MockBawApiModule } from "@baw-api/baw-apiMock.module"; | ||
import { ProjectsService } from "@baw-api/project/projects.service"; | ||
import { SecurityService } from "@baw-api/security/security.service"; | ||
import { Project } from "@models/Project"; | ||
import { SpyObject } from "@ngneat/spectator"; | ||
import { | ||
createComponentFactory, | ||
Spectator, | ||
SpyObject, | ||
} from "@ngneat/spectator"; | ||
import { AppConfigService } from "@services/app-config/app-config.service"; | ||
import { cmsRoot } from "@services/app-config/app-config.service.spec"; | ||
import { SharedModule } from "@shared/shared.module"; | ||
import { CardImageComponent } from "@shared/cards/card-image/card-image.component"; | ||
import { CardsComponent } from "@shared/cards/cards.component"; | ||
import { CmsComponent } from "@shared/cms/cms.component"; | ||
import { generateApiErrorDetails } from "@test/fakes/ApiErrorDetails"; | ||
import { generateProject } from "@test/fakes/Project"; | ||
import { nStepObservable } from "@test/helpers/general"; | ||
import { assertRoute } from "@test/helpers/html"; | ||
import { MockComponent } from "ng-mocks"; | ||
import { Subject } from "rxjs"; | ||
import { HomeComponent } from "./home.component"; | ||
|
||
describe("HomeComponent", () => { | ||
let httpMock: HttpTestingController; | ||
let projectApi: SpyObject<ProjectsService>; | ||
let securityApi: SecurityService; | ||
let component: HomeComponent; | ||
let env: AppConfigService; | ||
let fixture: ComponentFixture<HomeComponent>; | ||
let cmsUrl: string; | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [HomeComponent], | ||
imports: [ | ||
SharedModule, | ||
HttpClientTestingModule, | ||
RouterTestingModule, | ||
MockBawApiModule, | ||
], | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(HomeComponent); | ||
component = fixture.componentInstance; | ||
httpMock = TestBed.inject(HttpTestingController); | ||
projectApi = TestBed.inject(ProjectsService) as SpyObject<ProjectsService>; | ||
securityApi = TestBed.inject(SecurityService); | ||
env = TestBed.inject(AppConfigService); | ||
|
||
cmsUrl = `${cmsRoot}/home.html`; | ||
let config: AppConfigService; | ||
let spectator: Spectator<HomeComponent>; | ||
const createComponent = createComponentFactory({ | ||
component: HomeComponent, | ||
declarations: [ | ||
CardsComponent, | ||
MockComponent(CardImageComponent), | ||
MockComponent(CmsComponent), | ||
], | ||
imports: [RouterTestingModule, MockBawApiModule], | ||
}); | ||
|
||
afterEach(() => { | ||
httpMock.verify(); | ||
}); | ||
async function interceptProjects( | ||
projects: Project[] = [], | ||
error?: ApiErrorDetails | ||
) { | ||
const subject = new Subject<Project[]>(); | ||
const promise = nStepObservable( | ||
subject, | ||
() => (error ? error : projects), | ||
!projects | ||
); | ||
projectApi.filter.and.callFake(() => subject); | ||
spectator.detectChanges(); | ||
await promise; | ||
spectator.detectChanges(); | ||
} | ||
|
||
function interceptCmsRequest() { | ||
const req = httpMock.expectOne(cmsUrl); | ||
req.flush("<h1>Test Header</h1><p>Test Description</p>"); | ||
function getCardImages() { | ||
return spectator.queryAll(CardImageComponent); | ||
} | ||
|
||
it("should load cms", async () => { | ||
const subject = new Subject<Project[]>(); | ||
const promise = nStepObservable(subject, () => []); | ||
projectApi.filter.and.callFake(() => subject); | ||
function getButton() { | ||
return spectator.query<HTMLButtonElement>("button"); | ||
} | ||
|
||
await promise; | ||
fixture.detectChanges(); | ||
interceptCmsRequest(); | ||
fixture.detectChanges(); | ||
beforeEach(() => { | ||
spectator = createComponent({ detectChanges: false }); | ||
|
||
const header = fixture.nativeElement.querySelector("h1"); | ||
const body = fixture.nativeElement.querySelector("p"); | ||
projectApi = spectator.inject(ProjectsService); | ||
securityApi = spectator.inject(SecurityService); | ||
config = spectator.inject(AppConfigService); | ||
}); | ||
|
||
expect(header).toBeTruthy(); | ||
expect(header.innerText.trim()).toBe("Test Header"); | ||
expect(body).toBeTruthy(); | ||
expect(body.innerText.trim()).toBe("Test Description"); | ||
it("should load cms", async () => { | ||
await interceptProjects(); | ||
const cms = spectator.query(CmsComponent); | ||
expect(cms.page).toBe("/home.html"); | ||
}); | ||
|
||
describe("page", () => { | ||
async function setupComponent( | ||
projects: Project[], | ||
error?: ApiErrorDetails | ||
) { | ||
const subject = new Subject<Project[]>(); | ||
const promise = nStepObservable( | ||
subject, | ||
() => (projects ? projects : error), | ||
!projects | ||
); | ||
projectApi.filter.and.callFake(() => subject); | ||
|
||
fixture.detectChanges(); | ||
await promise; | ||
interceptCmsRequest(); | ||
fixture.detectChanges(); | ||
} | ||
|
||
function getCardImages() { | ||
return fixture.nativeElement.querySelectorAll("baw-card-image"); | ||
} | ||
|
||
function getCardTitle(card: HTMLElement): HTMLElement { | ||
return card.querySelector(".card-title"); | ||
} | ||
|
||
function getCardText(card: HTMLElement): HTMLElement { | ||
return card.querySelector(".card-text"); | ||
} | ||
|
||
function getButton() { | ||
return fixture.nativeElement.querySelector("button"); | ||
} | ||
|
||
it("should create", async () => { | ||
await setupComponent([]); | ||
expect(component).toBeTruthy(); | ||
}); | ||
it("should create", async () => { | ||
await interceptProjects(); | ||
expect(spectator.component).toBeTruthy(); | ||
}); | ||
|
||
it("should request 3 projects", async () => { | ||
await setupComponent([]); | ||
expect(projectApi.filter).toHaveBeenCalledWith({ | ||
paging: { items: 3 }, | ||
} as Filters); | ||
}); | ||
it("should request 3 projects", async () => { | ||
await interceptProjects(); | ||
expect(projectApi.filter).toHaveBeenCalledWith({ | ||
paging: { items: 3 }, | ||
} as Filters); | ||
}); | ||
|
||
it("should handle filter error", async () => { | ||
await setupComponent(undefined, generateApiErrorDetails()); | ||
expect(getCardImages().length).toBe(0); | ||
expect(getButton()).toBeTruthy(); | ||
}); | ||
it("should handle filter error", async () => { | ||
await interceptProjects(undefined, generateApiErrorDetails()); | ||
expect(getCardImages().length).toBe(0); | ||
expect(getButton()).toBeTruthy(); | ||
}); | ||
|
||
it("should display no projects", async () => { | ||
await setupComponent([]); | ||
expect(getCardImages().length).toBe(0); | ||
expect(getButton()).toBeTruthy(); | ||
}); | ||
it("should display no projects", async () => { | ||
await interceptProjects([]); | ||
expect(getCardImages().length).toBe(0); | ||
expect(getButton()).toBeTruthy(); | ||
}); | ||
|
||
it("should display single project", async () => { | ||
await setupComponent([new Project(generateProject())]); | ||
it("should display single project", async () => { | ||
await interceptProjects([new Project(generateProject())]); | ||
expect(getCardImages().length).toBe(1); | ||
expect(getButton()).toBeTruthy(); | ||
}); | ||
|
||
const cards = getCardImages(); | ||
expect(cards.length).toBe(1); | ||
expect(getButton()).toBeTruthy(); | ||
}); | ||
it("should display project name", async () => { | ||
await interceptProjects([ | ||
new Project({ ...generateProject(), name: "Project" }), | ||
]); | ||
|
||
it("should display project name", async () => { | ||
await setupComponent([ | ||
new Project({ ...generateProject(), name: "Project" }), | ||
]); | ||
const cards = getCardImages(); | ||
expect(cards[0].card.title).toBe("Project"); | ||
}); | ||
|
||
const cards = getCardImages(); | ||
expect(getCardTitle(cards[0]).innerText.trim()).toBe("Project"); | ||
}); | ||
it("should display description", async () => { | ||
await interceptProjects([ | ||
new Project({ | ||
...generateProject(), | ||
descriptionHtmlTagline: "Description", | ||
}), | ||
]); | ||
|
||
it("should display description", async () => { | ||
await setupComponent([ | ||
new Project({ | ||
...generateProject(), | ||
description: "Description", | ||
}), | ||
]); | ||
const cards = getCardImages(); | ||
expect(cards[0].card.description).toBe("Description"); | ||
}); | ||
|
||
const cards = getCardImages(); | ||
expect(getCardText(cards[0]).innerText.trim()).toBe("Description"); | ||
}); | ||
it("should display missing description", async () => { | ||
await interceptProjects([ | ||
new Project({ | ||
...generateProject(), | ||
descriptionHtmlTagline: undefined, | ||
}), | ||
]); | ||
|
||
it("should display missing description", async () => { | ||
await setupComponent([ | ||
new Project({ | ||
...generateProject(), | ||
description: undefined, | ||
}), | ||
]); | ||
|
||
const cards = getCardImages(); | ||
expect(getCardText(cards[0]).innerText.trim()).toBe( | ||
"No description given" | ||
); | ||
}); | ||
const cards = getCardImages(); | ||
expect(cards[0].card.description).toBe(undefined); | ||
}); | ||
|
||
it("should display multiple projects", async () => { | ||
const ids = [1, 2, 3]; | ||
const names = ids.map((id) => `Project ${id}`); | ||
const descriptions = ids.map((id) => `Description ${id}`); | ||
await setupComponent( | ||
ids.map( | ||
(id, index) => | ||
new Project({ | ||
...generateProject(id), | ||
name: names[index], | ||
description: descriptions[index], | ||
}) | ||
) | ||
); | ||
|
||
const cards = getCardImages(); | ||
expect(cards.length).toBe(ids.length); | ||
expect(getButton()).toBeTruthy(); | ||
ids.forEach((_, index) => { | ||
expect(getCardTitle(cards[index]).innerText.trim()).toBe(names[index]); | ||
expect(getCardText(cards[index]).innerText.trim()).toBe( | ||
descriptions[index] | ||
); | ||
}); | ||
it("should display multiple projects", async () => { | ||
const ids = [1, 2, 3]; | ||
const names = ids.map((id) => `Project ${id}`); | ||
const descriptions = ids.map((id) => `Description ${id}`); | ||
await interceptProjects( | ||
ids.map( | ||
(id, index) => | ||
new Project({ | ||
...generateProject(id), | ||
name: names[index], | ||
descriptionHtmlTagline: descriptions[index], | ||
}) | ||
) | ||
); | ||
|
||
const cards = getCardImages(); | ||
expect(cards.length).toBe(ids.length); | ||
expect(getButton()).toBeTruthy(); | ||
ids.forEach((_, index) => { | ||
expect(cards[index].card.title).toBe(names[index]); | ||
expect(cards[index].card.description).toBe(descriptions[index]); | ||
}); | ||
}); | ||
|
||
it("should link to project details page", async () => { | ||
await setupComponent([]); | ||
it("should link to project details page", async () => { | ||
await interceptProjects([]); | ||
|
||
const button = getButton(); | ||
expect(button).toBeTruthy(); | ||
expect(button.innerText.trim()).toBe("More Projects"); | ||
assertRoute(button, "/projects"); | ||
}); | ||
const button = getButton(); | ||
expect(button).toBeTruthy(); | ||
expect(button.innerText.trim()).toBe("More Projects"); | ||
assertRoute(button, "/projects"); | ||
}); | ||
}); |
Oops, something went wrong.