@@ -7,7 +7,10 @@
|
|
7 |
"build": "ng build",
|
8 |
"watch": "ng build --watch --configuration development",
|
9 |
"test": "ng test",
|
10 |
-
"lint": "ng lint"
|
|
|
|
|
|
|
11 |
},
|
12 |
"private": true,
|
13 |
"dependencies": {
|
7 |
"build": "ng build",
|
8 |
"watch": "ng build --watch --configuration development",
|
9 |
"test": "ng test",
|
10 |
+
"lint": "ng lint",
|
11 |
+
"docker:build": "docker build -t book-monkey .",
|
12 |
+
"docker:build:silicon": "npm run docker:build -- --platform=linux/amd64",
|
13 |
+
"docker:redeploy": "docker compose down --remove-orphans && docker compose up -d"
|
14 |
},
|
15 |
"private": true,
|
16 |
"dependencies": {
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"apiUrl": "https://api5.angular-buch.com"
|
3 |
+
}
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"apiUrl": "${API_URL}"
|
3 |
+
}
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { BookCreateComponent } from './book-create.component';
|
4 |
+
|
5 |
+
describe('BookCreateComponent', () => {
|
6 |
+
let component: BookCreateComponent;
|
7 |
+
let fixture: ComponentFixture<BookCreateComponent>;
|
8 |
+
|
9 |
+
beforeEach(async () => {
|
10 |
+
await TestBed.configureTestingModule({
|
11 |
+
declarations: [ BookCreateComponent ]
|
12 |
+
})
|
13 |
+
.compileComponents();
|
14 |
+
|
15 |
+
fixture = TestBed.createComponent(BookCreateComponent);
|
16 |
+
component = fixture.componentInstance;
|
17 |
+
fixture.detectChanges();
|
18 |
+
});
|
19 |
+
|
20 |
+
it('should create', () => {
|
21 |
+
expect(component).toBeTruthy();
|
22 |
+
});
|
23 |
+
});
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { BookEditComponent } from './book-edit.component';
|
4 |
+
|
5 |
+
describe('BookEditComponent', () => {
|
6 |
+
let component: BookEditComponent;
|
7 |
+
let fixture: ComponentFixture<BookEditComponent>;
|
8 |
+
|
9 |
+
beforeEach(async () => {
|
10 |
+
await TestBed.configureTestingModule({
|
11 |
+
declarations: [ BookEditComponent ]
|
12 |
+
})
|
13 |
+
.compileComponents();
|
14 |
+
|
15 |
+
fixture = TestBed.createComponent(BookEditComponent);
|
16 |
+
component = fixture.componentInstance;
|
17 |
+
fixture.detectChanges();
|
18 |
+
});
|
19 |
+
|
20 |
+
it('should create', () => {
|
21 |
+
expect(component).toBeTruthy();
|
22 |
+
});
|
23 |
+
});
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { BookFormComponent } from './book-form.component';
|
4 |
+
|
5 |
+
describe('BookFormComponent', () => {
|
6 |
+
let component: BookFormComponent;
|
7 |
+
let fixture: ComponentFixture<BookFormComponent>;
|
8 |
+
|
9 |
+
beforeEach(async () => {
|
10 |
+
await TestBed.configureTestingModule({
|
11 |
+
declarations: [ BookFormComponent ]
|
12 |
+
})
|
13 |
+
.compileComponents();
|
14 |
+
|
15 |
+
fixture = TestBed.createComponent(BookFormComponent);
|
16 |
+
component = fixture.componentInstance;
|
17 |
+
fixture.detectChanges();
|
18 |
+
});
|
19 |
+
|
20 |
+
it('should create', () => {
|
21 |
+
expect(component).toBeTruthy();
|
22 |
+
});
|
23 |
+
});
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { FormErrorsComponent } from './form-errors.component';
|
4 |
+
|
5 |
+
describe('FormErrorsComponent', () => {
|
6 |
+
let component: FormErrorsComponent;
|
7 |
+
let fixture: ComponentFixture<FormErrorsComponent>;
|
8 |
+
|
9 |
+
beforeEach(async () => {
|
10 |
+
await TestBed.configureTestingModule({
|
11 |
+
declarations: [ FormErrorsComponent ]
|
12 |
+
})
|
13 |
+
.compileComponents();
|
14 |
+
|
15 |
+
fixture = TestBed.createComponent(FormErrorsComponent);
|
16 |
+
component = fixture.componentInstance;
|
17 |
+
fixture.detectChanges();
|
18 |
+
});
|
19 |
+
|
20 |
+
it('should create', () => {
|
21 |
+
expect(component).toBeTruthy();
|
22 |
+
});
|
23 |
+
});
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { AsyncValidatorsService } from './async-validators.service';
|
4 |
+
|
5 |
+
describe('AsyncValidatorsService', () => {
|
6 |
+
let service: AsyncValidatorsService;
|
7 |
+
|
8 |
+
beforeEach(() => {
|
9 |
+
TestBed.configureTestingModule({});
|
10 |
+
service = TestBed.inject(AsyncValidatorsService);
|
11 |
+
});
|
12 |
+
|
13 |
+
it('should be created', () => {
|
14 |
+
expect(service).toBeTruthy();
|
15 |
+
});
|
16 |
+
});
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { BookDetailsComponent } from './book-details.component';
|
4 |
+
|
5 |
+
describe('BookDetailsComponent', () => {
|
6 |
+
let component: BookDetailsComponent;
|
7 |
+
let fixture: ComponentFixture<BookDetailsComponent>;
|
8 |
+
|
9 |
+
beforeEach(async () => {
|
10 |
+
await TestBed.configureTestingModule({
|
11 |
+
declarations: [ BookDetailsComponent ]
|
12 |
+
})
|
13 |
+
.compileComponents();
|
14 |
+
|
15 |
+
fixture = TestBed.createComponent(BookDetailsComponent);
|
16 |
+
component = fixture.componentInstance;
|
17 |
+
fixture.detectChanges();
|
18 |
+
});
|
19 |
+
|
20 |
+
it('should create', () => {
|
21 |
+
expect(component).toBeTruthy();
|
22 |
+
});
|
23 |
+
});
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { BookListComponent } from './book-list.component';
|
4 |
+
|
5 |
+
describe('BookListComponent', () => {
|
6 |
+
let component: BookListComponent;
|
7 |
+
let fixture: ComponentFixture<BookListComponent>;
|
8 |
+
|
9 |
+
beforeEach(async () => {
|
10 |
+
await TestBed.configureTestingModule({
|
11 |
+
declarations: [ BookListComponent ]
|
12 |
+
})
|
13 |
+
.compileComponents();
|
14 |
+
|
15 |
+
fixture = TestBed.createComponent(BookListComponent);
|
16 |
+
component = fixture.componentInstance;
|
17 |
+
fixture.detectChanges();
|
18 |
+
});
|
19 |
+
|
20 |
+
it('should create', () => {
|
21 |
+
expect(component).toBeTruthy();
|
22 |
+
});
|
23 |
+
});
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { LoggedinOnlyDirective } from './loggedin-only.directive';
|
2 |
+
|
3 |
+
describe('LoggedinOnlyDirective', () => {
|
4 |
+
it('should create an instance', () => {
|
5 |
+
const directive = new LoggedinOnlyDirective();
|
6 |
+
expect(directive).toBeTruthy();
|
7 |
+
});
|
8 |
+
});
|
@@ -1,4 +1,3 @@
|
|
1 |
-
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
2 |
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
3 |
|
4 |
import { HomeComponent } from './home.component';
|
@@ -9,8 +8,7 @@ describe('HomeComponent', () => {
|
|
9 |
|
10 |
beforeEach(async () => {
|
11 |
await TestBed.configureTestingModule({
|
12 |
-
declarations: [ HomeComponent ]
|
13 |
-
schemas: [NO_ERRORS_SCHEMA]
|
14 |
})
|
15 |
.compileComponents();
|
16 |
|
|
|
1 |
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
2 |
|
3 |
import { HomeComponent } from './home.component';
|
8 |
|
9 |
beforeEach(async () => {
|
10 |
await TestBed.configureTestingModule({
|
11 |
+
declarations: [ HomeComponent ]
|
|
|
12 |
})
|
13 |
.compileComponents();
|
14 |
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { SearchComponent } from './search.component';
|
4 |
+
|
5 |
+
describe('SearchComponent', () => {
|
6 |
+
let component: SearchComponent;
|
7 |
+
let fixture: ComponentFixture<SearchComponent>;
|
8 |
+
|
9 |
+
beforeEach(async () => {
|
10 |
+
await TestBed.configureTestingModule({
|
11 |
+
declarations: [ SearchComponent ]
|
12 |
+
})
|
13 |
+
.compileComponents();
|
14 |
+
|
15 |
+
fixture = TestBed.createComponent(SearchComponent);
|
16 |
+
component = fixture.componentInstance;
|
17 |
+
fixture.detectChanges();
|
18 |
+
});
|
19 |
+
|
20 |
+
it('should create', () => {
|
21 |
+
expect(component).toBeTruthy();
|
22 |
+
});
|
23 |
+
});
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { TestBed } from '@angular/core/testing';
|
2 |
+
|
3 |
+
import { BookStoreService } from './book-store.service';
|
4 |
+
|
5 |
+
describe('BookStoreService', () => {
|
6 |
+
let service: BookStoreService;
|
7 |
+
|
8 |
+
beforeEach(() => {
|
9 |
+
TestBed.configureTestingModule({});
|
10 |
+
service = TestBed.inject(BookStoreService);
|
11 |
+
});
|
12 |
+
|
13 |
+
it('should be created', () => {
|
14 |
+
expect(service).toBeTruthy();
|
15 |
+
});
|
16 |
+
});
|
@@ -1,16 +1,18 @@
|
|
1 |
import { HttpClient } from '@angular/common/http';
|
2 |
-
import { Injectable } from '@angular/core';
|
3 |
import { Observable, catchError, of } from 'rxjs';
|
4 |
|
5 |
import { Book } from './book';
|
|
|
6 |
|
7 |
@Injectable({
|
8 |
providedIn: 'root'
|
9 |
})
|
10 |
export class BookStoreService {
|
11 |
-
|
12 |
-
|
13 |
-
|
|
|
14 |
|
15 |
getAll(): Observable<Book[]> {
|
16 |
return this.http.get<Book[]>(`${this.apiUrl}/books`).pipe(
|
1 |
import { HttpClient } from '@angular/common/http';
|
2 |
+
import { Inject, Injectable } from '@angular/core';
|
3 |
import { Observable, catchError, of } from 'rxjs';
|
4 |
|
5 |
import { Book } from './book';
|
6 |
+
import { API_URL } from './settings';
|
7 |
|
8 |
@Injectable({
|
9 |
providedIn: 'root'
|
10 |
})
|
11 |
export class BookStoreService {
|
12 |
+
constructor(
|
13 |
+
@Inject(API_URL) private apiUrl: string,
|
14 |
+
private http: HttpClient
|
15 |
+
) {}
|
16 |
|
17 |
getAll(): Observable<Book[]> {
|
18 |
return this.http.get<Book[]>(`${this.apiUrl}/books`).pipe(
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { InjectionToken } from '@angular/core';
|
2 |
+
|
3 |
+
export interface Settings {
|
4 |
+
apiUrl: string;
|
5 |
+
}
|
6 |
+
|
7 |
+
export const API_URL = new InjectionToken<string>('apiUrl');
|
@@ -1,8 +1,19 @@
|
|
1 |
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
2 |
|
3 |
import { AppModule } from './app/app.module';
|
|
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
2 |
|
3 |
import { AppModule } from './app/app.module';
|
4 |
+
import { API_URL, Settings } from './app/shared/settings';
|
5 |
|
6 |
+
async function loadSettings(): Promise<Settings> {
|
7 |
+
const response = await fetch('settings.json');
|
8 |
+
return response.json();
|
9 |
+
}
|
10 |
+
|
11 |
+
loadSettings().then(settings => {
|
12 |
+
platformBrowserDynamic([
|
13 |
+
{ provide: API_URL, useValue: settings.apiUrl }
|
14 |
+
])
|
15 |
+
.bootstrapModule(AppModule, {
|
16 |
+
ngZoneEventCoalescing: true
|
17 |
+
})
|
18 |
+
.catch(err => console.error(err));
|
19 |
+
});
|