diff --git a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.html b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.html index f789f4df47..6c3dd79d7c 100644 --- a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.html +++ b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.html @@ -7,7 +7,8 @@ {{"submission.workspace.generic.view" | translate}} - @@ -15,6 +16,7 @@ - \ No newline at end of file + diff --git a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.spec.ts b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.spec.ts index 14d3c07650..f786782c05 100644 --- a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.spec.ts +++ b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.spec.ts @@ -1,3 +1,4 @@ +import { EPerson } from './../../../core/eperson/models/eperson.model'; import { ChangeDetectionStrategy, Injector, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { Router } from '@angular/router'; @@ -24,12 +25,16 @@ import { RequestService } from '../../../core/data/request.service'; import { getMockRequestService } from '../../mocks/request.service.mock'; import { getMockSearchService } from '../../mocks/search-service.mock'; import { SearchService } from '../../../core/shared/search/search.service'; +import { AuthService } from '../../../core/auth/auth.service'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; let component: WorkspaceitemActionsComponent; let fixture: ComponentFixture; let mockObject: WorkspaceItem; let notificationsServiceStub: NotificationsServiceStub; +let authorizationService; +let authService; const mockDataService = jasmine.createSpyObj('WorkspaceitemDataService', { delete: jasmine.createSpy('delete') @@ -71,10 +76,88 @@ const item = Object.assign(new Item(), { const rd = createSuccessfulRemoteDataObject(item); mockObject = Object.assign(new WorkspaceItem(), { item: observableOf(rd), id: '1234', uuid: '1234' }); -describe('WorkspaceitemActionsComponent', () => { - beforeEach(waitForAsync(() => { +const ePersonMock: EPerson = Object.assign(new EPerson(), { + handle: null, + netid: null, + lastActive: '2023-04-27T12:15:57.054+00:00', + canLogIn: true, + email: 'dspacedemo+submit@gmail.com', + requireCertificate: false, + selfRegistered: false, + _name: 'dspacedemo+submit@gmail.com', + id: '914955b1-cf2e-4884-8af7-a166aa24cf73', + uuid: '914955b1-cf2e-4884-8af7-a166aa24cf73', + type: 'eperson', + metadata: { + 'dspace.agreements.cookies': [ + { + uuid: '0a53a0f2-e168-4ed9-b4af-cba9a2d267ca', + language: null, + value: + '{"authentication":true,"preferences":true,"acknowledgement":true,"google-analytics":true}', + place: 0, + authority: null, + confidence: -1, + }, + ], + 'dspace.agreements.end-user': [ + { + uuid: '0879e571-6e4a-4efe-af9b-704c755166be', + language: null, + value: 'true', + place: 0, + authority: null, + confidence: -1, + }, + ], + 'eperson.firstname': [ + { + uuid: '18052a3e-f19b-49ca-b9f9-ee4cf9c71b86', + language: null, + value: 'Demo', + place: 0, + authority: null, + confidence: -1, + }, + ], + 'eperson.language': [ + { + uuid: '98c2abdb-6a6f-4b41-b455-896bcf333ca3', + language: null, + value: 'en', + place: 0, + authority: null, + confidence: -1, + }, + ], + 'eperson.lastname': [ + { + uuid: 'df722e70-9497-468d-a92a-4038e7ef2586', + language: null, + value: 'Submitter', + place: 0, + authority: null, + confidence: -1, + }, + ], + }, + _links: { + groups: { + href: 'http://localhost:8080/server/api/eperson/epersons/914955b1-cf2e-4884-8af7-a166aa24cf73/groups', + }, + self: { + href: 'http://localhost:8080/server/api/eperson/epersons/914955b1-cf2e-4884-8af7-a166aa24cf73', + }, + }, +}); - TestBed.configureTestingModule({ +authService = jasmine.createSpyObj('authService', { + getAuthenticatedUserFromStore: jasmine.createSpy('getAuthenticatedUserFromStore') +}); + +describe('WorkspaceitemActionsComponent', () => { + beforeEach(waitForAsync(async () => { + await TestBed.configureTestingModule({ imports: [ NgbModule, TranslateModule.forRoot({ @@ -92,6 +175,8 @@ describe('WorkspaceitemActionsComponent', () => { { provide: WorkspaceitemDataService, useValue: mockDataService }, { provide: SearchService, useValue: searchService }, { provide: RequestService, useValue: requestServce }, + { provide: AuthService, useValue: authService }, + { provide: AuthorizationDataService, useValue: authorizationService}, NgbModal ], schemas: [NO_ERRORS_SCHEMA] @@ -105,6 +190,10 @@ describe('WorkspaceitemActionsComponent', () => { component = fixture.componentInstance; component.object = mockObject; notificationsServiceStub = TestBed.inject(NotificationsService as any); + authorizationService = jasmine.createSpyObj('authorizationService', { + isAuthorized: observableOf(true) + }); + (authService.getAuthenticatedUserFromStore as jasmine.Spy).and.returnValue(observableOf(ePersonMock)); fixture.detectChanges(); }); @@ -150,7 +239,6 @@ describe('WorkspaceitemActionsComponent', () => { confirmBtn.click(); fixture.detectChanges(); - fixture.whenStable().then(() => { done(); }); diff --git a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.ts b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.ts index a6d30728ac..d758ef1bb5 100644 --- a/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.ts +++ b/src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.ts @@ -1,7 +1,12 @@ -import { Component, Injector, Input } from '@angular/core'; +import { EPerson } from './../../../core/eperson/models/eperson.model'; +import { AuthorizationDataService } from 'src/app/core/data/feature-authorization/authorization-data.service'; +import { AuthService } from './../../../core/auth/auth.service'; +import { Item } from 'src/app/core/shared/item.model'; +import { FeatureID } from './../../../core/data/feature-authorization/feature-id'; +import { Component, Injector, Input, OnInit } from '@angular/core'; import { Router } from '@angular/router'; -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, Observable, switchMap } from 'rxjs'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { TranslateService } from '@ngx-translate/core'; @@ -11,7 +16,7 @@ import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem import { NotificationsService } from '../../notifications/notifications.service'; import { RequestService } from '../../../core/data/request.service'; import { SearchService } from '../../../core/shared/search/search.service'; -import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { getFirstCompletedRemoteData, getRemoteDataPayload } from '../../../core/shared/operators'; import { RemoteData } from '../../../core/data/remote-data'; import { NoContent } from '../../../core/shared/NoContent.model'; import { getWorkspaceItemViewRoute } from '../../../workspaceitems-edit-page/workspaceitems-edit-page-routing-paths'; @@ -24,7 +29,7 @@ import { getWorkspaceItemViewRoute } from '../../../workspaceitems-edit-page/wor styleUrls: ['./workspaceitem-actions.component.scss'], templateUrl: './workspaceitem-actions.component.html', }) -export class WorkspaceitemActionsComponent extends MyDSpaceActionsComponent { +export class WorkspaceitemActionsComponent extends MyDSpaceActionsComponent implements OnInit { /** * The workspaceitem object @@ -37,6 +42,20 @@ export class WorkspaceitemActionsComponent extends MyDSpaceActionsComponent(false); + /** + * A boolean representing if the user is an admin + * @type {Observable} + */ + isAdmin$: Observable; + + /** + * A boolean representing if the user can edit the item + * and therefore can delete it as well + * (since the user can discard the item also from the edit page) + * @type {Observable} + */ + canEditItem$: Observable; + /** * Initialize instance variables * @@ -54,8 +73,12 @@ export class WorkspaceitemActionsComponent extends MyDSpaceActionsComponent this.authorizationService.isAuthorized(FeatureID.AdministratorOf, user.uuid))); + + this.canEditItem$ = activeEPerson$.pipe( + switchMap((eperson) => { + return this.object?.item.pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + switchMap((item: Item) => { + return this.authorizationService.isAuthorized(FeatureID.CanEditItem, item?._links?.self.href, eperson.uuid); + }) + ) as Observable; + })); + } + /** * Init the target object * @@ -92,5 +134,4 @@ export class WorkspaceitemActionsComponent extends MyDSpaceActionsComponent