Skip to content

Commit

Permalink
[Issue comixed#233] Add reading list creation to the library state wi…
Browse files Browse the repository at this point in the history
…ring.
  • Loading branch information
mcpierce committed May 18, 2020
1 parent c519a50 commit 3ca4418
Show file tree
Hide file tree
Showing 11 changed files with 451 additions and 72 deletions.
28 changes: 26 additions & 2 deletions comixed-frontend/src/app/library/actions/library.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ export enum LibraryActionTypes {
ConvertComicsFailed = '[LIBRARY] Failed to convert comics',
Consolidate = '[LIBRARY] Consolidate the library',
Consolidated = '[LIBRARY] Library is consolidated',
ConsolidateFailed = '[LIBRARY] Failed to consolidate library'
ConsolidateFailed = '[LIBRARY] Failed to consolidate library',
CreateReadingList = '[LIBRARY] Create a new reading list',
ReadingListCreated = '[LIBRARY] A reading list was created',
CreateReadingListFailed = '[LIBRARY] Failed to create a new reading list'
}

export class LibraryReset implements Action {
Expand Down Expand Up @@ -160,6 +163,24 @@ export class LibraryConsolidateFailed implements Action {
constructor() {}
}

export class LibraryCreateReadingList implements Action {
readonly type = LibraryActionTypes.CreateReadingList;

constructor(public payload: { name: string; summary: string }) {}
}

export class LibraryReadingListCreated implements Action {
readonly type = LibraryActionTypes.ReadingListCreated;

constructor(public payload: { readingList: ReadingList }) {}
}

export class LibraryCreateReadingListFailed implements Action {
readonly type = LibraryActionTypes.CreateReadingListFailed;

constructor() {}
}

export type LibraryActions =
| LibraryReset
| LibraryGetUpdates
Expand All @@ -176,4 +197,7 @@ export type LibraryActions =
| LibraryConvertComicsFailed
| LibraryConsolidate
| LibraryConsolidated
| LibraryConsolidateFailed;
| LibraryConsolidateFailed
| LibraryCreateReadingList
| LibraryReadingListCreated
| LibraryCreateReadingListFailed;
66 changes: 66 additions & 0 deletions comixed-frontend/src/app/library/adaptors/library.adaptor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ import {
LibraryConsolidateFailed,
LibraryConvertComics,
LibraryConvertComicsFailed,
LibraryCreateReadingList,
LibraryCreateReadingListFailed,
LibraryGetUpdates,
LibraryReadingListCreated,
LibraryUpdatesReceived
} from '../actions/library.actions';
import { LibraryAdaptor } from './library.adaptor';
Expand All @@ -59,6 +62,7 @@ import {
READING_LIST_1,
READING_LIST_2
} from 'app/comics/models/reading-list.fixtures';
import { ComicCollectionEntry } from 'app/library/models/comic-collection-entry';

describe('LibraryAdaptor', () => {
const ASCENDING = false;
Expand All @@ -73,6 +77,9 @@ describe('LibraryAdaptor', () => {
const ARCHIVE_TYPE = 'CBZ';
const RENAME_PAGES = true;
const READING_LISTS = [READING_LIST_1, READING_LIST_2];
const READING_LIST = READING_LIST_1;
const READING_LIST_NAME = READING_LIST.name;
const READING_LIST_SUMMARY = READING_LIST.summary;

let adaptor: LibraryAdaptor;
let store: Store<AppState>;
Expand Down Expand Up @@ -372,4 +379,63 @@ describe('LibraryAdaptor', () => {
});
});
});

describe('creating a reading list', () => {
beforeEach(() => {
adaptor.createReadingList(READING_LIST_NAME, READING_LIST_SUMMARY);
});

it('fires an action', () => {
expect(store.dispatch).toHaveBeenCalledWith(
new LibraryCreateReadingList({
name: READING_LIST_NAME,
summary: READING_LIST_SUMMARY
})
);
});

it('provides updates on creating reading lists', () => {
adaptor.savingReadingList$.subscribe(response =>
expect(response).toBeTruthy()
);
});

describe('success', () => {
beforeEach(() => {
store.dispatch(
new LibraryReadingListCreated({ readingList: READING_LIST })
);
});

it('provides updates on creating reading lists', () => {
adaptor.savingReadingList$.subscribe(response =>
expect(response).toBeFalsy()
);
});

it('provides updates on the reading lists', () => {
adaptor.readingLists$.subscribe(response =>
expect(response).toContain({
name: READING_LIST_NAME,
type: CollectionType.READING_LISTS,
last_comic_added: new Date(0).getTime(),
comics: [],
count: 0
} as ComicCollectionEntry)
);
});
});

describe('failure', () => {
beforeEach(() => {
store.dispatch(new LibraryCreateReadingListFailed());
});

it('provides updates on creating reading lists', () => {
adaptor.savingReadingList$.subscribe(response =>
expect(response).toBeFalsy()
);
});
});
});
});
28 changes: 28 additions & 0 deletions comixed-frontend/src/app/library/adaptors/library.adaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { LastReadDate } from 'app/library/models/last-read-date';
import {
LibraryConsolidate,
LibraryConvertComics,
LibraryCreateReadingList,
LibraryDeleteMultipleComics,
LibraryGetUpdates,
LibraryReset,
Expand All @@ -42,6 +43,7 @@ import { ComicGetIssue } from 'app/comics/actions/comic.actions';
import { ComicCollectionEntry } from 'app/library/models/comic-collection-entry';
import { LoggerService } from '@angular-ru/logger';
import { CollectionType } from 'app/library/models/collection-type.enum';
import { ReadingList } from 'app/comics/models/reading-list';

@Injectable()
export class LibraryAdaptor {
Expand All @@ -58,12 +60,14 @@ export class LibraryAdaptor {
private _locations$ = new BehaviorSubject<ComicCollectionEntry[]>([]);
private _stories$ = new BehaviorSubject<ComicCollectionEntry[]>([]);
private _readingLists$ = new BehaviorSubject<ComicCollectionEntry[]>([]);
private _rawReadingLists$ = new BehaviorSubject<ReadingList[]>([]);
private _processingCount$ = new BehaviorSubject<number>(0);
private comicId = -1;
private _timeout = 60;
private _maximum = 100;
private _converting$ = new BehaviorSubject<boolean>(false);
private _consolidating$ = new BehaviorSubject<boolean>(false);
private _savingReadingList$ = new BehaviorSubject<boolean>(false);

constructor(
private store: Store<AppState>,
Expand Down Expand Up @@ -104,7 +108,9 @@ export class LibraryAdaptor {
this._comicCount$.next(state.comicCount);
}
this._fetchingUpdate$.next(state.fetchingUpdates);
let redoReadingLists = false;
if (!_.isEqual(this._comic$.getValue(), state.comics)) {
redoReadingLists = true;
this._comic$.next(state.comics);
this._publishers$.next(
extractField(state.comics, CollectionType.PUBLISHERS)
Expand All @@ -120,6 +126,11 @@ export class LibraryAdaptor {
this._stories$.next(
extractField(state.comics, CollectionType.STORIES)
);
}
redoReadingLists =
redoReadingLists ||
!_.isEqual(this._rawReadingLists$.getValue(), state.readingLists);
if (redoReadingLists) {
const readingLists = extractField(
state.comics,
CollectionType.READING_LISTS,
Expand All @@ -143,6 +154,7 @@ export class LibraryAdaptor {
});
this._readingLists$.next(readingLists);
}
this._rawReadingLists$.next(state.readingLists);
if (
!!state.lastComicId &&
this._lastComicId$.getValue() !== state.lastComicId
Expand All @@ -155,6 +167,9 @@ export class LibraryAdaptor {
if (state.consolidating !== this._consolidating$.getValue()) {
this._consolidating$.next(state.consolidating);
}
if (state.savingReadingList !== this._savingReadingList$.getValue()) {
this._savingReadingList$.next(state.savingReadingList);
}
});
}

Expand Down Expand Up @@ -279,4 +294,17 @@ export class LibraryAdaptor {
get consolidating$(): Observable<boolean> {
return this._consolidating$.asObservable();
}

createReadingList(name: string, summary: string): void {
this.logger.debug(
`firing actiont o create a reading list: name=${name} summary=${summary}`
);
this.store.dispatch(
new LibraryCreateReadingList({ name: name, summary: summary })
);
}

get savingReadingList$(): Observable<boolean> {
return this._savingReadingList$.asObservable();
}
}
71 changes: 70 additions & 1 deletion comixed-frontend/src/app/library/effects/library.effects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,14 @@ import {
LibraryConsolidateFailed,
LibraryConvertComics,
LibraryConvertComicsFailed,
LibraryCreateReadingList,
LibraryCreateReadingListFailed,
LibraryDeleteMultipleComics,
LibraryDeleteMultipleComicsFailed,
LibraryGetUpdates,
LibraryGetUpdatesFailed,
LibraryMultipleComicsDeleted,
LibraryReadingListCreated,
LibraryRescanStarted,
LibraryStartRescan,
LibraryStartRescanFailed,
Expand All @@ -48,6 +51,7 @@ import { LoggerModule } from '@angular-ru/logger';
import { MessageService } from 'primeng/api';
import { Observable, of, throwError } from 'rxjs';
import { LibraryEffects } from './library.effects';
import { READING_LIST_1 } from 'app/comics/models/reading-list.fixtures';
import objectContaining = jasmine.objectContaining;

describe('LibraryEffects', () => {
Expand All @@ -57,6 +61,9 @@ describe('LibraryEffects', () => {
const LAST_READ_DATES = [COMIC_1_LAST_READ_DATE];
const COUNT = 25;
const ASCENDING = false;
const READING_LIST = READING_LIST_1;
const READING_LIST_NAME = READING_LIST.name;
const READING_LIST_SUMMARY = READING_LIST.summary;

let actions$: Observable<any>;
let effects: LibraryEffects;
Expand All @@ -81,7 +88,10 @@ describe('LibraryEffects', () => {
'LibraryService.deleteMultipleComics()'
),
convertComics: jasmine.createSpy('LibraryService.convertComics()'),
consolidate: jasmine.createSpy('LibraryService.consolidate()')
consolidate: jasmine.createSpy('LibraryService.consolidate()'),
createReadingList: jasmine.createSpy(
'LibraryService.createReadingList()'
)
}
},
MessageService
Expand Down Expand Up @@ -382,4 +392,63 @@ describe('LibraryEffects', () => {
);
});
});

describe('creating a reading list', () => {
it('fires an action on success', () => {
const serviceResponse = READING_LIST;
const action = new LibraryCreateReadingList({
name: READING_LIST_NAME,
summary: READING_LIST_SUMMARY
});
const outcome = new LibraryReadingListCreated({
readingList: READING_LIST
});

actions$ = hot('-a', { a: action });
libraryService.createReadingList.and.returnValue(of(serviceResponse));

const expected = hot('-b', { b: outcome });
expect(effects.createReadingList$).toBeObservable(expected);
expect(messageService.add).toHaveBeenCalledWith(
objectContaining({ severity: 'info' })
);
});

it('fires an action on service failure', () => {
const serviceResponse = new HttpErrorResponse({});
const action = new LibraryCreateReadingList({
name: READING_LIST_NAME,
summary: READING_LIST_SUMMARY
});
const outcome = new LibraryCreateReadingListFailed();

actions$ = hot('-a', { a: action });
libraryService.createReadingList.and.returnValue(
throwError(serviceResponse)
);

const expected = hot('-b', { b: outcome });
expect(effects.createReadingList$).toBeObservable(expected);
expect(messageService.add).toHaveBeenCalledWith(
objectContaining({ severity: 'error' })
);
});

it('fires an action on general failure', () => {
const action = new LibraryCreateReadingList({
name: READING_LIST_NAME,
summary: READING_LIST_SUMMARY
});
const outcome = new LibraryCreateReadingListFailed();

actions$ = hot('-a', { a: action });
libraryService.createReadingList.and.throwError('expected');

const expected = hot('-(b|)', { b: outcome });
expect(effects.createReadingList$).toBeObservable(expected);
expect(messageService.add).toHaveBeenCalledWith(
objectContaining({ severity: 'error' })
);
});
});
});

0 comments on commit 3ca4418

Please sign in to comment.