Skip to content

Commit

Permalink
refactor(example): remove @ngrx/db (#1664)
Browse files Browse the repository at this point in the history
Closes #1481
  • Loading branch information
King-i authored and timdeschryver committed Apr 1, 2019
1 parent c7e1406 commit f96974f
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 76 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
"@angular/router": "^7.0.1",
"@applitools/eyes-cypress": "^3.4.12",
"@bazel/buildifier": "^0.22.0",
"@ngrx/db": "^2.2.0-beta.0",
"core-js": "^2.5.4",
"hammerjs": "^2.0.8",
"opencollective": "^1.0.3",
Expand Down
10 changes: 9 additions & 1 deletion projects/example-app-cypress/integration/round-trip.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ context('Full round trip', () => {
testName: 'round-trip',
browser: { width: 800, height: 600 },
});
window.indexedDB.deleteDatabase('books_app');
window.localStorage.removeItem('books_app');
cy.visit('/');
});

beforeEach(() => {
(cy as any).restoreLocalStorage();
});

afterEach(() => {
(cy as any).saveLocalStorage();
});

after(() => {
(cy as any).eyesClose();
});
Expand Down
14 changes: 13 additions & 1 deletion projects/example-app-cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
import'@applitools/eyes-cypress/commands';
import '@applitools/eyes-cypress/commands';

let LOCAL_STORAGE_MEMORY = {};

Cypress.Commands.add('saveLocalStorage', () => {
Object.keys(localStorage).forEach(key => {
LOCAL_STORAGE_MEMORY[key] = localStorage[key];
});
});

