Skip to content

Commit

Permalink
Merged in DSC-1111-latest-version-maintenance (pull request DSpace#1409)
Browse files Browse the repository at this point in the history
DSC-1111 latest version maintenance

Approved-by: Vincenzo Mecca
  • Loading branch information
Mattia Vianelli authored and vins01-4science committed May 9, 2024
2 parents a77762a + d8501ae commit 5ec1ff3
Show file tree
Hide file tree
Showing 12 changed files with 297 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { Collection } from '../../core/shared/collection.model';
import { ComColFormComponent } from '../../shared/comcol/comcol-forms/comcol-form/comcol-form.component';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { CommunityDataService } from '../../core/data/community-data.service';
import { CollectionDataService } from '../../core/data/collection-data.service';
import { AuthService } from '../../core/auth/auth.service';
import { RequestService } from '../../core/data/request.service';
import { ObjectCacheService } from '../../core/cache/object-cache.service';
Expand All @@ -34,7 +34,7 @@ import { SubmissionDefinitionsConfigDataService } from '../../core/config/submis
import { ConfigObject } from '../../core/config/models/config.model';
import { NONE_ENTITY_TYPE } from '../../core/shared/item-relationships/item-type.resource-type';
import { hasNoValue, isNotNull } from 'src/app/shared/empty.util';

import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

/**
* Form used for creating and editing collections
Expand Down Expand Up @@ -85,13 +85,14 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> imp
protected translate: TranslateService,
protected notificationsService: NotificationsService,
protected authService: AuthService,
protected dsoService: CommunityDataService,
protected dsoService: CollectionDataService,
protected requestService: RequestService,
protected objectCache: ObjectCacheService,
protected entityTypeService: EntityTypeDataService,
protected chd: ChangeDetectorRef,
protected modalService: NgbModal,
protected submissionDefinitionService: SubmissionDefinitionsConfigDataService) {
super(formService, translate, notificationsService, authService, requestService, objectCache);
super(formService, translate, notificationsService, authService, requestService, objectCache, modalService);
}

ngOnInit(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ <h2 id="sub-header" class="border-bottom pb-2">{{'collection.create.sub-head' |
</div>
</div>
<ds-collection-form (submitForm)="onSubmit($event)"
[isCreation]="true"
(back)="navigateToHome()"
(finish)="navigateToNewPage()"></ds-collection-form>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
</div>
</div>
<ds-collection-form [dso]="(dsoRD$ | async)?.payload"
[isCreation]="false"
(submitForm)="onSubmit($event)"
(back)="navigateToHomePage()"
(finish)="navigateToHomePage()"></ds-collection-form>
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { AuthService } from '../../core/auth/auth.service';
import { RequestService } from '../../core/data/request.service';
import { ObjectCacheService } from '../../core/cache/object-cache.service';
import { environment } from '../../../environments/environment';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';

/**
* Form used for creating and editing communities
Expand Down Expand Up @@ -78,8 +79,9 @@ export class CommunityFormComponent extends ComColFormComponent<Community> imple
protected authService: AuthService,
protected dsoService: CommunityDataService,
protected requestService: RequestService,
protected objectCache: ObjectCacheService) {
super(formService, translate, notificationsService, authService, requestService, objectCache);
protected objectCache: ObjectCacheService,
protected modalService: NgbModal) {
super(formService, translate, notificationsService, authService, requestService, objectCache, modalService);
}

ngOnChanges(changes: SimpleChanges) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
<div class="row">
<div class="col-12 pb-4">
<ng-container *ngVar="(parentRD$ | async)?.payload as parent">
<h2 *ngIf="!parent" id="header" class="border-bottom pb-2">{{ 'community.create.head' | translate }}</h2>
<h2 *ngIf="!parent" id="header" class="border-bottom p-2">{{ 'community.create.head' | translate }}</h2>
<h2 *ngIf="parent" id="sub-header" class="border-bottom pb-2">{{ 'community.create.sub-head' | translate:{ parent: dsoNameService.getName(parent) } }}</h2>
</ng-container>
</div>
</div>
<ds-community-form (submitForm)="onSubmit($event)"
[isCreation]="true"
(back)="navigateToHome()"
(finish)="navigateToNewPage()"></ds-community-form>
</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<ds-community-form [dso]="(dsoRD$ | async)?.payload"
[isCreation]="false"
(submitForm)="onSubmit($event)"
(back)="navigateToHomePage()"
(finish)="navigateToHomePage()"></ds-community-form>

Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@
<label>{{type.value + '.edit.logo.label' | translate}}</label>
</div>
<ng-container *ngVar="(dso?.logo | async)?.payload as logo">
<div class="col-12 d-inline-block alert" [ngClass]="{'alert-danger': markLogoForDeletion}" id="logo-section" *ngIf="logo">
<div class="col-12 d-inline-block alert" id="logo-section" *ngIf="logo">
<div class="row">
<div class="col-8 d-inline-block">
<ds-comcol-page-logo [logo]="logo"></ds-comcol-page-logo>
</div>
<div class="col-4 d-inline-block">
<div *ngIf="logo" class="btn-group btn-group-sm float-right" role="group">
<button *ngIf="!markLogoForDeletion" type="button" class="btn btn-danger"
title="{{type.value + '.edit.logo.delete.title' | translate}}"
(click)="deleteLogo()">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
<button *ngIf="markLogoForDeletion" type="button" class="btn btn-warning"
title="{{type.value + '.edit.logo.delete-undo.title' | translate}}"
(click)="undoDeleteLogo()">
<i class="fas fa-undo" aria-hidden="true"></i>
<div *ngIf="logo" class="float-right">
<button
(click)="confirmLogoDeleteWithModal()"
class="btn btn-danger"
type="button">{{ 'community.edit.logo.delete.title' | translate }}
</button>
</div>
</div>
Expand All @@ -42,7 +37,8 @@
[formModel]="formModel"
[displayCancel]="false"
(submitForm)="onSubmit()">
<button before (click)="back.emit()" class="btn btn-outline-secondary" type="button">
<button (click)="back.emit()" before class="btn btn-outline-secondary" type="button">
<i class="fas fa-arrow-left"></i> {{ type.value + '.edit.return' | translate }}
</button>
</ds-form>

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { NotificationsServiceStub } from '../../../testing/notifications-service
import { VarDirective } from '../../../utils/var.directive';
import { ComColFormComponent } from './comcol-form.component';
import { Operation } from 'fast-json-patch';
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../remote-data.utils';
import { createSuccessfulRemoteDataObject$ } from '../../../remote-data.utils';

describe('ComColFormComponent', () => {
let comp: ComColFormComponent<any>;
Expand Down Expand Up @@ -61,7 +61,8 @@ describe('ComColFormComponent', () => {
const logoEndpoint = 'rest/api/logo/endpoint';
const dsoService = Object.assign({
getLogoEndpoint: () => observableOf(logoEndpoint),
deleteLogo: () => createSuccessfulRemoteDataObject$({})
deleteLogo: () => createSuccessfulRemoteDataObject$({}),
findById: () => createSuccessfulRemoteDataObject$({})
});
const notificationsService = new NotificationsServiceStub();

Expand All @@ -70,7 +71,8 @@ describe('ComColFormComponent', () => {
/* eslint-enable no-empty, @typescript-eslint/no-empty-function */

const requestServiceStub = jasmine.createSpyObj('requestService', {
removeByHrefSubstring: {}
removeByHrefSubstring: {},
setStaleByHrefSubstring: {}
});
const objectCacheStub = jasmine.createSpyObj('objectCache', {
remove: {}
Expand Down Expand Up @@ -148,8 +150,6 @@ describe('ComColFormComponent', () => {
type: Community.type,
}
),
uploader: undefined,
deleteLogo: false,
operations: operations,
}
);
Expand All @@ -158,32 +158,22 @@ describe('ComColFormComponent', () => {

describe('onCompleteItem', () => {
beforeEach(() => {
spyOn(comp.finish, 'emit');
comp.onCompleteItem();
});

it('should show a success notification', () => {
expect(notificationsService.success).toHaveBeenCalled();
});

it('should emit finish', () => {
expect(comp.finish.emit).toHaveBeenCalled();
});
});

describe('onUploadError', () => {
beforeEach(() => {
spyOn(comp.finish, 'emit');
comp.onUploadError();
});

it('should show an error notification', () => {
expect(notificationsService.error).toHaveBeenCalled();
});

it('should emit finish', () => {
expect(comp.finish.emit).toHaveBeenCalled();
});
});
});

Expand All @@ -204,6 +194,11 @@ describe('ComColFormComponent', () => {
it('should initialize the uploadFilesOptions with a POST method', () => {
expect(comp.uploadFilesOptions.method).toEqual(RestRequestMethod.POST);
});

it('should not show the delete logo button', () => {
const button = fixture.debugElement.query(By.css('#logo-section .btn-danger'));
expect(button).toBeFalsy();
});
});

describe('and the dso contains a logo', () => {
Expand All @@ -222,96 +217,71 @@ describe('ComColFormComponent', () => {
expect(comp.uploadFilesOptions.url).toEqual(logoEndpoint);
});

it('should initialize the uploadFilesOptions with a PUT method', () => {
expect(comp.uploadFilesOptions.method).toEqual(RestRequestMethod.PUT);
it('should show the delete logo button', () => {
const button = fixture.debugElement.query(By.css('#logo-section .btn-danger'));
expect(button).toBeTruthy();
});

describe('submit with logo marked for deletion', () => {
describe('when the delete logo button is clicked', () => {
beforeEach(() => {
spyOn(dsoService, 'deleteLogo').and.callThrough();
comp.markLogoForDeletion = true;
});

it('should call dsoService.deleteLogo on the DSO', () => {
comp.onSubmit();
spyOn(dsoService, 'deleteLogo').and.returnValue(createSuccessfulRemoteDataObject$({}));
spyOn(comp, 'handleLogoDeletion').and.callThrough();
spyOn(comp, 'createConfirmationModal').and.callThrough();
spyOn(comp, 'subscribeToConfirmationResponse').and.callThrough();
const deleteButton = fixture.debugElement.query(By.css('#logo-section .btn-danger'));
deleteButton.nativeElement.click();
fixture.detectChanges();

expect(dsoService.deleteLogo).toHaveBeenCalledWith(comp.dso);
});

describe('when dsoService.deleteLogo returns a successful response', () => {
beforeEach(() => {
dsoService.deleteLogo.and.returnValue(createSuccessfulRemoteDataObject$({}));
comp.onSubmit();
});
it('should create a confirmation modal with the correct labels and properties', () => {
const modalServiceSpy = spyOn((comp as any).modalService, 'open').and.callThrough();

it('should display a success notification', () => {
expect(notificationsService.success).toHaveBeenCalled();
});
});
const modalRef = comp.createConfirmationModal();

describe('when dsoService.deleteLogo returns an error response', () => {
beforeEach(() => {
dsoService.deleteLogo.and.returnValue(createFailedRemoteDataObject$('Error', 500));
comp.onSubmit();
});
expect(modalServiceSpy).toHaveBeenCalled();

it('should display an error notification', () => {
expect(notificationsService.error).toHaveBeenCalled();
});
});
});
expect(modalRef).toBeDefined();
expect(modalRef.componentInstance).toBeDefined();

describe('deleteLogo', () => {
beforeEach(() => {
comp.deleteLogo();
fixture.detectChanges();
expect(modalRef.componentInstance.headerLabel).toBe('community-collection.edit.logo.delete.title');
expect(modalRef.componentInstance.infoLabel).toBe('confirmation-modal.delete-community-collection-logo.info');
expect(modalRef.componentInstance.cancelLabel).toBe('form.cancel');
expect(modalRef.componentInstance.confirmLabel).toBe('community-collection.edit.logo.delete.title');
expect(modalRef.componentInstance.confirmIcon).toBe('fas fa-trash');
});

it('should set markLogoForDeletion to true', () => {
expect(comp.markLogoForDeletion).toEqual(true);
it('should call createConfirmationModal method', () => {
expect(comp.createConfirmationModal).toHaveBeenCalled();
});

it('should mark the logo section with a danger alert', () => {
const logoSection = fixture.debugElement.query(By.css('#logo-section.alert-danger'));
expect(logoSection).toBeTruthy();
it('should call subscribeToConfirmationResponse method', () => {
expect(comp.subscribeToConfirmationResponse).toHaveBeenCalled();
});

it('should hide the delete button', () => {
const button = fixture.debugElement.query(By.css('#logo-section .btn-danger'));
expect(button).not.toBeTruthy();
});
describe('when the modal is closed', () => {

it('should show the undo button', () => {
const button = fixture.debugElement.query(By.css('#logo-section .btn-warning'));
expect(button).toBeTruthy();
});
});
let modalRef;

describe('undoDeleteLogo', () => {
beforeEach(() => {
comp.markLogoForDeletion = true;
comp.undoDeleteLogo();
fixture.detectChanges();
});
beforeEach(() => {
modalRef = comp.createConfirmationModal();
comp.subscribeToConfirmationResponse(modalRef);
});

it('should set markLogoForDeletion to false', () => {
expect(comp.markLogoForDeletion).toEqual(false);
});
it('should call handleLogoDeletion and dsoService.deleteLogo methods when deletion is confirmed', waitForAsync(() => {
modalRef.componentInstance.confirmPressed();

it('should disable the danger alert on the logo section', () => {
const logoSection = fixture.debugElement.query(By.css('#logo-section.alert-danger'));
expect(logoSection).not.toBeTruthy();
});
expect(comp.handleLogoDeletion).toHaveBeenCalled();
expect(dsoService.deleteLogo).toHaveBeenCalled();

it('should show the delete button', () => {
const button = fixture.debugElement.query(By.css('#logo-section .btn-danger'));
expect(button).toBeTruthy();
});
}));

it('should not call handleLogoDeletion and dsoService.deleteLogo methods when deletion is refused', waitForAsync(() => {
modalRef.componentInstance.cancelPressed();

expect(comp.handleLogoDeletion).not.toHaveBeenCalled();
expect(dsoService.deleteLogo).not.toHaveBeenCalled();
}));

it('should hide the undo button', () => {
const button = fixture.debugElement.query(By.css('#logo-section .btn-warning'));
expect(button).not.toBeTruthy();
});
});
});
Expand Down
Loading

0 comments on commit 5ec1ff3

Please sign in to comment.