Differenzansicht 16a-cypress
im Vergleich zu 16-guards

← Zurück zur Ãœbersicht | Demo | Quelltext auf GitHub
angular.json CHANGED
@@ -108,13 +108,60 @@
108
  "src/**/*.html"
109
  ]
110
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  }
112
  }
113
  }
114
  },
115
  "cli": {
116
  "schematicCollections": [
117
- "@angular-eslint/schematics"
 
 
118
  ]
119
  }
120
- }
108
  "src/**/*.html"
109
  ]
110
  }
111
+ },
112
+ "cypress-run": {
113
+ "builder": "@cypress/schematic:cypress",
114
+ "options": {
115
+ "devServerTarget": "book-monkey:serve"
116
+ },
117
+ "configurations": {
118
+ "production": {
119
+ "devServerTarget": "book-monkey:serve:production"
120
+ }
121
+ }
122
+ },
123
+ "cypress-open": {
124
+ "builder": "@cypress/schematic:cypress",
125
+ "options": {
126
+ "watch": true,
127
+ "headless": false
128
+ }
129
+ },
130
+ "ct": {
131
+ "builder": "@cypress/schematic:cypress",
132
+ "options": {
133
+ "devServerTarget": "book-monkey:serve",
134
+ "watch": true,
135
+ "headless": false,
136
+ "testingType": "component"
137
+ },
138
+ "configurations": {
139
+ "development": {
140
+ "devServerTarget": "book-monkey:serve:development"
141
+ }
142
+ }
143
+ },
144
+ "e2e": {
145
+ "builder": "@cypress/schematic:cypress",
146
+ "options": {
147
+ "devServerTarget": "book-monkey:serve",
148
+ "watch": true,
149
+ "headless": false
150
+ },
151
+ "configurations": {
152
+ "production": {
153
+ "devServerTarget": "book-monkey:serve:production"
154
+ }
155
+ }
156
  }
157
  }
158
  }
159
  },
160
  "cli": {
161
  "schematicCollections": [
162
+ "@cypress/schematic",
163
+ "@angular-eslint/schematics",
164
+ "@schematics/angular"
165
  ]
166
  }
