Skip to content

Commit

Permalink
Changed the fetch volumes button to use the last cache option [#148]
Browse files Browse the repository at this point in the history
 - The default behavior is determined by a new user property.
 - Selecting a split button changes the user property.
  • Loading branch information
mcpierce authored and BRUCELLA2 committed Jul 2, 2020
1 parent 00654c0 commit ec4dbee
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 139 deletions.
2 changes: 2 additions & 0 deletions comixed-frontend/src/app/comics/comics.constants.ts
Expand Up @@ -45,3 +45,5 @@ export const GET_ISSUE_URL = `${API_ROOT_URL}/scraping/volumes/\${volume}/issues
export const LOAD_METADATA_URL = `${API_ROOT_URL}/scraping/comics/\${comicId}/issue/\${issueId}`;

export const PUBLISHER_IMPRINT_FORMAT = `\${imprint} (\${publisher})`;

export const USER_PREFERENCE_SKIP_CACHE = 'user-preference.skip-cache';
@@ -1,139 +1,139 @@
<p-blockUI [target]='comicDetailsFormPanel'
[blocked]='fetchingIssue||fetchingVolumes||scraping'></p-blockUI>
<p-progressBar *ngIf='fetchingIssue||fetchingVolumes||scraping'
mode='indeterminate'></p-progressBar>
<p-blockUI [blocked]="fetchingIssue||fetchingVolumes||scraping"
[target]="comicDetailsFormPanel"></p-blockUI>
<p-progressBar *ngIf="fetchingIssue||fetchingVolumes||scraping"
mode="indeterminate"></p-progressBar>
<p-panel #comicDetailsFormPanel
[showHeader]='false'>
<div *ngIf='!volumes.length'>
<p-toolbar>
<div class='ui-toolbar-group-left'>
<button id='save-details-changes'
pButton
class='cx-action-button ui-button-success'
type='button'
[label]='"comic-details-editor.button.save-changes"|translate'
[disabled]='!comicDetailsForm.valid || !comicDetailsForm.dirty'
(click)='saveDetails()'></button>
<button id='reset-details-changes'
pButton
class='cx-action-button ui-button-danger'
type='button'
[label]='"comic-details-editor.button.reset-changes"|translate'
[disabled]='!comicDetailsForm.dirty'
(click)='resetDetails()'></button>
[showHeader]="false">
<div *ngIf="!volumes.length">
<p-toolbar>
<div class="ui-toolbar-group-left">
<button (click)="saveDetails()"
[disabled]="!comicDetailsForm.valid || !comicDetailsForm.dirty"
[label]="'comic-details-editor.button.save-changes'|translate"
class="cx-action-button ui-button-success"
id="save-details-changes"
pButton
type="button"></button>
<button (click)="resetDetails()"
[disabled]="!comicDetailsForm.dirty"
[label]="'comic-details-editor.button.reset-changes'|translate"
class="cx-action-button ui-button-danger"
id="reset-details-changes"
pButton
type="button"></button>
</div>
<div class="ui-toolbar-group-right">
<button (click)="skipCurrentComic()"
*ngIf="multiComicMode"
[label]="'comic-details-editor.button.skip-comic'|translate"
class="cx-action-button ui-button-danger"
icon="fa fa-fw fas fa-step-forward"
pButton
type="button"></button>
<p-splitButton [disabled]="!comicDetailsForm.valid"
[label]="(skipCache ? 'comic-details-editor.option.fetch-skip-cache' : 'comic-details-editor.option.fetch-with-cache')|translate"
[model]="fetchOptions"
class="ui-button-secondary"
icon="fa fa-fw fa-search"
id="fetch-volumes-button"
(onClick)="doFetchVolumes()"></p-splitButton>
</div>
</p-toolbar>
<form [formGroup]="comicDetailsForm">
<div class="ui-g">
<div class="ui-g-12">
<div>
<div class="cx-input-label">
<label for="comicvine-api-key">{{"comic-details-editor.label.comicvine-api-key"|translate}}</label>
</div>
<div class='ui-toolbar-group-right'>
<button *ngIf='multiComicMode'
pButton
class='cx-action-button ui-button-danger'
type='button'
[label]='"comic-details-editor.button.skip-comic"|translate'
icon='fa fa-fw fas fa-step-forward'
(click)='skipCurrentComic()'></button>
<p-splitButton id='fetch-volumes-button'
class='ui-button-secondary'
[label]='"comic-details-editor.button.fetch-volumes"|translate'
icon='fa fa-fw fa-search'
[model]='fetchOptions'
[disabled]='!comicDetailsForm.valid'></p-splitButton>
</div>
</p-toolbar>

<form [formGroup]='comicDetailsForm'>
<div class='ui-g'>
<div class='ui-g-12'>
<div>
<div class='cx-input-label'>
<label for='comicvine-api-key'>{{'comic-details-editor.label.comicvine-api-key'|translate}}</label>
</div>
<p-inplace [active]='editingApiKey'
(onActivate)='editingApiKey = true'>
<span pInplaceDisplay>{{apiKey || ('comic-details-editor.text.comicvine-api-key-placeholder'|translate)}}</span>
<span pInplaceContent>
<div class='ui-inputgroup'>
<input id='comicvine-api-key'
formControlName='apiKey'/>
<button id='save-api-key'
<p-inplace (onActivate)="editingApiKey = true"
[active]="editingApiKey">
<span pInplaceDisplay>{{apiKey || ("comic-details-editor.text.comicvine-api-key-placeholder"|translate)}}</span>
<span pInplaceContent>
<div class="ui-inputgroup">
<input formControlName="apiKey"
id="comicvine-api-key"/>
<button (click)="saveApiKey()"
[disabled]="!comicDetailsForm.controls['apiKey'].dirty"
[pTooltip]="'comic-details-editor.tooltip.save-api-key'|translate"
class="ui-button-success"
icon="fa fa-fw fa-save"
id="save-api-key"
pButton
type='button'
class='ui-button-success'
icon='fa fa-fw fa-save'
[pTooltip]='"comic-details-editor.tooltip.save-api-key"|translate'
[disabled]='!comicDetailsForm.controls["apiKey"].dirty'
(click)='saveApiKey()'></button>
<button id='reset-api-key'
type="button"></button>
<button (click)="resetApiKey()"
[disabled]="!comicDetailsForm.controls['apiKey'].dirty"
[pTooltip]="'comic-details-editor.tooltip.reset-api-key'|translate"
class="ui-button-danger"
icon="fa fa-fw fa-undo"
id="reset-api-key"
pButton
type='button'
class='ui-button-danger'
icon='fa fa-fw fa-undo'
[pTooltip]='"comic-details-editor.tooltip.reset-api-key"|translate'
[disabled]='!comicDetailsForm.controls["apiKey"].dirty'
(click)='resetApiKey()'></button>
type="button"></button>
</div>
</span>
</p-inplace>
</div>
</div>
<div class='ui-g-12'>
<div class='cx-input-label'>
<label for='series-name'>{{'comic-details-editor.label.series-name'|translate}}</label>
</div>
<div>
<input id='series-name'
pInputText
class='cx-input-field'
formControlName='seriesName'/>
<div *ngIf='comicDetailsForm.controls.seriesName.errors?.required'
class='cx-form-validation-error-container'>
<span class='cx-form-validation-error'>{{'global.errors.form-field-required'|translate:{name: 'Series name'} }}</span>
</div>
</div>
</div>
<div class='ui-g-6'>
<div class='cx-input-label'>
<label for='volume-name'>{{'comic-details-editor.label.volume-name'|translate}}</label>
</div>
<div>
<input id='volume-name'
pInputText
class='cx-input-field'
formControlName='volumeName'/>
<div *ngIf='comicDetailsForm.controls.volumeName.errors?.required'
class='cx-form-validation-error-container'>
<span class='cx-form-validation-error'>{{'global.errors.form-field-required'|translate:{name: 'Volume name'} }}</span>
</div>
</div>
<div class='cx-input-label'>
<label for='issue-number'>{{'comic-details-editor.label.issue-number'|translate}}</label>
</div>
<div>
<input id='issue-number'
pInputText
class='cx-input-field'
formControlName='issueNumber'/>
<div *ngIf='comicDetailsForm.controls.issueNumber.errors?.required'
class='cx-form-validation-error-container'>
<span class='cx-form-validation-error'>{{'global.errors.form-field-required'|translate:{name: 'Issue #'} }}</span>
</div>
</div>
</div>
<div class='ui-g-6'>
<!-- TODO placeholder for filter widgets -->
</div>
</p-inplace>
</div>
</div>
<div class="ui-g-12">
<div class="cx-input-label">
<label for="series-name">{{"comic-details-editor.label.series-name"|translate}}</label>
</div>
<div>
<input class="cx-input-field"
formControlName="seriesName"
id="series-name"
pInputText/>
<div *ngIf="comicDetailsForm.controls.seriesName.errors?.required"
class="cx-form-validation-error-container">
<span class="cx-form-validation-error">{{"global.errors.form-field-required"|translate:{name: "Series name"} }}</span>
</div>
</form>
</div>
<div *ngIf='volumes.length'
class='ui-g'>
<div class='ui-g-12'>
<app-volume-list [volumes]="volumes"
[comic]='comic'
[currentVolume]='currentVolume'
[currentIssue]='currentIssue'
[apiKey]='getApiKey()'
(volumeSelected)='volumeSelected($event)'
(issueSelected)='issueSelected($event)'
(cancelSelection)='selectionCancelled()'></app-volume-list>
</div>
</div>
<div class="ui-g-6">
<div class="cx-input-label">
<label for="volume-name">{{"comic-details-editor.label.volume-name"|translate}}</label>
</div>
<div>
<input class="cx-input-field"
formControlName="volumeName"
id="volume-name"
pInputText/>
<div *ngIf="comicDetailsForm.controls.volumeName.errors?.required"
class="cx-form-validation-error-container">
<span class="cx-form-validation-error">{{"global.errors.form-field-required"|translate:{name: "Volume name"} }}</span>
</div>
</div>
<div class="cx-input-label">
<label for="issue-number">{{"comic-details-editor.label.issue-number"|translate}}</label>
</div>
<div>
<input class="cx-input-field"
formControlName="issueNumber"
id="issue-number"
pInputText/>
<div *ngIf="comicDetailsForm.controls.issueNumber.errors?.required"
class="cx-form-validation-error-container">
<span class="cx-form-validation-error">{{"global.errors.form-field-required"|translate:{name: "Issue #"} }}</span>
</div>
</div>
</div>
<div class="ui-g-6">
<!-- TODO placeholder for filter widgets -->
</div>
</div>
</form>
</div>
<div *ngIf="volumes.length"
class="ui-g">
<div class="ui-g-12">
<app-volume-list (cancelSelection)="selectionCancelled()"
(issueSelected)="issueSelected($event)"
(volumeSelected)="volumeSelected($event)"
[apiKey]="getApiKey()"
[comic]="comic"
[currentIssue]="currentIssue"
[currentVolume]="currentVolume"
[volumes]='volumes'></app-volume-list>
</div>
</div>
</p-panel>
Expand Up @@ -54,12 +54,15 @@ import {
} from 'primeng/primeng';
import { TableModule } from 'primeng/table';
import { ComicDetailsEditorComponent } from './comic-details-editor.component';
import { USER_PREFERENCE_SKIP_CACHE } from 'app/comics/comics.constants';

describe('ComicDetailsEditorComponent', () => {
fdescribe('ComicDetailsEditorComponent', () => {
const API_KEY = 'ABCDEF0123456789';
const COMIC = COMIC_1;
const VOLUME = SCRAPING_VOLUME_1000;
const ISSUE = SCRAPING_ISSUE_1000;
const SERIES = 'Series name';
const ISSUE_NUMBER = '717';

let component: ComicDetailsEditorComponent;
let fixture: ComponentFixture<ComicDetailsEditorComponent>;
Expand Down Expand Up @@ -113,6 +116,8 @@ describe('ComicDetailsEditorComponent', () => {
store = TestBed.get(Store);
scrapingAdaptor = TestBed.get(ScrapingAdaptor);
authenticationAdaptor = TestBed.get(AuthenticationAdaptor);
spyOn(authenticationAdaptor, 'setPreference');
spyOn(authenticationAdaptor, 'getPreference');
translateService = TestBed.get(TranslateService);
comicAdaptor = TestBed.get(ComicAdaptor);
confirmationService = TestBed.get(ConfirmationService);
Expand Down Expand Up @@ -144,6 +149,7 @@ describe('ComicDetailsEditorComponent', () => {
});

it('contains an option to fetch volumes without skipping the cache', () => {
component.skipCache = false;
component.fetchOptions
.find(
option =>
Expand All @@ -159,6 +165,7 @@ describe('ComicDetailsEditorComponent', () => {
});

it('contains an option to fetch volumes while skipping the cache', () => {
component.skipCache = true;
component.fetchOptions
.find(
option =>
Expand Down Expand Up @@ -248,7 +255,6 @@ describe('ComicDetailsEditorComponent', () => {
describe('saving the API key', () => {
beforeEach(() => {
component.comicDetailsForm.controls['apiKey'].setValue(API_KEY);
spyOn(authenticationAdaptor, 'setPreference');
component.saveApiKey();
});

Expand All @@ -262,7 +268,6 @@ describe('ComicDetailsEditorComponent', () => {

describe('resetting the API key', () => {
beforeEach(() => {
spyOn(authenticationAdaptor, 'getPreference');
component.editingApiKey = true;
component.resetApiKey();
});
Expand Down Expand Up @@ -465,4 +470,60 @@ describe('ComicDetailsEditorComponent', () => {
);
});
});

describe('fetching volumes', () => {
beforeEach(() => {
spyOn(scrapingAdaptor, 'getVolumes');
component.comicDetailsForm.controls['apiKey'].setValue(API_KEY);
component.comicDetailsForm.controls['seriesName'].setValue(SERIES);
component.comicDetailsForm.controls['issueNumber'].setValue(ISSUE_NUMBER);
});

describe('skipping the cache', () => {
beforeEach(() => {
component.skipCache = true;
component.doFetchVolumes();
});

it('calls the scraping adaptor', () => {
expect(scrapingAdaptor.getVolumes).toHaveBeenCalledWith(
API_KEY,
SERIES,
ISSUE_NUMBER,
true
);
});
});

describe('using the cache', () => {
beforeEach(() => {
component.skipCache = false;
component.doFetchVolumes();
});

it('calls the scraping adaptor', () => {
expect(scrapingAdaptor.getVolumes).toHaveBeenCalledWith(
API_KEY,
SERIES,
ISSUE_NUMBER,
false
);
});
});
});

it('saves the skip cache preference if it is changed', () => {
component.skipCache = false;
component.getVolumes(!component.skipCache);
expect(authenticationAdaptor.setPreference).toHaveBeenCalledWith(
USER_PREFERENCE_SKIP_CACHE,
`${!component.skipCache}`
);
});

it('does not save the skip cache preference if it is not changed', () => {
component.skipCache = false;
component.getVolumes(component.skipCache);
expect(authenticationAdaptor.setPreference).not.toHaveBeenCalled();
});
});

0 comments on commit ec4dbee

Please sign in to comment.