Cypress.Commands.add('restoreLocalStorage', () => {
Object.keys(LOCAL_STORAGE_MEMORY).forEach(key => {
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
});
});
4 changes: 1 addition & 3 deletions projects/example-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
Example application utilizing @ngrx libraries, showcasing common patterns and best practices. Try it on [StackBlitz](https://ngrx.github.io/platform/stackblitz.html).

This app is a book collection manager. The user can authenticate, use the Google Books API to search for
books and add them to their collection. This application utilizes [@ngrx/db](https://github.com/ngrx/db)
to persist the collection across sessions; [@ngrx/store](../../docs/store/README.md) to manage
books and add them to their collection. This application utilizes [@ngrx/store](../../docs/store/README.md to manage
the state of the app and to cache requests made to the Google Books API;
[@ngrx/effects](../../docs/effects/README.md) to isolate side effects; [@angular/router](https://github.com/angular/angular) to manage navigation between routes; [@angular/material](https://github.com/angular/material2) to provide design and styling.

Expand All @@ -17,7 +16,6 @@ Built with [@angular/cli](https://github.com/angular/angular-cli)
- [@ngrx/router-store](../../docs/router-store/README.md) - Bindings to connect the Angular Router to @ngrx/store
- [@ngrx/entity](../../docs/entity/README.md) - Entity State adapter for managing record collections.
- [@ngrx/store-devtools](../../docs/store-devtools/README.md) - Instrumentation for @ngrx/store enabling time-travel debugging
- [@ngrx/db](https://github.com/ngrx/db) - RxJS powered IndexedDB for Angular apps
- [@angular/router](https://github.com/angular/angular) - Angular Router
- [@angular/material](https://github.com/angular/material2) - Angular Material
- [jest](https://facebook.github.io/jest/) - JavaScript test runner with easy setup, isolated browser testing and snapshot testing
Expand Down
2 changes: 1 addition & 1 deletion projects/example-app/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = {
mapCoverage: true,
coveragePathIgnorePatterns: ['/node_modules/', '/modules/*.*/'],
moduleNameMapper: {
'^@ngrx/(?!db)(.*)': '<rootDir>/../../modules/$1',
'^@ngrx/(.*)': '<rootDir>/../../modules/$1',
'^@example-app/(.*)': '<rootDir>/src/app/$1',
},
transformIgnorePatterns: ['node_modules/(?!@ngrx)'],
Expand Down
8 changes: 0 additions & 8 deletions projects/example-app/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { DBModule } from '@ngrx/db';
import { StoreRouterConnectingModule } from '@ngrx/router-store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';

import { CoreModule } from '@example-app/core/core.module';
import { AuthModule } from '@example-app/auth/auth.module';

import { reducers, metaReducers } from '@example-app/reducers';
import { schema } from '@example-app/db';

import { AppComponent } from '@example-app/core/containers/app.component';
import { AppRoutingModule } from '@example-app/app-routing.module';
Expand Down Expand Up @@ -68,12 +66,6 @@ import { AppRoutingModule } from '@example-app/app-routing.module';
*/
EffectsModule.forRoot([]),

/**
* `provideDB` sets up @ngrx/db with the provided schema and makes the Database
* service available.
*/
DBModule.provideDB(schema),

CoreModule,
],
bootstrap: [AppComponent],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { TestBed } from '@angular/core/testing';
import { Database } from '@ngrx/db';
import { Actions } from '@ngrx/effects';
import { provideMockActions } from '@ngrx/effects/testing';
import { cold, hot } from 'jasmine-marbles';
Expand All @@ -12,6 +11,10 @@ import {
} from '@example-app/books/actions';
import { Book } from '@example-app/books/models/book';
import { CollectionEffects } from '@example-app/books/effects/collection.effects';
import {
BookStorageService,
LOCAL_STORAGE_TOKEN,
} from '@example-app/core/services/';

describe('CollectionEffects', () => {
let db: any;
Expand All @@ -26,30 +29,37 @@ describe('CollectionEffects', () => {
providers: [
CollectionEffects,
{
provide: Database,
provide: BookStorageService,
useValue: {
supported: jest.fn(),
deleteStoredCollection: jest.fn(),
addToCollection: jest.fn(),
getCollection: jest.fn(),
removeFromCollection: jest.fn(),
},
},
{
provide: LOCAL_STORAGE_TOKEN,
useValue: {
open: jest.fn(),
query: jest.fn(),
insert: jest.fn(),
executeWrite: jest.fn(),
removeItem: jest.fn(),
setItem: jest.fn(),
getItem: jest.fn(_ => JSON.stringify([])),
},
},
provideMockActions(() => actions$),
],
});

db = TestBed.get(Database);
db = TestBed.get(BookStorageService);
effects = TestBed.get(CollectionEffects);
actions$ = TestBed.get(Actions);
});

describe('openDB$', () => {
it('should call db.open when initially subscribed to', () => {
effects.openDB$.subscribe();
expect(db.open).toHaveBeenCalledWith('books_app');
describe('checkStorageSupport$', () => {
it('should call db.checkStorageSupport when initially subscribed to', () => {
effects.checkStorageSupport$.subscribe();
expect(db.supported).toHaveBeenCalled();
});
});

describe('loadCollection$', () => {
it('should return a collection.LoadSuccess, with the books, on success', () => {
const action = CollectionPageActions.loadCollection();
Expand All @@ -58,9 +68,9 @@ describe('CollectionEffects', () => {
});

actions$ = hot('-a', { a: action });
const response = cold('-a-b|', { a: book1, b: book2 });
const expected = cold('-----c', { c: completion });
db.query = jest.fn(() => response);
const response = cold('-a|', { a: [book1, book2] });
const expected = cold('--c', { c: completion });
db.getCollection = jest.fn(() => response);

expect(effects.loadCollection$).toBeObservable(expected);
});
Expand All @@ -73,7 +83,7 @@ describe('CollectionEffects', () => {
actions$ = hot('-a', { a: action });
const response = cold('-#', {}, error);
const expected = cold('--c', { c: completion });
db.query = jest.fn(() => response);
db.getCollection = jest.fn(() => response);

expect(effects.loadCollection$).toBeObservable(expected);
});
Expand All @@ -87,10 +97,10 @@ describe('CollectionEffects', () => {
actions$ = hot('-a', { a: action });
const response = cold('-b', { b: true });
const expected = cold('--c', { c: completion });
db.insert = jest.fn(() => response);
db.addToCollection = jest.fn(() => response);

expect(effects.addBookToCollection$).toBeObservable(expected);
expect(db.insert).toHaveBeenCalledWith('books', [book1]);
expect(db.addToCollection).toHaveBeenCalledWith([book1]);
});

it('should return a collection.AddBookFail, with the book, when the db insert throws', () => {
Expand All @@ -101,7 +111,7 @@ describe('CollectionEffects', () => {
actions$ = hot('-a', { a: action });
const response = cold('-#', {}, error);
const expected = cold('--c', { c: completion });
db.insert = jest.fn(() => response);
db.addToCollection = jest.fn(() => response);

expect(effects.addBookToCollection$).toBeObservable(expected);
});
Expand All @@ -116,12 +126,10 @@ describe('CollectionEffects', () => {
actions$ = hot('-a', { a: action });
const response = cold('-b', { b: true });
const expected = cold('--c', { c: completion });
db.executeWrite = jest.fn(() => response);
db.removeFromCollection = jest.fn(() => response);

expect(effects.removeBookFromCollection$).toBeObservable(expected);
expect(db.executeWrite).toHaveBeenCalledWith('books', 'delete', [
book1.id,
]);
expect(db.removeFromCollection).toHaveBeenCalledWith([book1.id]);
});

it('should return a collection.RemoveBookFail, with the book, when the db insert throws', () => {
Expand All @@ -134,12 +142,10 @@ describe('CollectionEffects', () => {
actions$ = hot('-a', { a: action });
const response = cold('-#', {}, error);
const expected = cold('--c', { c: completion });
db.executeWrite = jest.fn(() => response);
db.removeFromCollection = jest.fn(() => response);

expect(effects.removeBookFromCollection$).toBeObservable(expected);
expect(db.executeWrite).toHaveBeenCalledWith('books', 'delete', [
book1.id,
]);
expect(db.removeFromCollection).toHaveBeenCalledWith([book1.id]);
});
});
});
Expand Down
23 changes: 9 additions & 14 deletions projects/example-app/src/app/books/effects/collection.effects.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { Injectable } from '@angular/core';
import { Database } from '@ngrx/db';
import { Actions, Effect, ofType, createEffect } from '@ngrx/effects';
import { defer, of } from 'rxjs';
import { catchError, map, mergeMap, switchMap, toArray } from 'rxjs/operators';

import { catchError, map, mergeMap, switchMap } from 'rxjs/operators';
import { Book } from '@example-app/books/models/book';
import {
SelectedBookPageActions,
CollectionPageActions,
CollectionApiActions,
CollectionPageActions,
SelectedBookPageActions,
} from '@example-app/books/actions';

import { BookStorageService } from '@example-app/core/services';
@Injectable()
export class CollectionEffects {
/**
Expand All @@ -24,16 +22,13 @@ export class CollectionEffects {
* effect easier to test.
*/
@Effect({ dispatch: false })
openDB$ = defer(() => {
return this.db.open('books_app');
});
checkStorageSupport$ = defer(() => this.storageService.supported());

loadCollection$ = createEffect(() =>
this.actions$.pipe(
ofType(CollectionPageActions.loadCollection.type),
switchMap(() =>
this.db.query('books').pipe(
toArray(),
this.storageService.getCollection().pipe(
map((books: Book[]) =>
CollectionApiActions.loadBooksSuccess({ books })
),
Expand All @@ -49,7 +44,7 @@ export class CollectionEffects {
this.actions$.pipe(
ofType(SelectedBookPageActions.addBook.type),
mergeMap(({ book }) =>
this.db.insert('books', [book]).pipe(
this.storageService.addToCollection([book]).pipe(
map(() => CollectionApiActions.addBookSuccess({ book })),
catchError(() => of(CollectionApiActions.addBookFailure({ book })))
)
Expand All @@ -61,7 +56,7 @@ export class CollectionEffects {
this.actions$.pipe(
ofType(SelectedBookPageActions.removeBook.type),
mergeMap(({ book }) =>
this.db.executeWrite('books', 'delete', [book.id]).pipe(
this.storageService.removeFromCollection([book.id]).pipe(
map(() => CollectionApiActions.removeBookSuccess({ book })),
catchError(() => of(CollectionApiActions.removeBookFailure({ book })))
)
Expand All @@ -73,6 +68,6 @@ export class CollectionEffects {
private actions$: Actions<
SelectedBookPageActions.SelectedBookPageActionsUnion
>,
private db: Database
private storageService: BookStorageService
) {}
}
Loading

0 comments on commit f96974f

Please sign in to comment.