mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
[CST-5307] Move profile-claim-item-modal.component to profile page module and add unit tests
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
<button class="list-group-item list-group-item-action border-0 list-entry"
|
||||
title="{{ listEntry.indexableObject.name }}"
|
||||
(click)="selectItem(listEntry.indexableObject)" #listEntryElement>
|
||||
<ds-listable-object-component-loader [object]="listEntry" [viewMode]="viewMode"
|
||||
<ds-listable-object-component-loader [object]="listEntry" [viewMode]="viewMode"
|
||||
[linkType]=linkTypes.None></ds-listable-object-component-loader>
|
||||
</button>
|
||||
</div>
|
||||
@@ -26,7 +26,7 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="mr-5">
|
||||
<input type="checkbox" [checked]="false" (change)="toggleCheckbox()"/>
|
||||
<input type="checkbox" [checked]="checked" (change)="toggleCheckbox()"/>
|
||||
{{ 'dso-selector.claim.item.not-mine-label' | translate }}
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary ml-5 mr-2" (click)="createFromScratch()" [disabled]="!checked">
|
@@ -0,0 +1,223 @@
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
import { of } from 'rxjs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
import { ProfileClaimItemModalComponent } from './profile-claim-item-modal.component';
|
||||
import { ProfileClaimService } from '../profile-claim/profile-claim.service';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
import { ItemSearchResult } from '../../shared/object-collection/shared/item-search-result.model';
|
||||
import { SearchObjects } from '../../shared/search/models/search-objects.model';
|
||||
import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils';
|
||||
import { getItemPageRoute } from '../../item-page/item-page-routing-paths';
|
||||
import { RouterStub } from '../../shared/testing/router.stub';
|
||||
|
||||
describe('ProfileClaimItemModalComponent', () => {
|
||||
let component: ProfileClaimItemModalComponent;
|
||||
let fixture: ComponentFixture<ProfileClaimItemModalComponent>;
|
||||
|
||||
const item1: Item = Object.assign(new Item(), {
|
||||
uuid: 'e1c51c69-896d-42dc-8221-1d5f2ad5516e',
|
||||
metadata: {
|
||||
'person.email': [
|
||||
{
|
||||
value: 'fake@email.com'
|
||||
}
|
||||
],
|
||||
'person.familyName': [
|
||||
{
|
||||
value: 'Doe'
|
||||
}
|
||||
],
|
||||
'person.givenName': [
|
||||
{
|
||||
value: 'John'
|
||||
}
|
||||
]
|
||||
},
|
||||
_links: {
|
||||
self: {
|
||||
href: 'item-href'
|
||||
}
|
||||
}
|
||||
});
|
||||
const item2: Item = Object.assign(new Item(), {
|
||||
uuid: 'c8279647-1acc-41ae-b036-951d5f65649b',
|
||||
metadata: {
|
||||
'person.email': [
|
||||
{
|
||||
value: 'fake2@email.com'
|
||||
}
|
||||
],
|
||||
'dc.title': [
|
||||
{
|
||||
value: 'John, Doe'
|
||||
}
|
||||
]
|
||||
},
|
||||
_links: {
|
||||
self: {
|
||||
href: 'item-href'
|
||||
}
|
||||
}
|
||||
});
|
||||
const item3: Item = Object.assign(new Item(), {
|
||||
uuid: 'c8279647-1acc-41ae-b036-951d5f65649b',
|
||||
metadata: {
|
||||
'person.email': [
|
||||
{
|
||||
value: 'fake3@email.com'
|
||||
}
|
||||
],
|
||||
'dc.title': [
|
||||
{
|
||||
value: 'John, Doe'
|
||||
}
|
||||
]
|
||||
},
|
||||
_links: {
|
||||
self: {
|
||||
href: 'item-href'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const searchResult1 = Object.assign(new ItemSearchResult(), { indexableObject: item1 });
|
||||
const searchResult2 = Object.assign(new ItemSearchResult(), { indexableObject: item2 });
|
||||
const searchResult3 = Object.assign(new ItemSearchResult(), { indexableObject: item3 });
|
||||
|
||||
const searchResult = Object.assign(new SearchObjects(), {
|
||||
page: [searchResult1, searchResult2, searchResult3]
|
||||
});
|
||||
const emptySearchResult = Object.assign(new SearchObjects(), {
|
||||
page: []
|
||||
});
|
||||
const searchResultRD = createSuccessfulRemoteDataObject(searchResult);
|
||||
const emptySearchResultRD = createSuccessfulRemoteDataObject(emptySearchResult);
|
||||
|
||||
const profileClaimService = jasmine.createSpyObj('profileClaimService', {
|
||||
searchForSuggestions: jasmine.createSpy('searchForSuggestions')
|
||||
});
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot()],
|
||||
declarations: [ProfileClaimItemModalComponent],
|
||||
providers: [
|
||||
{ provide: NgbActiveModal, useValue: {} },
|
||||
{ provide: ActivatedRoute, useValue: {} },
|
||||
{ provide: Router, useValue: new RouterStub() },
|
||||
{ provide: ProfileClaimService, useValue: profileClaimService }
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProfileClaimItemModalComponent);
|
||||
component = fixture.componentInstance;
|
||||
});
|
||||
|
||||
describe('when there are suggestions', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
profileClaimService.searchForSuggestions.and.returnValue(of(searchResultRD));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should init the list of suggestions', () => {
|
||||
const entries = fixture.debugElement.queryAll(By.css('.list-group-item'));
|
||||
expect(component.listEntries$.value).toEqual(searchResultRD);
|
||||
expect(entries.length).toBe(3);
|
||||
});
|
||||
|
||||
it('should close modal and call navigate method', () => {
|
||||
spyOn(component, 'close');
|
||||
spyOn(component, 'navigate');
|
||||
component.selectItem(item1);
|
||||
|
||||
expect(component.close).toHaveBeenCalled();
|
||||
expect(component.navigate).toHaveBeenCalledWith(item1);
|
||||
});
|
||||
|
||||
it('should call router navigate method', () => {
|
||||
const route = [getItemPageRoute(item1)];
|
||||
component.navigate(item1);
|
||||
|
||||
expect((component as any).router.navigate).toHaveBeenCalledWith(route);
|
||||
});
|
||||
|
||||
it('should toggle checkbox', () => {
|
||||
component.toggleCheckbox();
|
||||
|
||||
expect((component as any).checked).toBe(true);
|
||||
});
|
||||
|
||||
it('should emit create event', () => {
|
||||
spyOn(component, 'close');
|
||||
spyOn(component.create, 'emit');
|
||||
component.createFromScratch();
|
||||
|
||||
expect(component.create.emit).toHaveBeenCalled();
|
||||
expect(component.close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when there are not suggestions', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
profileClaimService.searchForSuggestions.and.returnValue(of(emptySearchResultRD));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should init the list of suggestions', () => {
|
||||
const entries = fixture.debugElement.queryAll(By.css('.list-group-item'));
|
||||
expect(component.listEntries$.value).toEqual(emptySearchResultRD);
|
||||
expect(entries.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should close modal and call navigate method', () => {
|
||||
spyOn(component, 'close');
|
||||
spyOn(component, 'navigate');
|
||||
component.selectItem(item1);
|
||||
|
||||
expect(component.close).toHaveBeenCalled();
|
||||
expect(component.navigate).toHaveBeenCalledWith(item1);
|
||||
});
|
||||
|
||||
it('should call router navigate method', () => {
|
||||
const route = [getItemPageRoute(item1)];
|
||||
component.navigate(item1);
|
||||
|
||||
expect((component as any).router.navigate).toHaveBeenCalledWith(route);
|
||||
});
|
||||
|
||||
it('should toggle checkbox', () => {
|
||||
component.toggleCheckbox();
|
||||
|
||||
expect((component as any).checked).toBe(true);
|
||||
});
|
||||
|
||||
it('should emit create event', () => {
|
||||
spyOn(component, 'close');
|
||||
spyOn(component.create, 'emit');
|
||||
component.createFromScratch();
|
||||
|
||||
expect(component.create.emit).toHaveBeenCalled();
|
||||
expect(component.close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
@@ -0,0 +1,105 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
import {
|
||||
DSOSelectorModalWrapperComponent
|
||||
} from '../../shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component';
|
||||
import { getItemPageRoute } from '../../item-page/item-page-routing-paths';
|
||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { ViewMode } from '../../core/shared/view-mode.model';
|
||||
import { ProfileClaimService } from '../profile-claim/profile-claim.service';
|
||||
import { CollectionElementLinkType } from '../../shared/object-collection/collection-element-link.type';
|
||||
import { SearchObjects } from '../../shared/search/models/search-objects.model';
|
||||
|
||||
/**
|
||||
* Component representing a modal that show a list of suggested profile item to claim
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ds-profile-claim-item-modal',
|
||||
templateUrl: './profile-claim-item-modal.component.html'
|
||||
})
|
||||
export class ProfileClaimItemModalComponent extends DSOSelectorModalWrapperComponent implements OnInit {
|
||||
|
||||
/**
|
||||
* The current page's DSO
|
||||
*/
|
||||
@Input() dso: DSpaceObject;
|
||||
|
||||
/**
|
||||
* List of suggested profiles, if any
|
||||
*/
|
||||
listEntries$: BehaviorSubject<RemoteData<SearchObjects<DSpaceObject>>> = new BehaviorSubject(null);
|
||||
|
||||
/**
|
||||
* The view mode of the listed objects
|
||||
*/
|
||||
viewMode = ViewMode.ListElement;
|
||||
|
||||
/**
|
||||
* The available link types
|
||||
*/
|
||||
linkTypes = CollectionElementLinkType;
|
||||
|
||||
/**
|
||||
* A boolean representing form checkbox status
|
||||
*/
|
||||
checked = false;
|
||||
|
||||
/**
|
||||
* An event fired when user click on submit button
|
||||
*/
|
||||
@Output() create: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router,
|
||||
private profileClaimService: ProfileClaimService) {
|
||||
super(activeModal, route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve suggested profiles, if any
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.profileClaimService.searchForSuggestions(this.dso as EPerson).subscribe(
|
||||
(result: RemoteData<SearchObjects<DSpaceObject>>) => this.listEntries$.next(result)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close modal and Navigate to given DSO
|
||||
*
|
||||
* @param dso
|
||||
*/
|
||||
selectItem(dso: DSpaceObject): void {
|
||||
this.close();
|
||||
this.navigate(dso);
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to given DSO
|
||||
*
|
||||
* @param dso
|
||||
*/
|
||||
navigate(dso: DSpaceObject) {
|
||||
this.router.navigate([getItemPageRoute(dso as Item)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the status of form's checkbox
|
||||
*/
|
||||
toggleCheckbox() {
|
||||
this.checked = !this.checked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event when profile should be created from scratch
|
||||
*/
|
||||
createFromScratch() {
|
||||
this.create.emit();
|
||||
this.close();
|
||||
}
|
||||
|
||||
}
|
@@ -5,10 +5,13 @@ import { ProfilePageRoutingModule } from './profile-page-routing.module';
|
||||
import { ProfilePageComponent } from './profile-page.component';
|
||||
import { ProfilePageMetadataFormComponent } from './profile-page-metadata-form/profile-page-metadata-form.component';
|
||||
import { ProfilePageSecurityFormComponent } from './profile-page-security-form/profile-page-security-form.component';
|
||||
import { ProfilePageResearcherFormComponent } from './profile-page-researcher-form/profile-page-researcher-form.component';
|
||||
import {
|
||||
ProfilePageResearcherFormComponent
|
||||
} from './profile-page-researcher-form/profile-page-researcher-form.component';
|
||||
import { ThemedProfilePageComponent } from './themed-profile-page.component';
|
||||
import { FormModule } from '../shared/form/form.module';
|
||||
import { UiSwitchModule } from 'ngx-ui-switch';
|
||||
import { ProfileClaimItemModalComponent } from './profile-claim-item-modal/profile-claim-item-modal.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@@ -29,6 +32,7 @@ import { UiSwitchModule } from 'ngx-ui-switch';
|
||||
declarations: [
|
||||
ProfilePageComponent,
|
||||
ThemedProfilePageComponent,
|
||||
ProfileClaimItemModalComponent,
|
||||
ProfilePageMetadataFormComponent,
|
||||
ProfilePageSecurityFormComponent,
|
||||
ProfilePageResearcherFormComponent
|
||||
|
@@ -1,45 +0,0 @@
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
/* tslint:disable:no-unused-variable */
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { ClaimItemSelectorComponent } from './claim-item-selector.component';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { ProfileClaimService } from '../../../../profile-page/profile-claim/profile-claim.service';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
describe('ClaimItemSelectorComponent', () => {
|
||||
let component: ClaimItemSelectorComponent;
|
||||
let fixture: ComponentFixture<ClaimItemSelectorComponent>;
|
||||
|
||||
const profileClaimService = jasmine.createSpyObj('profileClaimService', {
|
||||
search: of({ payload: {page: []}})
|
||||
});
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot()],
|
||||
declarations: [ ClaimItemSelectorComponent ],
|
||||
providers: [
|
||||
{ provide: NgbActiveModal, useValue: {} },
|
||||
{ provide: ActivatedRoute, useValue: {} },
|
||||
{ provide: Router, useValue: {} },
|
||||
{ provide: ProfileClaimService, useValue: profileClaimService }
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ClaimItemSelectorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
@@ -1,69 +0,0 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { SearchResult } from '../../../search/models/search-result.model';
|
||||
import { DSOSelectorModalWrapperComponent } from '../dso-selector-modal-wrapper.component';
|
||||
import { getItemPageRoute } from '../../../../item-page/item-page-routing-paths';
|
||||
import { EPerson } from '../../../../core/eperson/models/eperson.model';
|
||||
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
|
||||
import { ViewMode } from '../../../../core/shared/view-mode.model';
|
||||
import { ProfileClaimService } from '../../../../profile-page/profile-claim/profile-claim.service';
|
||||
import { CollectionElementLinkType } from '../../../object-collection/collection-element-link.type';
|
||||
|
||||
/**
|
||||
* Component
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ds-claim-item-selector',
|
||||
templateUrl: './claim-item-selector.component.html'
|
||||
})
|
||||
export class ClaimItemSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
|
||||
|
||||
@Input() dso: DSpaceObject;
|
||||
|
||||
listEntries$: BehaviorSubject<RemoteData<PaginatedList<SearchResult<DSpaceObject>>>> = new BehaviorSubject(null);
|
||||
|
||||
viewMode = ViewMode.ListElement;
|
||||
|
||||
// enum to be exposed
|
||||
linkTypes = CollectionElementLinkType;
|
||||
|
||||
checked = false;
|
||||
|
||||
@Output() create: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router,
|
||||
private profileClaimService: ProfileClaimService) {
|
||||
super(activeModal, route);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.profileClaimService.search(this.dso as EPerson).subscribe(
|
||||
(result) => this.listEntries$.next(result)
|
||||
);
|
||||
}
|
||||
|
||||
// triggered when an item is selected
|
||||
selectItem(dso: DSpaceObject): void {
|
||||
this.close();
|
||||
this.navigate(dso);
|
||||
}
|
||||
|
||||
navigate(dso: DSpaceObject) {
|
||||
this.router.navigate([getItemPageRoute(dso as Item)]);
|
||||
}
|
||||
|
||||
toggleCheckbox() {
|
||||
this.checked = !this.checked;
|
||||
}
|
||||
|
||||
createFromScratch() {
|
||||
this.create.emit();
|
||||
this.close();
|
||||
}
|
||||
|
||||
}
|
@@ -285,9 +285,6 @@ import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'
|
||||
import {
|
||||
ThemedItemListPreviewComponent
|
||||
} from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component';
|
||||
import {
|
||||
ClaimItemSelectorComponent
|
||||
} from './dso-selector/modal-wrappers/claim-item-selector/claim-item-selector.component';
|
||||
import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component';
|
||||
import { PersonPageClaimButtonComponent } from './dso-page/person-page-claim-button/person-page-claim-button.component';
|
||||
|
||||
@@ -458,9 +455,7 @@ const COMPONENTS = [
|
||||
CollectionSidebarSearchListElementComponent,
|
||||
CommunitySidebarSearchListElementComponent,
|
||||
SearchNavbarComponent,
|
||||
ScopeSelectorModalComponent,
|
||||
|
||||
ClaimItemSelectorComponent
|
||||
ScopeSelectorModalComponent
|
||||
];
|
||||
|
||||
const ENTRY_COMPONENTS = [
|
||||
@@ -517,7 +512,6 @@ const ENTRY_COMPONENTS = [
|
||||
OnClickMenuItemComponent,
|
||||
TextMenuItemComponent,
|
||||
ScopeSelectorModalComponent,
|
||||
ClaimItemSelectorComponent,
|
||||
ExternalLinkMenuItemComponent
|
||||
];
|
||||
|
||||
|
Reference in New Issue
Block a user