diff --git a/app/db/package.json b/app/db/package.json index 2dae1c4e..b18458ec 100644 --- a/app/db/package.json +++ b/app/db/package.json @@ -6,7 +6,8 @@ "start": "ng serve", "build": "ng build --prod", "test": "ng test", - "test-headless": "ng test --watch=false --browsers=ChromeHeadless", + "test-headless-one": "ng test --watch=false --browsers=ChromeHeadless", + "test-headless": "ng test --watch=true --browsers=ChromeHeadless", "lint": "ng lint", "e2e": "ng e2e" }, diff --git a/app/db/src/app/services/app-state-actions.ts b/app/db/src/app/services/app-state-actions.ts index 01f59dcc..3ccc9abc 100644 --- a/app/db/src/app/services/app-state-actions.ts +++ b/app/db/src/app/services/app-state-actions.ts @@ -3,6 +3,152 @@ import { IStorable } from '../models/storable'; import { NoteItem } from '../models/note-state'; import { ListDirection } from '../common/list-direction'; +export class AppActionFactory { + static newGetSavedPage(pageId: string) { + return { + type: 'GET_SAVED_PAGE', + pageId, + } as AppAction; + } + + static newSavePage(title: string) { + return { + type: 'SAVE_PAGE', + title, + } as AppAction; + } + + static newUpdateCurrentPage() { + return { + type: 'UPDATE_CURRENT_PAGE', + } as AppAction; + } + + static newUpdateSavedPages(savedPages: IStorable) { + return { + type: 'UPDATE_SAVED_PAGES', + savedPages, + } as AppAction; + } + + static newAddCardToSavedPage(card: CardItem, pageId: string) { + return { + type: 'ADD_CARD_TO_SAVED_PAGE', + card, + pageId, + } as AppAction; + } + + static newAddCard(card: CardItem, nextToItem: CardItem) { + return { + type: 'ADD_CARD', + card, + nextToItem, + } as AppAction; + } + + static newUpdateCard(newCard: CardItem, oldCard: CardItem) { + return { + type: 'UPDATE_CARD', + newCard, + oldCard, + } as AppAction; + } + + static newRemoveCard(card: CardItem) { + return { + type: 'REMOVE_CARD', + card, + } as AppAction; + } + + static newMoveCard(card: CardItem, direction: ListDirection) { + return { + type: 'MOVE_CARD', + card, + direction, + } as AppAction; + } + + static newUpdateError(error: Error) { + return { + type: 'UPDATE_ERROR', + error, + } as AppAction; + } + + static newUpdateCardFontSize(cardFontSize: number) { + return { + type: 'UPDATE_CARD_FONT_SIZE', + cardFontSize, + } as AppAction; + } + + static newUpdateCardFontFamily(cardFontFamily: string) { + return { + type: 'UPDATE_CARD_FONT_FAMILY', + cardFontFamily, + } as AppAction; + } + + static newUpdateAutocomplete(words: string[]) { + return { + type: 'UPDATE_AUTOCOMPLETE', + words, + } as AppAction; + } + + static newUpdateDisplaySettings(settings: IStorable) { + return { + type: 'UPDATE_DISPLAY_SETTINGS', + settings, + } as AppAction; + } + static newUser(user: User) { + return { + type: 'SET_USER', + user, + } as AppAction; + } + + static newFindNotes(qry: string, nextToItem: CardItem) { + return { + type: 'FIND_NOTES', + qry, + nextToItem, + } as AppAction; + } + + static newGetNote(noteId: string, nextToItem: CardItem) { + return { + type: 'GET_NOTE', + noteId, + nextToItem, + } as AppAction; + } + + static newUpdateNotes(notes: IStorable) { + return { + type: 'UPDATE_NOTES', + notes, + } as AppAction; + } + + static newSaveNote(note: NoteItem) { + return { + type: 'SAVE_NOTE', + note, + } as AppAction; + } + + static newDeleteNote(note: NoteItem) { + return { + type: 'DELETE_NOTE', + note, + } as AppAction; + } +} + export type AppAction = | { type: 'GET_SAVED_PAGE'; @@ -48,11 +194,11 @@ export type AppAction = error: Error; } | { - type: 'UPDATE_FONT_SIZE'; + type: 'UPDATE_CARD_FONT_SIZE'; cardFontSize: number; } | { - type: 'UPDATE_FONT_FAMILY'; + type: 'UPDATE_CARD_FONT_FAMILY'; cardFontFamily: string; } | { diff --git a/app/db/src/app/services/app-state-reducer.spec.ts b/app/db/src/app/services/app-state-reducer.spec.ts index fd095699..ad7819ae 100644 --- a/app/db/src/app/services/app-state-reducer.spec.ts +++ b/app/db/src/app/services/app-state-reducer.spec.ts @@ -1,10 +1,8 @@ import { TestBed } from '@angular/core/testing'; import { reducer } from './app-state-reducer'; -import { UUID } from 'angular2-uuid'; -import { PageTitles, PageIcons } from '../constants'; -import { AppAction } from './app-state-actions'; -import { CardItem, CardType } from '../models/app-state'; +import { AppAction, AppActionFactory } from './app-state-actions'; import { Overlap } from '../common/bible-reference'; +import { CardType } from '../models/app-state'; describe('AppService Reducer', () => { const preState = { @@ -57,25 +55,180 @@ describe('AppService Reducer', () => { TestBed.configureTestingModule({}); }); - it('UPDATE_FONT_SIZE', () => { - const action = { - type: 'UPDATE_FONT_SIZE', - cardFontSize: 32, - } as AppAction; - + it('UPDATE_CARD_FONT_SIZE', () => { + const action = AppActionFactory.newUpdateCardFontSize(32); const testState = reducer(preState, action); - - expect(testState.displaySettings.value.cardFontSize).toBe(32); + expect(testState.displaySettings.value.cardFontSize).toBe(32, 'Failed to change card font size to 32'); }); - it('UPDATE_FONT_FAMILY', () => { - const action = { - type: 'UPDATE_FONT_FAMILY', - cardFontFamily: 'Jason', - } as AppAction; - + it('UPDATE_CARD_FONT_FAMILY', () => { + const action = AppActionFactory.newUpdateCardFontFamily('Jason'); const testState = reducer(preState, action); + expect(testState.displaySettings.value.cardFontFamily).toBe( + 'Jason', + 'Failed to change card font family to "Jason"' + ); + }); - expect(testState.displaySettings.value.cardFontFamily).toBe('Jason'); + it('UPDATE_DISPLAY_SETTINGS', () => { + const settings = { + createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(), + value: { + showStrongsAsModal: true, + appendCardToBottom: false, + insertCardNextToItem: false, + clearSearchAfterQuery: false, + cardFontSize: 100, + cardFontFamily: 'Jason', + showVersesOnNewLine: true, + showVerseNumbers: true, + showParagraphs: false, + showParagraphHeadings: false, + syncCardsAcrossDevices: true, + }, + }; + + const action = AppActionFactory.newUpdateDisplaySettings(settings); + const testState = reducer(preState, action); + expect(testState.displaySettings).toBe(settings, 'Failed to update the display settings'); + }); + + it('ADD_CARD', () => { + const card1 = { + qry: 'H123', + data: null, + type: CardType.Strongs, + dict: 'H', + }; + const action1 = AppActionFactory.newAddCard(card1, null); + const testState = reducer(preState, action1); + expect(testState.cards[0]).toBe(card1, 'Failed to add first card to empty list'); + + const card2 = { + qry: 'G123', + data: null, + type: CardType.Strongs, + dict: 'G', + }; + + const action2 = AppActionFactory.newAddCard(card2, null); + const testState2 = reducer(testState, action2); + expect(testState2.cards.length).toBe(2, 'Failed to add second card to list with 1 item'); + expect(testState2.cards[1]).toBe(card2); + + const card3 = { + qry: 'G1234', + data: null, + type: CardType.Strongs, + dict: 'G', + }; + + // append to top, insert next to card + + let setState = reducer( + testState2, + AppActionFactory.newUpdateDisplaySettings({ + createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(), + value: { + showStrongsAsModal: true, + appendCardToBottom: false, + insertCardNextToItem: true, + clearSearchAfterQuery: false, + cardFontSize: 100, + cardFontFamily: 'Jason', + showVersesOnNewLine: true, + showVerseNumbers: true, + showParagraphs: false, + showParagraphHeadings: false, + syncCardsAcrossDevices: true, + }, + }) + ); + + const action3 = AppActionFactory.newAddCard(card3, card2); + const testState3 = reducer(setState, action3); + expect(testState3.cards.length).toBe(3, 'Failed to add third card'); + expect(testState3.cards[1]).toBe(card3, 'Failed to insert card above the second card'); + + // append to bottom, insert next to card + + setState = reducer( + testState2, + AppActionFactory.newUpdateDisplaySettings({ + createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(), + value: { + showStrongsAsModal: true, + appendCardToBottom: true, + insertCardNextToItem: true, + clearSearchAfterQuery: false, + cardFontSize: 100, + cardFontFamily: 'Jason', + showVersesOnNewLine: true, + showVerseNumbers: true, + showParagraphs: false, + showParagraphHeadings: false, + syncCardsAcrossDevices: true, + }, + }) + ); + + const action4 = AppActionFactory.newAddCard(card3, card1); + const testState4 = reducer(setState, action4); + expect(testState4.cards.length).toBe(3, 'Failed to add third card'); + expect(testState4.cards[1]).toBe(card3, 'Failed to insert card below the first card'); + + // append to bottom, do not insert next to card + + setState = reducer( + testState2, + AppActionFactory.newUpdateDisplaySettings({ + createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(), + value: { + showStrongsAsModal: true, + appendCardToBottom: true, + insertCardNextToItem: false, + clearSearchAfterQuery: false, + cardFontSize: 100, + cardFontFamily: 'Jason', + showVersesOnNewLine: true, + showVerseNumbers: true, + showParagraphs: false, + showParagraphHeadings: false, + syncCardsAcrossDevices: true, + }, + }) + ); + + const action5 = AppActionFactory.newAddCard(card3, card1); + const testState5 = reducer(setState, action5); + expect(testState5.cards.length).toBe(3, 'Failed to add third card'); + expect(testState5.cards[2]).toBe(card3, 'Failed to insert card at end of the list'); + + // append to top, do not insert next to card + + setState = reducer( + testState2, + AppActionFactory.newUpdateDisplaySettings({ + createdOn: new Date(2020, 1, 1, 0, 0, 0, 0).toISOString(), + value: { + showStrongsAsModal: true, + appendCardToBottom: false, + insertCardNextToItem: false, + clearSearchAfterQuery: false, + cardFontSize: 100, + cardFontFamily: 'Jason', + showVersesOnNewLine: true, + showVerseNumbers: true, + showParagraphs: false, + showParagraphHeadings: false, + syncCardsAcrossDevices: true, + }, + }) + ); + + const action6 = AppActionFactory.newAddCard(card3, card1); + const testState6 = reducer(setState, action6); + expect(testState6.cards.length).toBe(3, 'Failed to add third card'); + expect(testState6.cards[0]).toBe(card3, 'Failed to insert card at start of the list'); }); }); diff --git a/app/db/src/app/services/app-state-reducer.ts b/app/db/src/app/services/app-state-reducer.ts index 1b485c5e..ba2beb20 100644 --- a/app/db/src/app/services/app-state-reducer.ts +++ b/app/db/src/app/services/app-state-reducer.ts @@ -41,7 +41,7 @@ export function reducer(state: AppState, action: AppAction): AppState { }; }); } - case 'UPDATE_FONT_SIZE': { + case 'UPDATE_CARD_FONT_SIZE': { const settings = new Storable({ ...state.displaySettings.value, cardFontSize: action.cardFontSize, @@ -52,7 +52,7 @@ export function reducer(state: AppState, action: AppAction): AppState { settings, }); } - case 'UPDATE_FONT_FAMILY': { + case 'UPDATE_CARD_FONT_FAMILY': { const settings = new Storable({ ...state.displaySettings.value, cardFontFamily: action.cardFontFamily, diff --git a/app/db/src/app/services/app.service.ts b/app/db/src/app/services/app.service.ts index 680b3774..0e2e7f76 100644 --- a/app/db/src/app/services/app.service.ts +++ b/app/db/src/app/services/app.service.ts @@ -115,14 +115,14 @@ export class AppService extends createStateService(reducer, initialState) { changeCardFontFamily(cardFont: string) { this.dispatch({ - type: 'UPDATE_FONT_FAMILY', + type: 'UPDATE_CARD_FONT_FAMILY', cardFontFamily: cardFont, }); } changeCardFontSize(size: number) { this.dispatch({ - type: 'UPDATE_FONT_SIZE', + type: 'UPDATE_CARD_FONT_SIZE', cardFontSize: size, }); }