From e43f04e56487c77d731026b6da854e5a44c5bf32 Mon Sep 17 00:00:00 2001 From: lotte Date: Wed, 8 Apr 2020 15:41:55 +0200 Subject: [PATCH] finished tests --- .../admin-workflow-page.component.ts | 2 +- ...arch-result-grid-element.component.spec.ts | 5 + ...ow-search-result-grid-element.component.ts | 8 +- ...in-workflow-grid-element.component.spec.ts | 23 +++- ...m-admin-workflow-grid-element.component.ts | 18 ++- ...arch-result-list-element.component.spec.ts | 5 + ...ow-search-result-list-element.component.ts | 8 +- ...in-workflow-list-element.component.spec.ts | 14 +- ...m-admin-workflow-list-element.component.ts | 9 +- ...w-item-admin-workflow-actions.component.ts | 4 +- ...orkflow-item-action-page.component.spec.ts | 124 ++++++++++++++++++ .../workflow-item-action-page.component.ts | 23 +++- .../workflow-item-delete.component.spec.ts | 52 +++++++- .../workflow-item-delete.component.ts | 10 ++ .../workflow-item-page.resolver.spec.ts | 29 ++++ .../workflow-item-page.resolver.ts | 8 +- .../workflow-item-send-back.component.spec.ts | 54 +++++++- .../workflow-item-send-back.component.ts | 10 ++ 18 files changed, 383 insertions(+), 23 deletions(-) create mode 100644 src/app/+workflowitems-edit-page/workflow-item-action-page.component.spec.ts create mode 100644 src/app/+workflowitems-edit-page/workflow-item-page.resolver.spec.ts diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-page.component.ts b/src/app/+admin/admin-workflow-page/admin-workflow-page.component.ts index 37ddc70692..8c86c8ec98 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-page.component.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-page.component.ts @@ -8,7 +8,7 @@ import { Context } from '../../core/shared/context.model'; }) /** - * Component that represents a search page for administrators + * Component that represents a workflow item search page for administrators */ export class AdminWorkflowPageComponent { /** diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/task-search-result/task-admin-workflow-search-result-grid-element.component.spec.ts b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/task-search-result/task-admin-workflow-search-result-grid-element.component.spec.ts index a2d88465d5..a2461bffda 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/task-search-result/task-admin-workflow-search-result-grid-element.component.spec.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/task-search-result/task-admin-workflow-search-result-grid-element.component.spec.ts @@ -21,6 +21,7 @@ import { SearchResult } from '../../../../../shared/search/search-result.model'; import { LinkService } from '../../../../../core/cache/builders/link.service'; import { getMockLinkService } from '../../../../../shared/mocks/mock-link-service'; import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model'; +import { followLink } from '../../../../../shared/utils/follow-link-config.model'; describe('TaskAdminWorkflowSearchResultGridElementComponent', () => { let component: TaskAdminWorkflowSearchResultGridElementComponent; @@ -79,4 +80,8 @@ describe('TaskAdminWorkflowSearchResultGridElementComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should retrieve the workflow item using the link service', () => { + expect(linkService.resolveLink).toHaveBeenCalledWith(searchResult.indexableObject, followLink('workflowitem')); + }); }); diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/task-search-result/task-admin-workflow-search-result-grid-element.component.ts b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/task-search-result/task-admin-workflow-search-result-grid-element.component.ts index 1f394fe134..cc002c87c0 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/task-search-result/task-admin-workflow-search-result-grid-element.component.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/task-search-result/task-admin-workflow-search-result-grid-element.component.ts @@ -24,15 +24,21 @@ import { BitstreamDataService } from '../../../../../core/data/bitstream-data.se templateUrl: './task-admin-workflow-search-result-grid-element.component.html' }) /** - * The component for displaying a list element for an pool task search result on the admin search page + * The component for displaying a list element for an task search result on the admin workflow search page */ export class TaskAdminWorkflowSearchResultGridElementComponent extends SearchResultGridElementComponent, TaskObject> implements OnInit { + /** + * The workflow item linked to the task object + */ public wfi$: Observable; constructor(private linkService: LinkService, protected truncatableService: TruncatableService, protected bitstreamService: BitstreamDataService) { super(truncatableService, bitstreamService); } + /** + * Initialize the workflow item + */ ngOnInit(): void { super.ngOnInit(); this.dso = this.linkService.resolveLink(this.dso, followLink('workflowitem')); diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-admin-workflow-grid-element.component.spec.ts b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-admin-workflow-grid-element.component.spec.ts index 917d3770bb..4d064444e5 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-admin-workflow-grid-element.component.spec.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-admin-workflow-grid-element.component.spec.ts @@ -3,8 +3,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { TranslateModule } from '@ngx-translate/core'; -import { mockTruncatableService } from '../../../../../shared/mocks/mock-trucatable.service'; -import { SharedModule } from '../../../../../shared/shared.module'; import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; import { CollectionElementLinkType } from '../../../../../shared/object-collection/collection-element-link.type'; import { ViewMode } from '../../../../../core/shared/view-mode.model'; @@ -13,17 +11,25 @@ import { WorkflowItemAdminWorkflowGridElementComponent } from './workflow-item-a import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model'; import { LinkService } from '../../../../../core/cache/builders/link.service'; import { getMockLinkService } from '../../../../../shared/mocks/mock-link-service'; +import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/testing/utils'; +import { followLink } from '../../../../../shared/utils/follow-link-config.model'; +import { Item } from '../../../../../core/shared/item.model'; +import { PublicationGridElementComponent } from '../../../../../shared/object-grid/item-grid-element/item-types/publication/publication-grid-element.component'; +import { ListableObjectDirective } from '../../../../../shared/object-collection/shared/listable-object/listable-object.directive'; describe('WorkflowItemAdminWorkflowGridElementComponent', () => { let component: WorkflowItemAdminWorkflowGridElementComponent; let fixture: ComponentFixture; let id; let wfi; + let itemRD$; let linkService; function init() { + itemRD$ = createSuccessfulRemoteDataObject$(new Item()); id = '780b2588-bda5-4112-a1cd-0b15000a5339'; wfi = new WorkflowItem(); + wfi.item = itemRD$; linkService = getMockLinkService(); } @@ -31,18 +37,23 @@ describe('WorkflowItemAdminWorkflowGridElementComponent', () => { init(); TestBed.configureTestingModule( { - declarations: [WorkflowItemAdminWorkflowGridElementComponent], + declarations: [WorkflowItemAdminWorkflowGridElementComponent, PublicationGridElementComponent, ListableObjectDirective], imports: [ NoopAnimationsModule, TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), - SharedModule ], providers: [ { provide: LinkService, useValue: linkService }, + { provide: TruncatableService, useValue: {} }, ], schemas: [NO_ERRORS_SCHEMA] }) + .overrideComponent(WorkflowItemAdminWorkflowGridElementComponent, { + set: { + entryComponents: [PublicationGridElementComponent] + } + }) .compileComponents(); })); @@ -60,4 +71,8 @@ describe('WorkflowItemAdminWorkflowGridElementComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should retrieve the item using the link service', () => { + expect(linkService.resolveLink).toHaveBeenCalledWith(wfi, followLink('item')); + }); }); diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-admin-workflow-grid-element.component.ts b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-admin-workflow-grid-element.component.ts index 2ee9f16f52..2139590e6e 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-admin-workflow-grid-element.component.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-admin-workflow-grid-element.component.ts @@ -36,12 +36,27 @@ import { take } from 'rxjs/operators'; templateUrl: './workflow-item-admin-workflow-grid-element.component.html' }) /** - * The component for displaying a list element for an workflow item on the admin search page + * The component for displaying a grid element for an workflow item on the admin workflow search page */ export class WorkflowItemAdminWorkflowGridElementComponent extends AbstractListableElementComponent { + /** + * Directive used to render the dynamic component in + */ @ViewChild(ListableObjectDirective, { static: true }) listableObjectDirective: ListableObjectDirective; + + /** + * The html child that contains the badges html + */ @ViewChild('badges', { static: true }) badges: ElementRef; + + /** + * The html child that contains the button html + */ @ViewChild('buttons', { static: true }) buttons: ElementRef; + + /** + * The item linked to the workflow item + */ public item$: Observable; constructor(private componentFactoryResolver: ComponentFactoryResolver, private linkService: LinkService) { @@ -50,6 +65,7 @@ export class WorkflowItemAdminWorkflowGridElementComponent extends AbstractLista /** * Setup the dynamic child component + * Initialize the item object from the workflow item */ ngOnInit(): void { this.object = this.linkService.resolveLink(this.object, followLink('item')); diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/task-item-search-result/task-admin-workflow-search-result-list-element.component.spec.ts b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/task-item-search-result/task-admin-workflow-search-result-list-element.component.spec.ts index 68ffe9e421..f67e653ea4 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/task-item-search-result/task-admin-workflow-search-result-list-element.component.spec.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/task-item-search-result/task-admin-workflow-search-result-list-element.component.spec.ts @@ -13,6 +13,7 @@ import { LinkService } from '../../../../../core/cache/builders/link.service'; import { getMockLinkService } from '../../../../../shared/mocks/mock-link-service'; import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model'; import { TaskObject } from '../../../../../core/tasks/models/task-object.model'; +import { followLink } from '../../../../../shared/utils/follow-link-config.model'; describe('TaskAdminWorkflowSearchResultListElementComponent', () => { let component: TaskAdminWorkflowSearchResultListElementComponent; @@ -60,4 +61,8 @@ describe('TaskAdminWorkflowSearchResultListElementComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should retrieve the workflow item using the link service', () => { + expect(linkService.resolveLink).toHaveBeenCalledWith(searchResult.indexableObject, followLink('workflowitem')); + }); }); diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/task-item-search-result/task-admin-workflow-search-result-list-element.component.ts b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/task-item-search-result/task-admin-workflow-search-result-list-element.component.ts index 2de768b747..04951f59eb 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/task-item-search-result/task-admin-workflow-search-result-list-element.component.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/task-item-search-result/task-admin-workflow-search-result-list-element.component.ts @@ -23,15 +23,21 @@ import { TruncatableService } from '../../../../../shared/truncatable/truncatabl templateUrl: './task-admin-workflow-search-result-list-element.component.html' }) /** - * The component for displaying a list element for an pool task search result on the admin search page + * The component for displaying a grid element for an task search result on the admin workflow search page */ export class TaskAdminWorkflowSearchResultListElementComponent extends SearchResultListElementComponent, TaskObject> { + /** + * The workflow item linked to the task object + */ public wfi$: Observable; constructor(private linkService: LinkService, protected truncatableService: TruncatableService) { super(truncatableService); } + /** + * Initialize the workflow item + */ ngOnInit(): void { super.ngOnInit(); this.dso = this.linkService.resolveLink(this.dso, followLink('workflowitem')); diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-admin-workflow-list-element.component.spec.ts b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-admin-workflow-list-element.component.spec.ts index af9bbbc70f..10a05a8b30 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-admin-workflow-list-element.component.spec.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-admin-workflow-list-element.component.spec.ts @@ -13,16 +13,25 @@ import { WorkflowItem } from '../../../../../core/submission/models/workflowitem import { WorkflowItemAdminWorkflowListElementComponent } from './workflow-item-admin-workflow-list-element.component'; import { LinkService } from '../../../../../core/cache/builders/link.service'; import { getMockLinkService } from '../../../../../shared/mocks/mock-link-service'; +import { createSuccessfulRemoteDataObject$ } from '../../../../../shared/testing/utils'; +import { followLink } from '../../../../../shared/utils/follow-link-config.model'; +import { Item } from '../../../../../core/shared/item.model'; +import { PublicationGridElementComponent } from '../../../../../shared/object-grid/item-grid-element/item-types/publication/publication-grid-element.component'; +import { AdminSidebarSectionComponent } from '../../../../admin-sidebar/admin-sidebar-section/admin-sidebar-section.component'; describe('WorkflowItemAdminWorkflowListElementComponent', () => { let component: WorkflowItemAdminWorkflowListElementComponent; let fixture: ComponentFixture; let id; let wfi; + let itemRD$; let linkService; + function init() { + itemRD$ = createSuccessfulRemoteDataObject$(new Item()); id = '780b2588-bda5-4112-a1cd-0b15000a5339'; wfi = new WorkflowItem(); + wfi.item = itemRD$; linkService = getMockLinkService(); } @@ -35,7 +44,6 @@ describe('WorkflowItemAdminWorkflowListElementComponent', () => { NoopAnimationsModule, TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), - SharedModule ], providers: [ { provide: TruncatableService, useValue: mockTruncatableService }, @@ -60,4 +68,8 @@ describe('WorkflowItemAdminWorkflowListElementComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should retrieve the item using the link service', () => { + expect(linkService.resolveLink).toHaveBeenCalledWith(wfi, followLink('item')); + }); }); diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-admin-workflow-list-element.component.ts b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-admin-workflow-list-element.component.ts index 7681d7e75d..835d6acfbb 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-admin-workflow-list-element.component.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-admin-workflow-list-element.component.ts @@ -18,15 +18,22 @@ import { Item } from '../../../../../core/shared/item.model'; templateUrl: './workflow-item-admin-workflow-list-element.component.html' }) /** - * The component for displaying a list element for an workflow item on the admin search page + * The component for displaying a list element for an workflow item on the admin workflow search page */ export class WorkflowItemAdminWorkflowListElementComponent extends AbstractListableElementComponent implements OnInit { + + /** + * The item linked to the workflow item + */ public item$: Observable; constructor(private linkService: LinkService) { super(); } + /** + * Initialize the item object from the workflow item + */ ngOnInit(): void { this.object = this.linkService.resolveLink(this.object, followLink('item')); this.item$ = (this.object.item as Observable>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload()); diff --git a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/workflow-item-admin-workflow-actions.component.ts b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/workflow-item-admin-workflow-actions.component.ts index 58f89e31e6..2109357b81 100644 --- a/src/app/+admin/admin-workflow-page/admin-workflow-search-results/workflow-item-admin-workflow-actions.component.ts +++ b/src/app/+admin/admin-workflow-page/admin-workflow-search-results/workflow-item-admin-workflow-actions.component.ts @@ -8,11 +8,11 @@ import { getWorkflowItemDeletePath, getWorkflowItemSendBackPath } from '../../.. templateUrl: './workflow-item-admin-workflow-actions.component.html' }) /** - * The component for displaying the actions for a list element for an item on the admin workflow page + * The component for displaying the actions for a list element for an item on the admin workflow search page */ export class WorkflowItemAdminWorkflowActionsComponent { /** - * The item to perform the actions on + * The workflow item to perform the actions on */ @Input() public wfi: WorkflowItem; diff --git a/src/app/+workflowitems-edit-page/workflow-item-action-page.component.spec.ts b/src/app/+workflowitems-edit-page/workflow-item-action-page.component.spec.ts new file mode 100644 index 0000000000..71d9346b29 --- /dev/null +++ b/src/app/+workflowitems-edit-page/workflow-item-action-page.component.spec.ts @@ -0,0 +1,124 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; +import { WorkflowItemActionPageComponent } from './workflow-item-action-page.component'; +import { MockTranslateLoader } from '../shared/mocks/mock-translate-loader'; +import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../shared/testing/utils'; +import { ActivatedRouteStub } from '../shared/testing/active-router-stub'; +import { NotificationsServiceStub } from '../shared/testing/notifications-service-stub'; +import { NotificationsService } from '../shared/notifications/notifications.service'; +import { RouteService } from '../core/services/route.service'; +import { RouterStub } from '../shared/testing/router-stub'; +import { Component, NO_ERRORS_SCHEMA } from '@angular/core'; +import { WorkflowItemDataService } from '../core/submission/workflowitem-data.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { WorkflowItem } from '../core/submission/models/workflowitem.model'; +import { Observable, of as observableOf } from 'rxjs'; +import { VarDirective } from '../shared/utils/var.directive'; +import { By } from '@angular/platform-browser'; + +const type = 'testType'; +describe('WorkflowItemActionPageComponent', () => { + let component: WorkflowItemActionPageComponent; + let fixture: ComponentFixture; + let wfiService; + let wfi; + let itemRD$; + let id; + + function init() { + wfiService = jasmine.createSpyObj('workflowItemService', { + sendBack: observableOf(true) + }); + itemRD$ = createSuccessfulRemoteDataObject$(itemRD$); + wfi = new WorkflowItem(); + wfi.item = itemRD$; + id = 'de11b5e5-064a-4e98-a7ac-a1a6a65ddf80'; + } + + beforeEach(async(() => { + init(); + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: MockTranslateLoader + } + })], + declarations: [TestComponent, VarDirective], + providers: [ + { provide: ActivatedRoute, useValue: new ActivatedRouteStub({}, { wfi: createSuccessfulRemoteDataObject(wfi) }) }, + { provide: Router, useClass: RouterStub }, + { provide: RouteService, useValue: {} }, + { provide: NotificationsService, useClass: NotificationsServiceStub }, + { provide: WorkflowItemDataService, useValue: wfiService }, + ], + schemas: [NO_ERRORS_SCHEMA] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TestComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should set the initial type correctly', () => { + expect(component.type).toEqual(type); + }); + + describe('clicking the button with class btn-danger', () => { + beforeEach(() => { + spyOn(component, 'performAction'); + }); + + it('should call performAction on clicking the btn-danger', () => { + const button = fixture.debugElement.query(By.css('.btn-danger')).nativeElement; + button.click(); + fixture.detectChanges(); + expect(component.performAction).toHaveBeenCalled(); + }); + }); + + describe('clicking the button with class btn-default', () => { + beforeEach(() => { + spyOn(component, 'previousPage'); + }); + + it('should call performAction on clicking the btn-default', () => { + const button = fixture.debugElement.query(By.css('.btn-default')).nativeElement; + button.click(); + fixture.detectChanges(); + expect(component.previousPage).toHaveBeenCalled(); + }); + }); +}); + +@Component({ + selector: 'ds-workflow-item-test-action-page', + templateUrl: 'workflow-item-action-page.component.html' + } +) +class TestComponent extends WorkflowItemActionPageComponent { + constructor(protected route: ActivatedRoute, + protected workflowItemService: WorkflowItemDataService, + protected router: Router, + protected routeService: RouteService, + protected notificationsService: NotificationsService, + protected translationService: TranslateService) { + super(route, workflowItemService, router, routeService, notificationsService, translationService); + } + + getType(): string { + return type; + } + + sendRequest(id: string): Observable { + return observableOf(true); + } +} diff --git a/src/app/+workflowitems-edit-page/workflow-item-action-page.component.ts b/src/app/+workflowitems-edit-page/workflow-item-action-page.component.ts index fcc943a741..2859ca3e44 100644 --- a/src/app/+workflowitems-edit-page/workflow-item-action-page.component.ts +++ b/src/app/+workflowitems-edit-page/workflow-item-action-page.component.ts @@ -12,6 +12,9 @@ import { RemoteData } from '../core/data/remote-data'; import { getAllSucceededRemoteData, getRemoteDataPayload } from '../core/shared/operators'; import { isEmpty } from '../shared/empty.util'; +/** + * Abstract component representing a page to perform an action on a workflow item + */ export abstract class WorkflowItemActionPageComponent implements OnInit { public type; public wfi$: Observable; @@ -25,12 +28,18 @@ export abstract class WorkflowItemActionPageComponent implements OnInit { protected translationService: TranslateService) { } + /** + * Sets up the type, workflow item and its item object + */ ngOnInit() { this.type = this.getType(); this.wfi$ = this.route.data.pipe(map((data: Data) => data.wfi as RemoteData), getRemoteDataPayload()); this.item$ = this.wfi$.pipe(switchMap((wfi: WorkflowItem) => (wfi.item as Observable>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload()))); } + /** + * Performs the action and shows a notification based on the outcome of the action + */ performAction() { this.wfi$.pipe( take(1), @@ -49,6 +58,10 @@ export abstract class WorkflowItemActionPageComponent implements OnInit { }) } + /** + * Navigates to the previous url + * If there's not previous url, it continues to the mydspace page instead + */ previousPage() { this.routeService.getPreviousUrl().pipe(take(1)) .subscribe((url) => { @@ -56,10 +69,18 @@ export abstract class WorkflowItemActionPageComponent implements OnInit { url = '/mydspace'; } this.router.navigateByUrl(url); - } ); } + + /** + * Performs the action of this workflow item action page + * @param id The id of the WorkflowItem + */ abstract sendRequest(id: string): Observable; + + /** + * Returns the type of page + */ abstract getType(): string; } diff --git a/src/app/+workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.spec.ts b/src/app/+workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.spec.ts index b42fe965c1..d2c093ff4b 100644 --- a/src/app/+workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.spec.ts +++ b/src/app/+workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.spec.ts @@ -1,16 +1,59 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { WorkflowItemDeleteComponent } from './workflow-item-delete.component'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { MockTranslateLoader } from '../../shared/mocks/mock-translate-loader'; +import { ActivatedRoute, Router } from '@angular/router'; +import { RouterStub } from '../../shared/testing/router-stub'; +import { ActivatedRouteStub } from '../../shared/testing/active-router-stub'; +import { RouteService } from '../../core/services/route.service'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { WorkflowItemDataService } from '../../core/submission/workflowitem-data.service'; +import { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub'; +import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils'; +import { WorkflowItem } from '../../core/submission/models/workflowitem.model'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { VarDirective } from '../../shared/utils/var.directive'; +import { of as observableOf } from 'rxjs'; describe('WorkflowItemDeleteComponent', () => { let component: WorkflowItemDeleteComponent; let fixture: ComponentFixture; + let wfiService; + let wfi; + let itemRD$; + let id; + + function init() { + wfiService = jasmine.createSpyObj('workflowItemService', { + delete: observableOf(true) + }); + itemRD$ = createSuccessfulRemoteDataObject$(itemRD$); + wfi = new WorkflowItem(); + wfi.item = itemRD$; + id = 'de11b5e5-064a-4e98-a7ac-a1a6a65ddf80'; + } beforeEach(async(() => { + init(); TestBed.configureTestingModule({ - declarations: [ WorkflowItemDeleteComponent ] + imports: [TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: MockTranslateLoader + } + })], + declarations: [WorkflowItemDeleteComponent, VarDirective], + providers: [ + { provide: ActivatedRoute, useValue: new ActivatedRouteStub({}, { wfi: createSuccessfulRemoteDataObject(wfi) }) }, + { provide: Router, useClass: RouterStub }, + { provide: RouteService, useValue: {} }, + { provide: NotificationsService, useClass: NotificationsServiceStub }, + { provide: WorkflowItemDataService, useValue: wfiService }, + ], + schemas: [NO_ERRORS_SCHEMA] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { @@ -22,4 +65,9 @@ describe('WorkflowItemDeleteComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should call delete on the workflow-item service when sendRequest is called', () => { + component.sendRequest(id); + expect(wfiService.delete).toHaveBeenCalledWith(id); + }); }); diff --git a/src/app/+workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts b/src/app/+workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts index 171aeb27d1..73111bdf2b 100644 --- a/src/app/+workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts +++ b/src/app/+workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts @@ -11,6 +11,9 @@ import { TranslateService } from '@ngx-translate/core'; selector: 'ds-workflow-item-delete', templateUrl: '../workflow-item-action-page.component.html' }) +/** + * Component representing a page to delete a workflow item + */ export class WorkflowItemDeleteComponent extends WorkflowItemActionPageComponent { constructor(protected route: ActivatedRoute, protected workflowItemService: WorkflowItemDataService, @@ -21,10 +24,17 @@ export class WorkflowItemDeleteComponent extends WorkflowItemActionPageComponent super(route, workflowItemService, router, routeService, notificationsService, translationService); } + /** + * Returns the type of page + */ getType(): string { return 'delete'; } + /** + * Performs the action of this workflow item action page + * @param id The id of the WorkflowItem + */ sendRequest(id: string): Observable { return this.workflowItemService.delete(id); } diff --git a/src/app/+workflowitems-edit-page/workflow-item-page.resolver.spec.ts b/src/app/+workflowitems-edit-page/workflow-item-page.resolver.spec.ts new file mode 100644 index 0000000000..792c642ec7 --- /dev/null +++ b/src/app/+workflowitems-edit-page/workflow-item-page.resolver.spec.ts @@ -0,0 +1,29 @@ +import { first } from 'rxjs/operators'; +import { of as observableOf } from 'rxjs'; +import { WorkflowItemPageResolver } from './workflow-item-page.resolver'; +import { WorkflowItemDataService } from '../core/submission/workflowitem-data.service'; + +describe('WorkflowItemPageResolver', () => { + describe('resolve', () => { + let resolver: WorkflowItemPageResolver; + let wfiService: WorkflowItemDataService; + const uuid = '1234-65487-12354-1235'; + + beforeEach(() => { + wfiService = { + findById: (id: string) => observableOf({ payload: { id }, hasSucceeded: true }) as any + } as any; + resolver = new WorkflowItemPageResolver(wfiService); + }); + + it('should resolve a workflow item with the correct id', () => { + resolver.resolve({ params: { id: uuid } } as any, undefined) + .pipe(first()) + .subscribe( + (resolved) => { + expect(resolved.payload.id).toEqual(uuid); + } + ); + }); + }); +}); diff --git a/src/app/+workflowitems-edit-page/workflow-item-page.resolver.ts b/src/app/+workflowitems-edit-page/workflow-item-page.resolver.ts index 5ae11efff6..19cc4b4914 100644 --- a/src/app/+workflowitems-edit-page/workflow-item-page.resolver.ts +++ b/src/app/+workflowitems-edit-page/workflow-item-page.resolver.ts @@ -2,8 +2,6 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs'; import { RemoteData } from '../core/data/remote-data'; -import { ItemDataService } from '../core/data/item-data.service'; -import { Item } from '../core/shared/item.model'; import { hasValue } from '../shared/empty.util'; import { find } from 'rxjs/operators'; import { followLink } from '../shared/utils/follow-link-config.model'; @@ -11,7 +9,7 @@ import { WorkflowItemDataService } from '../core/submission/workflowitem-data.se import { WorkflowItem } from '../core/submission/models/workflowitem.model'; /** - * This class represents a resolver that requests a specific item before the route is activated + * This class represents a resolver that requests a specific workflow item before the route is activated */ @Injectable() export class WorkflowItemPageResolver implements Resolve> { @@ -19,10 +17,10 @@ export class WorkflowItemPageResolver implements Resolve> Emits the found item based on the parameters in the current route, + * @returns Observable<> Emits the found workflow item based on the parameters in the current route, * or an error if something went wrong */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable> { diff --git a/src/app/+workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.spec.ts b/src/app/+workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.spec.ts index e76e01b7f3..daf58450e4 100644 --- a/src/app/+workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.spec.ts +++ b/src/app/+workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.spec.ts @@ -1,16 +1,59 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { WorkflowItemSendBackComponent } from './workflow-item-send-back.component'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { MockTranslateLoader } from '../../shared/mocks/mock-translate-loader'; +import { ActivatedRoute, Router } from '@angular/router'; +import { RouterStub } from '../../shared/testing/router-stub'; +import { ActivatedRouteStub } from '../../shared/testing/active-router-stub'; +import { RouteService } from '../../core/services/route.service'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { WorkflowItemDataService } from '../../core/submission/workflowitem-data.service'; +import { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub'; +import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/testing/utils'; +import { WorkflowItem } from '../../core/submission/models/workflowitem.model'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { VarDirective } from '../../shared/utils/var.directive'; +import { of as observableOf } from 'rxjs'; +import { WorkflowItemSendBackComponent } from './workflow-item-send-back.component'; describe('WorkflowItemSendBackComponent', () => { let component: WorkflowItemSendBackComponent; let fixture: ComponentFixture; + let wfiService; + let wfi; + let itemRD$; + let id; + + function init() { + wfiService = jasmine.createSpyObj('workflowItemService', { + sendBack: observableOf(true) + }); + itemRD$ = createSuccessfulRemoteDataObject$(itemRD$); + wfi = new WorkflowItem(); + wfi.item = itemRD$; + id = 'de11b5e5-064a-4e98-a7ac-a1a6a65ddf80'; + } beforeEach(async(() => { + init(); TestBed.configureTestingModule({ - declarations: [ WorkflowItemSendBackComponent ] + imports: [TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: MockTranslateLoader + } + })], + declarations: [WorkflowItemSendBackComponent, VarDirective], + providers: [ + { provide: ActivatedRoute, useValue: new ActivatedRouteStub({}, { wfi: createSuccessfulRemoteDataObject(wfi) }) }, + { provide: Router, useClass: RouterStub }, + { provide: RouteService, useValue: {} }, + { provide: NotificationsService, useClass: NotificationsServiceStub }, + { provide: WorkflowItemDataService, useValue: wfiService }, + ], + schemas: [NO_ERRORS_SCHEMA] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { @@ -22,4 +65,9 @@ describe('WorkflowItemSendBackComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should call sendBack on the workflow-item service when sendRequest is called', () => { + component.sendRequest(id); + expect(wfiService.sendBack).toHaveBeenCalledWith(id); + }); }); diff --git a/src/app/+workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts b/src/app/+workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts index c4006811d9..6e9a2e841e 100644 --- a/src/app/+workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts +++ b/src/app/+workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts @@ -11,6 +11,9 @@ import { TranslateService } from '@ngx-translate/core'; selector: 'ds-workflow-item-send-back', templateUrl: '../workflow-item-action-page.component.html' }) +/** + * Component representing a page to send back a workflow item to the submitter + */ export class WorkflowItemSendBackComponent extends WorkflowItemActionPageComponent { constructor(protected route: ActivatedRoute, protected workflowItemService: WorkflowItemDataService, @@ -21,10 +24,17 @@ export class WorkflowItemSendBackComponent extends WorkflowItemActionPageCompone super(route, workflowItemService, router, routeService, notificationsService, translationService); } + /** + * Returns the type of page + */ getType(): string { return 'send-back'; } + /** + * Performs the action of this workflow item action page + * @param id The id of the WorkflowItem + */ sendRequest(id: string): Observable { return this.workflowItemService.sendBack(id); }