167
+ }
cypress/e2e/spec.cy.ts ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ describe('BookMonkey', () => {
2
+ beforeEach(() => {
3
+ cy.visit('/');
4
+ });
5
+
6
+ it('should open the home page by default', () => {
7
+ cy.get('h1')
8
+ .should('contain', 'Home');
9
+ cy.url()
10
+ .should('contain', '/home');
11
+ });
12
+
13
+ it('should not show the administration form when not logged in', () => {
14
+ cy.get('nav button')
15
+ .as('loginLogoutBtn')
16
+ .contains('Logout')
17
+ .should('have.class', 'red')
18
+ .click();
19
+ cy.get('@loginLogoutBtn')
20
+ .contains('Login')
21
+ .should('have.class', 'green');
22
+ cy.get('nav')
23
+ .contains('Administration')
24
+ .as('adminButton')
25
+ .click();
26
+ cy.on('window:alert', (str) => {
27
+ expect(str).to.equal('Not logged in!');
28
+ });
29
+ cy.url()
30
+ .should('not.contain', '/admin/create');
31
+ cy.get('@adminButton')
32
+ .should('not.have.class', 'active');
33
+ });
34
+
35
+ it('should find all angular books using search input', () => {
36
+ cy.intercept('GET', 'https://api5.angular-buch.com/books/search/Angular')
37
+ .as('search');
38
+ cy.get('input[type=search]')
39
+ .clear()
40
+ .type('Angular');
41
+ cy.wait('@search')
42
+ .its('response.statusCode')
43
+ .should('eq', 200);
44
+ cy.get('.search-results')
45
+ .find('li')
46
+ .should('have.length.gte', 3)
47
+ .each(($li) => {
48
+ cy.wrap($li).contains('Angular')
49
+ });
50
+ });
51
+
52
+ it('should not open the results box on server errors', () => {
53
+ cy.intercept('GET', 'https://api5.angular-buch.com/books/search/*', {
54
+ statusCode: 500,
55
+ body: '500 Internal Server Error',
56
+ }).as('search');
57
+ cy.get('input[type=search]')
58
+ .clear()
59
+ .type('Angular');
60
+ cy.wait('@search');
61
+ cy.get('.search-results')
62
+ .should('not.exist');
63
+ });
64
+
65
+ it('should display the books list', () => {
66
+ cy.intercept('https://api5.angular-buch.com/books', {
67
+ fixture: 'books.json',
68
+ });
69
+ cy.get('nav')
70
+ .contains('Books')
71
+ .click();
72
+ cy.get('.book-list')
73
+ .children()
74
+ .its('length')
75
+ .should('eq', 1);
76
+ });
77
+ });
cypress/fixtures/books.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "isbn": "0123456789",
4
+ "title": "Dummy title",
5
+ "authors": [
6
+ "John Doe"
7
+ ],
8
+ "published": "2022-08-01T12:00:00.000Z",
9
+ "subtitle": "",
10
+ "description": "Some description",
11
+ "thumbnailUrl": "https://via.placeholder.com/500.png"
12
+ }
13
+ ]
cypress/fixtures/example.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ {
2
+ "name": "Using fixtures to represent data",
3
+ "email": "[email protected]"
4
+ }
5
+
cypress/support/commands.ts ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ***********************************************
2
+ // This example namespace declaration will help
3
+ // with Intellisense and code completion in your
4
+ // IDE or Text Editor.
5
+ // ***********************************************
6
+ // declare namespace Cypress {
7
+ // interface Chainable<Subject = any> {
8
+ // customCommand(param: any): typeof customCommand;
9
+ // }
10
+ // }
11
+ //
12
+ // function customCommand(param: any): void {
13
+ // console.warn(param);
14
+ // }
15
+ //
16
+ // NOTE: You can use it like so:
17
+ // Cypress.Commands.add('customCommand', customCommand);
18
+ //
19
+ // ***********************************************
20
+ // This example commands.js shows you how to
21
+ // create various custom commands and overwrite
22
+ // existing commands.
23
+ //
24
+ // For more comprehensive examples of custom
25
+ // commands please read more here:
26
+ // https://on.cypress.io/custom-commands
27
+ // ***********************************************
28
+ //
29
+ //
30
+ // -- This is a parent command --
31
+ // Cypress.Commands.add("login", (email, password) => { ... })
32
+ //
33
+ //
34
+ // -- This is a child command --
35
+ // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
36
+ //
37
+ //
38
+ // -- This is a dual command --
39
+ // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
40
+ //
41
+ //
42
+ // -- This will overwrite an existing command --
43
+ // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
cypress/support/component-index.html ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
+ <title>Components App</title>
8
+ </head>
9
+ <body>
10
+ <div data-cy-root></div>
11
+ </body>
12
+ </html>
cypress/support/component.ts ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ***********************************************************
2
+ // This example support/component.ts is processed and
3
+ // loaded automatically before your test files.
4
+ //
5
+ // This is a great place to put global configuration and
6
+ // behavior that modifies Cypress.
7
+ //
8
+ // You can change the location of this file or turn off
9
+ // automatically serving support files with the
10
+ // 'supportFile' configuration option.
11
+ //
12
+ // You can read more here:
13
+ // https://on.cypress.io/configuration
14
+ // ***********************************************************
15
+
16
+ // Import commands.js using ES2015 syntax:
17
+ import './commands'
18
+
19
+ // Alternatively you can use CommonJS syntax:
20
+ // require('./commands')
21
+
22
+ import { mount } from 'cypress/angular'
23
+
24
+ // Augment the Cypress namespace to include type definitions for
25
+ // your custom command.
26
+ // Alternatively, can be defined in cypress/support/component.d.ts
27
+ // with a <reference path="./component" /> at the top of your spec.
28
+ declare global {
29
+ namespace Cypress {
30
+ interface Chainable {
31
+ mount: typeof mount
32
+ }
33
+ }
34
+ }
35
+
36
+ Cypress.Commands.add('mount', mount)
37
+
38
+ // Example use:
39
+ // cy.mount(MyComponent)
cypress/support/e2e.ts ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ***********************************************************
2
+ // This example support/e2e.ts is processed and
3
+ // loaded automatically before your test files.
4
+ //
5
+ // This is a great place to put global configuration and
6
+ // behavior that modifies Cypress.
7
+ //
8
+ // You can change the location of this file or turn off
9
+ // automatically serving support files with the
10
+ // 'supportFile' configuration option.
11
+ //
12
+ // You can read more here:
13
+ // https://on.cypress.io/configuration
14
+ // ***********************************************************
15
+
16
+ // When a command from ./commands is ready to use, import with `import './commands'` syntax
17
+ // import './commands';
cypress/tsconfig.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "include": ["**/*.ts"],
4
+ "compilerOptions": {
5
+ "sourceMap": false,
6
+ "types": ["cypress"]
7
+ }
8
+ }
cypress.config.ts ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from 'cypress'
2
+
3
+ export default defineConfig({
4
+
5
+ e2e: {
6
+ 'baseUrl': 'http://localhost:4200'
7
+ },
8
+
9
+
10
+ component: {
11
+ devServer: {
12
+ framework: 'angular',
13
+ bundler: 'webpack',
14
+ },
15
+ specPattern: '**/*.cy.ts'
16
+ }
17
+
18
+ })
package.json CHANGED
@@ -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": {
@@ -30,6 +33,7 @@
30
  "@angular-devkit/build-angular": "^18.2.1",
