|
@@ -1,11 +1,11 @@
|
|
| 1 |
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
|
| 2 |
-
import { provideRouter } from '@angular/router';
|
| 3 |
|
| 4 |
import { routes } from './app.routes';
|
| 5 |
|
| 6 |
export const appConfig: ApplicationConfig = {
|
| 7 |
providers: [
|
| 8 |
provideBrowserGlobalErrorListeners(),
|
| 9 |
-
provideRouter(routes)
|
| 10 |
]
|
| 11 |
};
|
|
|
|
| 1 |
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
|
| 2 |
+
import { provideRouter, withComponentInputBinding } from '@angular/router';
|
| 3 |
|
| 4 |
import { routes } from './app.routes';
|
| 5 |
|
| 6 |
export const appConfig: ApplicationConfig = {
|
| 7 |
providers: [
|
| 8 |
provideBrowserGlobalErrorListeners(),
|
| 9 |
+
provideRouter(routes, withComponentInputBinding())
|
| 10 |
]
|
| 11 |
};
|
|
@@ -1,8 +1,8 @@
|
|
| 1 |
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
| 2 |
-
import { RouterTestingHarness } from '@angular/router/testing';
|
| 3 |
import { provideRouter, Router } from '@angular/router';
|
| 4 |
import { provideLocationMocks } from '@angular/common/testing';
|
| 5 |
import { Location } from '@angular/common';
|
|
|
|
| 6 |
|
| 7 |
import { BookDetailsPage } from './book-details-page';
|
| 8 |
import { booksPortalRoutes } from '../books-portal.routes';
|
|
@@ -13,7 +13,11 @@ describe('BookDetailsPage', () => {
|
|
| 13 |
let fixture: ComponentFixture<BookDetailsPage>;
|
| 14 |
let bookStore: BookStore;
|
| 15 |
|
|
|
|
|
|
|
| 16 |
beforeEach(async () => {
|
|
|
|
|
|
|
| 17 |
await TestBed.configureTestingModule({
|
| 18 |
imports: [BookDetailsPage],
|
| 19 |
providers: [
|
|
@@ -23,7 +27,9 @@ describe('BookDetailsPage', () => {
|
|
| 23 |
})
|
| 24 |
.compileComponents();
|
| 25 |
|
| 26 |
-
fixture = TestBed.createComponent(BookDetailsPage
|
|
|
|
|
|
|
| 27 |
component = fixture.componentInstance;
|
| 28 |
bookStore = TestBed.inject(BookStore);
|
| 29 |
await fixture.whenStable();
|
|
@@ -34,13 +40,8 @@ describe('BookDetailsPage', () => {
|
|
| 34 |
});
|
| 35 |
|
| 36 |
it('should load the correct book by ISBN', async () => {
|
| 37 |
-
const harness = await RouterTestingHarness.create();
|
| 38 |
-
const component = await harness.navigateByUrl('/books/details/12345', BookDetailsPage);
|
| 39 |
-
|
| 40 |
const expectedBook = bookStore.getSingle('12345');
|
| 41 |
-
|
| 42 |
expect(component['book']()).toEqual(expectedBook);
|
| 43 |
-
expect(document.title).toBe('Book Details');
|
| 44 |
});
|
| 45 |
|
| 46 |
it('should navigate to the details page', async () => {
|
|
@@ -51,4 +52,12 @@ describe('BookDetailsPage', () => {
|
|
| 51 |
|
| 52 |
expect(location.path()).toBe('/books/details/12345');
|
| 53 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
});
|
|
|
|
| 1 |
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
|
|
| 2 |
import { provideRouter, Router } from '@angular/router';
|
| 3 |
import { provideLocationMocks } from '@angular/common/testing';
|
| 4 |
import { Location } from '@angular/common';
|
| 5 |
+
import { inputBinding, signal, WritableSignal } from '@angular/core';
|
| 6 |
|
| 7 |
import { BookDetailsPage } from './book-details-page';
|
| 8 |
import { booksPortalRoutes } from '../books-portal.routes';
|
|
|
|
| 13 |
let fixture: ComponentFixture<BookDetailsPage>;
|
| 14 |
let bookStore: BookStore;
|
| 15 |
|
| 16 |
+
let isbn: WritableSignal<string>;
|
| 17 |
+
|
| 18 |
beforeEach(async () => {
|
| 19 |
+
isbn = signal('12345');
|
| 20 |
+
|
| 21 |
await TestBed.configureTestingModule({
|
| 22 |
imports: [BookDetailsPage],
|
| 23 |
providers: [
|
|
|
|
| 27 |
})
|
| 28 |
.compileComponents();
|
| 29 |
|
| 30 |
+
fixture = TestBed.createComponent(BookDetailsPage, {
|
| 31 |
+
bindings: [inputBinding('isbn', isbn)]
|
| 32 |
+
});
|
| 33 |
component = fixture.componentInstance;
|
| 34 |
bookStore = TestBed.inject(BookStore);
|
| 35 |
await fixture.whenStable();
|
|
|
|
| 40 |
});
|
| 41 |
|
| 42 |
it('should load the correct book by ISBN', async () => {
|
|
|
|
|
|
|
|
|
|
| 43 |
const expectedBook = bookStore.getSingle('12345');
|
|
|
|
| 44 |
expect(component['book']()).toEqual(expectedBook);
|
|
|
|
| 45 |
});
|
| 46 |
|
| 47 |
it('should navigate to the details page', async () => {
|
|
|
|
| 52 |
|
| 53 |
expect(location.path()).toBe('/books/details/12345');
|
| 54 |
});
|
| 55 |
+
|
| 56 |
+
it('should update the book when ISBN changes', async () => {
|
| 57 |
+
isbn.set('67890');
|
| 58 |
+
await fixture.whenStable();
|
| 59 |
+
|
| 60 |
+
const expectedBook = bookStore.getSingle('67890');
|
| 61 |
+
expect(component['book']()).toEqual(expectedBook);
|
| 62 |
+
});
|
| 63 |
});
|
|
@@ -1,7 +1,6 @@
|
|
| 1 |
-
import { Component, inject,
|
| 2 |
-
import {
|
| 3 |
|
| 4 |
-
import { Book } from '../../shared/book';
|
| 5 |
import { BookStore } from '../../shared/book-store';
|
| 6 |
|
| 7 |
@Component({
|
|
@@ -12,14 +11,7 @@ import { BookStore } from '../../shared/book-store';
|
|
| 12 |
})
|
| 13 |
export class BookDetailsPage {
|
| 14 |
#bookStore = inject(BookStore);
|
| 15 |
-
#route = inject(ActivatedRoute);
|
| 16 |
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
constructor() {
|
| 20 |
-
const isbn = this.#route.snapshot.paramMap.get('isbn');
|
| 21 |
-
if (isbn) {
|
| 22 |
-
this.book.set(this.#bookStore.getSingle(isbn));
|
| 23 |
-
}
|
| 24 |
-
}
|
| 25 |
}
|
|
|
|
| 1 |
+
import { Component, computed, inject, input } from '@angular/core';
|
| 2 |
+
import { RouterLink } from '@angular/router';
|
| 3 |
|
|
|
|
| 4 |
import { BookStore } from '../../shared/book-store';
|
| 5 |
|
| 6 |
@Component({
|
|
|
|
| 11 |
})
|
| 12 |
export class BookDetailsPage {
|
| 13 |
#bookStore = inject(BookStore);
|
|
|
|
| 14 |
|
| 15 |
+
readonly isbn = input.required<string>();
|
| 16 |
+
protected book = computed(() => this.#bookStore.getSingle(this.isbn()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
}
|