finished tests

This commit is contained in:
lotte
2020-04-08 15:41:55 +02:00
parent d003400c16
commit e43f04e564
18 changed files with 383 additions and 23 deletions

View File

@@ -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 { export class AdminWorkflowPageComponent {
/** /**

View File

@@ -21,6 +21,7 @@ import { SearchResult } from '../../../../../shared/search/search-result.model';
import { LinkService } from '../../../../../core/cache/builders/link.service'; import { LinkService } from '../../../../../core/cache/builders/link.service';
import { getMockLinkService } from '../../../../../shared/mocks/mock-link-service'; import { getMockLinkService } from '../../../../../shared/mocks/mock-link-service';
import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model'; import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model';
import { followLink } from '../../../../../shared/utils/follow-link-config.model';
describe('TaskAdminWorkflowSearchResultGridElementComponent', () => { describe('TaskAdminWorkflowSearchResultGridElementComponent', () => {
let component: TaskAdminWorkflowSearchResultGridElementComponent; let component: TaskAdminWorkflowSearchResultGridElementComponent;
@@ -79,4 +80,8 @@ describe('TaskAdminWorkflowSearchResultGridElementComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should retrieve the workflow item using the link service', () => {
expect(linkService.resolveLink).toHaveBeenCalledWith(searchResult.indexableObject, followLink('workflowitem'));
});
}); });

View File

@@ -24,15 +24,21 @@ import { BitstreamDataService } from '../../../../../core/data/bitstream-data.se
templateUrl: './task-admin-workflow-search-result-grid-element.component.html' 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<SearchResult<TaskObject>, TaskObject> implements OnInit { export class TaskAdminWorkflowSearchResultGridElementComponent extends SearchResultGridElementComponent<SearchResult<TaskObject>, TaskObject> implements OnInit {
/**
* The workflow item linked to the task object
*/
public wfi$: Observable<WorkflowItem>; public wfi$: Observable<WorkflowItem>;
constructor(private linkService: LinkService, protected truncatableService: TruncatableService, protected bitstreamService: BitstreamDataService) { constructor(private linkService: LinkService, protected truncatableService: TruncatableService, protected bitstreamService: BitstreamDataService) {
super(truncatableService, bitstreamService); super(truncatableService, bitstreamService);
} }
/**
* Initialize the workflow item
*/
ngOnInit(): void { ngOnInit(): void {
super.ngOnInit(); super.ngOnInit();
this.dso = this.linkService.resolveLink(this.dso, followLink('workflowitem')); this.dso = this.linkService.resolveLink(this.dso, followLink('workflowitem'));

View File

@@ -3,8 +3,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { TranslateModule } from '@ngx-translate/core'; 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 { TruncatableService } from '../../../../../shared/truncatable/truncatable.service';
import { CollectionElementLinkType } from '../../../../../shared/object-collection/collection-element-link.type'; import { CollectionElementLinkType } from '../../../../../shared/object-collection/collection-element-link.type';
import { ViewMode } from '../../../../../core/shared/view-mode.model'; 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 { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model';
import { LinkService } from '../../../../../core/cache/builders/link.service'; import { LinkService } from '../../../../../core/cache/builders/link.service';
import { getMockLinkService } from '../../../../../shared/mocks/mock-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', () => { describe('WorkflowItemAdminWorkflowGridElementComponent', () => {
let component: WorkflowItemAdminWorkflowGridElementComponent; let component: WorkflowItemAdminWorkflowGridElementComponent;
let fixture: ComponentFixture<WorkflowItemAdminWorkflowGridElementComponent>; let fixture: ComponentFixture<WorkflowItemAdminWorkflowGridElementComponent>;
let id; let id;
let wfi; let wfi;
let itemRD$;
let linkService; let linkService;
function init() { function init() {
itemRD$ = createSuccessfulRemoteDataObject$(new Item());
id = '780b2588-bda5-4112-a1cd-0b15000a5339'; id = '780b2588-bda5-4112-a1cd-0b15000a5339';
wfi = new WorkflowItem(); wfi = new WorkflowItem();
wfi.item = itemRD$;
linkService = getMockLinkService(); linkService = getMockLinkService();
} }
@@ -31,18 +37,23 @@ describe('WorkflowItemAdminWorkflowGridElementComponent', () => {
init(); init();
TestBed.configureTestingModule( TestBed.configureTestingModule(
{ {
declarations: [WorkflowItemAdminWorkflowGridElementComponent], declarations: [WorkflowItemAdminWorkflowGridElementComponent, PublicationGridElementComponent, ListableObjectDirective],
imports: [ imports: [
NoopAnimationsModule, NoopAnimationsModule,
TranslateModule.forRoot(), TranslateModule.forRoot(),
RouterTestingModule.withRoutes([]), RouterTestingModule.withRoutes([]),
SharedModule
], ],
providers: [ providers: [
{ provide: LinkService, useValue: linkService }, { provide: LinkService, useValue: linkService },
{ provide: TruncatableService, useValue: {} },
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
}) })
.overrideComponent(WorkflowItemAdminWorkflowGridElementComponent, {
set: {
entryComponents: [PublicationGridElementComponent]
}
})
.compileComponents(); .compileComponents();
})); }));
@@ -60,4 +71,8 @@ describe('WorkflowItemAdminWorkflowGridElementComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should retrieve the item using the link service', () => {
expect(linkService.resolveLink).toHaveBeenCalledWith(wfi, followLink('item'));
});
}); });

View File

@@ -36,12 +36,27 @@ import { take } from 'rxjs/operators';
templateUrl: './workflow-item-admin-workflow-grid-element.component.html' 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<WorkflowItem> { export class WorkflowItemAdminWorkflowGridElementComponent extends AbstractListableElementComponent<WorkflowItem> {
/**
* Directive used to render the dynamic component in
*/
@ViewChild(ListableObjectDirective, { static: true }) listableObjectDirective: ListableObjectDirective; @ViewChild(ListableObjectDirective, { static: true }) listableObjectDirective: ListableObjectDirective;
/**
* The html child that contains the badges html
*/
@ViewChild('badges', { static: true }) badges: ElementRef; @ViewChild('badges', { static: true }) badges: ElementRef;
/**
* The html child that contains the button html
*/
@ViewChild('buttons', { static: true }) buttons: ElementRef; @ViewChild('buttons', { static: true }) buttons: ElementRef;
/**
* The item linked to the workflow item
*/
public item$: Observable<Item>; public item$: Observable<Item>;
constructor(private componentFactoryResolver: ComponentFactoryResolver, private linkService: LinkService) { constructor(private componentFactoryResolver: ComponentFactoryResolver, private linkService: LinkService) {
@@ -50,6 +65,7 @@ export class WorkflowItemAdminWorkflowGridElementComponent extends AbstractLista
/** /**
* Setup the dynamic child component * Setup the dynamic child component
* Initialize the item object from the workflow item
*/ */
ngOnInit(): void { ngOnInit(): void {
this.object = this.linkService.resolveLink(this.object, followLink('item')); this.object = this.linkService.resolveLink(this.object, followLink('item'));

View File

@@ -13,6 +13,7 @@ import { LinkService } from '../../../../../core/cache/builders/link.service';
import { getMockLinkService } from '../../../../../shared/mocks/mock-link-service'; import { getMockLinkService } from '../../../../../shared/mocks/mock-link-service';
import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model'; import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model';
import { TaskObject } from '../../../../../core/tasks/models/task-object.model'; import { TaskObject } from '../../../../../core/tasks/models/task-object.model';
import { followLink } from '../../../../../shared/utils/follow-link-config.model';
describe('TaskAdminWorkflowSearchResultListElementComponent', () => { describe('TaskAdminWorkflowSearchResultListElementComponent', () => {
let component: TaskAdminWorkflowSearchResultListElementComponent; let component: TaskAdminWorkflowSearchResultListElementComponent;
@@ -60,4 +61,8 @@ describe('TaskAdminWorkflowSearchResultListElementComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should retrieve the workflow item using the link service', () => {
expect(linkService.resolveLink).toHaveBeenCalledWith(searchResult.indexableObject, followLink('workflowitem'));
});
}); });

View File

@@ -23,15 +23,21 @@ import { TruncatableService } from '../../../../../shared/truncatable/truncatabl
templateUrl: './task-admin-workflow-search-result-list-element.component.html' 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<SearchResult<TaskObject>, TaskObject> { export class TaskAdminWorkflowSearchResultListElementComponent extends SearchResultListElementComponent<SearchResult<TaskObject>, TaskObject> {
/**
* The workflow item linked to the task object
*/
public wfi$: Observable<WorkflowItem>; public wfi$: Observable<WorkflowItem>;
constructor(private linkService: LinkService, protected truncatableService: TruncatableService) { constructor(private linkService: LinkService, protected truncatableService: TruncatableService) {
super(truncatableService); super(truncatableService);
} }
/**
* Initialize the workflow item
*/
ngOnInit(): void { ngOnInit(): void {
super.ngOnInit(); super.ngOnInit();
this.dso = this.linkService.resolveLink(this.dso, followLink('workflowitem')); this.dso = this.linkService.resolveLink(this.dso, followLink('workflowitem'));

View File

@@ -13,16 +13,25 @@ import { WorkflowItem } from '../../../../../core/submission/models/workflowitem
import { WorkflowItemAdminWorkflowListElementComponent } from './workflow-item-admin-workflow-list-element.component'; import { WorkflowItemAdminWorkflowListElementComponent } from './workflow-item-admin-workflow-list-element.component';
import { LinkService } from '../../../../../core/cache/builders/link.service'; import { LinkService } from '../../../../../core/cache/builders/link.service';
import { getMockLinkService } from '../../../../../shared/mocks/mock-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', () => { describe('WorkflowItemAdminWorkflowListElementComponent', () => {
let component: WorkflowItemAdminWorkflowListElementComponent; let component: WorkflowItemAdminWorkflowListElementComponent;
let fixture: ComponentFixture<WorkflowItemAdminWorkflowListElementComponent>; let fixture: ComponentFixture<WorkflowItemAdminWorkflowListElementComponent>;
let id; let id;
let wfi; let wfi;
let itemRD$;
let linkService; let linkService;
function init() { function init() {
itemRD$ = createSuccessfulRemoteDataObject$(new Item());
id = '780b2588-bda5-4112-a1cd-0b15000a5339'; id = '780b2588-bda5-4112-a1cd-0b15000a5339';
wfi = new WorkflowItem(); wfi = new WorkflowItem();
wfi.item = itemRD$;
linkService = getMockLinkService(); linkService = getMockLinkService();
} }
@@ -35,7 +44,6 @@ describe('WorkflowItemAdminWorkflowListElementComponent', () => {
NoopAnimationsModule, NoopAnimationsModule,
TranslateModule.forRoot(), TranslateModule.forRoot(),
RouterTestingModule.withRoutes([]), RouterTestingModule.withRoutes([]),
SharedModule
], ],
providers: [ providers: [
{ provide: TruncatableService, useValue: mockTruncatableService }, { provide: TruncatableService, useValue: mockTruncatableService },
@@ -60,4 +68,8 @@ describe('WorkflowItemAdminWorkflowListElementComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should retrieve the item using the link service', () => {
expect(linkService.resolveLink).toHaveBeenCalledWith(wfi, followLink('item'));
});
}); });

View File

@@ -18,15 +18,22 @@ import { Item } from '../../../../../core/shared/item.model';
templateUrl: './workflow-item-admin-workflow-list-element.component.html' 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<WorkflowItem> implements OnInit { export class WorkflowItemAdminWorkflowListElementComponent extends AbstractListableElementComponent<WorkflowItem> implements OnInit {
/**
* The item linked to the workflow item
*/
public item$: Observable<Item>; public item$: Observable<Item>;
constructor(private linkService: LinkService) { constructor(private linkService: LinkService) {
super(); super();
} }
/**
* Initialize the item object from the workflow item
*/
ngOnInit(): void { ngOnInit(): void {
this.object = this.linkService.resolveLink(this.object, followLink('item')); this.object = this.linkService.resolveLink(this.object, followLink('item'));
this.item$ = (this.object.item as Observable<RemoteData<Item>>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload()); this.item$ = (this.object.item as Observable<RemoteData<Item>>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload());

View File

@@ -8,11 +8,11 @@ import { getWorkflowItemDeletePath, getWorkflowItemSendBackPath } from '../../..
templateUrl: './workflow-item-admin-workflow-actions.component.html' 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 { export class WorkflowItemAdminWorkflowActionsComponent {
/** /**
* The item to perform the actions on * The workflow item to perform the actions on
*/ */
@Input() public wfi: WorkflowItem; @Input() public wfi: WorkflowItem;

View File

@@ -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<WorkflowItemActionPageComponent>;
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<boolean> {
return observableOf(true);
}
}

View File

@@ -12,6 +12,9 @@ import { RemoteData } from '../core/data/remote-data';
import { getAllSucceededRemoteData, getRemoteDataPayload } from '../core/shared/operators'; import { getAllSucceededRemoteData, getRemoteDataPayload } from '../core/shared/operators';
import { isEmpty } from '../shared/empty.util'; 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 { export abstract class WorkflowItemActionPageComponent implements OnInit {
public type; public type;
public wfi$: Observable<WorkflowItem>; public wfi$: Observable<WorkflowItem>;
@@ -25,12 +28,18 @@ export abstract class WorkflowItemActionPageComponent implements OnInit {
protected translationService: TranslateService) { protected translationService: TranslateService) {
} }
/**
* Sets up the type, workflow item and its item object
*/
ngOnInit() { ngOnInit() {
this.type = this.getType(); this.type = this.getType();
this.wfi$ = this.route.data.pipe(map((data: Data) => data.wfi as RemoteData<WorkflowItem>), getRemoteDataPayload()); this.wfi$ = this.route.data.pipe(map((data: Data) => data.wfi as RemoteData<WorkflowItem>), getRemoteDataPayload());
this.item$ = this.wfi$.pipe(switchMap((wfi: WorkflowItem) => (wfi.item as Observable<RemoteData<Item>>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload()))); this.item$ = this.wfi$.pipe(switchMap((wfi: WorkflowItem) => (wfi.item as Observable<RemoteData<Item>>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload())));
} }
/**
* Performs the action and shows a notification based on the outcome of the action
*/
performAction() { performAction() {
this.wfi$.pipe( this.wfi$.pipe(
take(1), 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() { previousPage() {
this.routeService.getPreviousUrl().pipe(take(1)) this.routeService.getPreviousUrl().pipe(take(1))
.subscribe((url) => { .subscribe((url) => {
@@ -56,10 +69,18 @@ export abstract class WorkflowItemActionPageComponent implements OnInit {
url = '/mydspace'; url = '/mydspace';
} }
this.router.navigateByUrl(url); 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<boolean>; abstract sendRequest(id: string): Observable<boolean>;
/**
* Returns the type of page
*/
abstract getType(): string; abstract getType(): string;
} }

View File

@@ -1,16 +1,59 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WorkflowItemDeleteComponent } from './workflow-item-delete.component'; 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', () => { describe('WorkflowItemDeleteComponent', () => {
let component: WorkflowItemDeleteComponent; let component: WorkflowItemDeleteComponent;
let fixture: ComponentFixture<WorkflowItemDeleteComponent>; let fixture: ComponentFixture<WorkflowItemDeleteComponent>;
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(() => { beforeEach(async(() => {
init();
TestBed.configureTestingModule({ 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(() => { beforeEach(() => {
@@ -22,4 +65,9 @@ describe('WorkflowItemDeleteComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should call delete on the workflow-item service when sendRequest is called', () => {
component.sendRequest(id);
expect(wfiService.delete).toHaveBeenCalledWith(id);
});
}); });

View File

@@ -11,6 +11,9 @@ import { TranslateService } from '@ngx-translate/core';
selector: 'ds-workflow-item-delete', selector: 'ds-workflow-item-delete',
templateUrl: '../workflow-item-action-page.component.html' templateUrl: '../workflow-item-action-page.component.html'
}) })
/**
* Component representing a page to delete a workflow item
*/
export class WorkflowItemDeleteComponent extends WorkflowItemActionPageComponent { export class WorkflowItemDeleteComponent extends WorkflowItemActionPageComponent {
constructor(protected route: ActivatedRoute, constructor(protected route: ActivatedRoute,
protected workflowItemService: WorkflowItemDataService, protected workflowItemService: WorkflowItemDataService,
@@ -21,10 +24,17 @@ export class WorkflowItemDeleteComponent extends WorkflowItemActionPageComponent
super(route, workflowItemService, router, routeService, notificationsService, translationService); super(route, workflowItemService, router, routeService, notificationsService, translationService);
} }
/**
* Returns the type of page
*/
getType(): string { getType(): string {
return 'delete'; return 'delete';
} }
/**
* Performs the action of this workflow item action page
* @param id The id of the WorkflowItem
*/
sendRequest(id: string): Observable<boolean> { sendRequest(id: string): Observable<boolean> {
return this.workflowItemService.delete(id); return this.workflowItemService.delete(id);
} }

View File

@@ -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);
}
);
});
});
});

View File

@@ -2,8 +2,6 @@ import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { RemoteData } from '../core/data/remote-data'; 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 { hasValue } from '../shared/empty.util';
import { find } from 'rxjs/operators'; import { find } from 'rxjs/operators';
import { followLink } from '../shared/utils/follow-link-config.model'; 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'; 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() @Injectable()
export class WorkflowItemPageResolver implements Resolve<RemoteData<WorkflowItem>> { export class WorkflowItemPageResolver implements Resolve<RemoteData<WorkflowItem>> {
@@ -19,10 +17,10 @@ export class WorkflowItemPageResolver implements Resolve<RemoteData<WorkflowItem
} }
/** /**
* Method for resolving an item based on the parameters in the current route * Method for resolving a workflow item based on the parameters in the current route
* @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot * @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot
* @param {RouterStateSnapshot} state The current RouterStateSnapshot * @param {RouterStateSnapshot} state The current RouterStateSnapshot
* @returns Observable<<RemoteData<Item>> Emits the found item based on the parameters in the current route, * @returns Observable<<RemoteData<Item>> Emits the found workflow item based on the parameters in the current route,
* or an error if something went wrong * or an error if something went wrong
*/ */
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<WorkflowItem>> { resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<WorkflowItem>> {

View File

@@ -1,16 +1,59 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 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', () => { describe('WorkflowItemSendBackComponent', () => {
let component: WorkflowItemSendBackComponent; let component: WorkflowItemSendBackComponent;
let fixture: ComponentFixture<WorkflowItemSendBackComponent>; let fixture: ComponentFixture<WorkflowItemSendBackComponent>;
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(() => { beforeEach(async(() => {
init();
TestBed.configureTestingModule({ 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(() => { beforeEach(() => {
@@ -22,4 +65,9 @@ describe('WorkflowItemSendBackComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should call sendBack on the workflow-item service when sendRequest is called', () => {
component.sendRequest(id);
expect(wfiService.sendBack).toHaveBeenCalledWith(id);
});
}); });

View File

@@ -11,6 +11,9 @@ import { TranslateService } from '@ngx-translate/core';
selector: 'ds-workflow-item-send-back', selector: 'ds-workflow-item-send-back',
templateUrl: '../workflow-item-action-page.component.html' 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 { export class WorkflowItemSendBackComponent extends WorkflowItemActionPageComponent {
constructor(protected route: ActivatedRoute, constructor(protected route: ActivatedRoute,
protected workflowItemService: WorkflowItemDataService, protected workflowItemService: WorkflowItemDataService,
@@ -21,10 +24,17 @@ export class WorkflowItemSendBackComponent extends WorkflowItemActionPageCompone
super(route, workflowItemService, router, routeService, notificationsService, translationService); super(route, workflowItemService, router, routeService, notificationsService, translationService);
} }
/**
* Returns the type of page
*/
getType(): string { getType(): string {
return 'send-back'; return 'send-back';
} }
/**
* Performs the action of this workflow item action page
* @param id The id of the WorkflowItem
*/
sendRequest(id: string): Observable<boolean> { sendRequest(id: string): Observable<boolean> {
return this.workflowItemService.sendBack(id); return this.workflowItemService.sendBack(id);
} }