31
  "@angular/cli": "^18.2.1",
32
  "@angular/compiler-cli": "^18.2.0",
 
33
  "@types/jasmine": "~5.1.0",
34
  "angular-eslint": "18.3.0",
35
  "eslint": "^9.9.0",
@@ -40,6 +44,7 @@
40
  "karma-jasmine": "~5.1.0",
41
  "karma-jasmine-html-reporter": "~2.1.0",
42
  "typescript": "~5.5.2",
43
- "typescript-eslint": "8.1.0"
 
44
  }
45
  }
7
  "build": "ng build",
8
  "watch": "ng build --watch --configuration development",
9
  "test": "ng test",
10
+ "lint": "ng lint",
11
+ "e2e": "ng e2e",
12
+ "cypress:open": "cypress open",
13
+ "cypress:run": "cypress run"
14
  },
15
  "private": true,
16
  "dependencies": {
33
  "@angular-devkit/build-angular": "^18.2.1",
34
  "@angular/cli": "^18.2.1",
35
  "@angular/compiler-cli": "^18.2.0",
36
+ "@cypress/schematic": "^2.5.2",
37
  "@types/jasmine": "~5.1.0",
38
  "angular-eslint": "18.3.0",
39
  "eslint": "^9.9.0",
44
  "karma-jasmine": "~5.1.0",
45
  "karma-jasmine-html-reporter": "~2.1.0",
46
  "typescript": "~5.5.2",
47
+ "typescript-eslint": "8.1.0",
48
+ "cypress": "latest"
49
  }
50
  }
src/app/admin/book-create/book-create.component.spec.ts ADDED
@@ -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
+ });
src/app/admin/book-edit/book-edit.component.spec.ts ADDED
@@ -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
+ });
src/app/admin/book-form/book-form.component.cy.ts ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { HttpClientModule } from '@angular/common/http';
2
+ import { BookStoreService } from '../../shared/book-store.service';
3
+ import { BookFormComponent } from './book-form.component';
4
+
5
+ describe('BookFormComponent', () => {
6
+ it('should be able to fill required fields', () => {
7
+ cy.mount(BookFormComponent, {
8
+ providers: [BookStoreService],
9
+ imports: [HttpClientModule]
10
+ });
11
+
12
+ cy.get('#title').type('My Title');
13
+ cy.get('#isbn').type('0123456789');
14
+ cy.get('[aria-label="Author 0"').type('Erika Mustermann');
15
+ cy.get('#description').type('My very first book');
16
+ cy.get('#published').type('2022-09-10');
17
+ });
18
+
19
+ it('should prefill form with an existing book', () => {
20
+ cy.mount(`<bm-book-form [book]="book" (submitBook)="submitBook.emit($event)"></bm-book-form>`, {
21
+ declarations: [BookFormComponent],
22
+ providers: [BookStoreService],
23
+ imports: [HttpClientModule],
24
+ componentProperties: {
25
+ book: {
26
+ isbn: '0123456789',
27
+ title: 'My Title',
28
+ authors: ['Erika Mustermann'],
29
+ published: '2022-09-10'
30
+ },
31
+ submitBook: {
32
+ emit: cy.spy().as('submitBookSpy')
33
+ }
34
+ }
35
+ });
36
+
37
+ //cy.get('button[type=submit]').as('submitBtn').should('not.have.attr', 'disabled').click()
38
+ cy.get('button[type=submit]').click();
39
+ // Assert
40
+ cy.get('@submitBookSpy').should('have.been.calledWith', 1);
41
+ });
42
+ });
src/app/admin/book-form/book-form.component.spec.ts ADDED
@@ -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
+ });
src/app/admin/form-errors/form-errors.component.spec.ts ADDED
@@ -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
+ });
src/app/admin/shared/async-validators.service.spec.ts ADDED
@@ -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
+ });
src/app/books/book-details/book-details.component.spec.ts ADDED
@@ -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
+ });
src/app/books/book-list/book-list.component.spec.ts ADDED
@@ -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
+ });
src/app/books/book-list-item/book-list-item.component.cy.ts ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { IsbnPipe } from '../shared/isbn.pipe';
2
+ import { BookListItemComponent } from './book-list-item.component';
3
+
4
+ describe('BookListItemComponent', () => {
5
+ it('should display the book with formatted ISBN', () => {
6
+ cy.mount(`<bm-book-list-item [book]="{
7
+ isbn: '0123456789',
8
+ title: 'Some Book',
9
+ authors: ['Author 1']
10
+ }"></bm-book-list-item>`, {
11
+ declarations: [BookListItemComponent, IsbnPipe],
12
+ });
13
+
14
+ cy.get('a').contains('ISBN 012-3456789');
15
+ });
16
+ });
src/app/books/shared/loggedin-only.directive.spec.ts ADDED
@@ -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
+ });
src/app/home/home.component.spec.ts CHANGED
@@ -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
 
src/app/search/search.component.cy.ts ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { HttpClientModule } from '@angular/common/http';
2
+ import { BookStoreService } from './../shared/book-store.service';
3
+ import { SearchComponent } from './search.component';
4
+
5
+ describe('SearchComponent', () => {
6
+ it('should display search results', () => {
7
+ cy.mount(`<bm-search></bm-search>`, {
8
+ declarations: [SearchComponent],
9
+ providers: [BookStoreService],
10
+ imports: [HttpClientModule]
11
+ });
12
+
13
+ const book = {
14
+ isbn: '0123456789',
15
+ title: 'Some Book',
16
+ authors: ['Author 1']
17
+ };
18
+ cy.intercept(
19
+ 'GET',
20
+ 'https://api5.angular-buch.com/books/search/*',
21
+ { body: [book] }
22
+ ).as('search');
23
+
24
+ cy.get('input[type=search]')
25
+ .clear()
26
+ .type(book.title)
27
+ .wait('@search');
28
+
29
+ cy.get('.search-results > li')
30
+ .its('length').should('eq', 1);
31
+ });
32
+ });
src/app/search/search.component.spec.ts ADDED
@@ -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
+ });
src/app/shared/book-store.service.spec.ts ADDED
@@ -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
+ });
src/app/shared/book-store.service.ts CHANGED
@@ -31,10 +31,10 @@ export class BookStoreService {
31
 
32
  getAllSearch(term: string): Observable<Book[]> {
33
  return this.http.get<Book[]>(`${this.apiUrl}/books/search/${term}`).pipe(
34
- catchError(err => {
35
  console.error(err);
36
  return of([]);
37
- })
38
  );
39
  }
40
 
31
 
32
  getAllSearch(term: string): Observable<Book[]> {
33
  return this.http.get<Book[]>(`${this.apiUrl}/books/search/${term}`).pipe(
34
+ /*catchError(err => {
35
  console.error(err);
36
  return of([]);
37
+ })*/
38
  );
39
  }
40