Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/app/app-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { ACCESS_CONTROL_MODULE_PATH } from './access-control/access-control-rout
import { NOTIFICATIONS_MODULE_PATH } from './admin/admin-routing-paths';
import {
ADMIN_MODULE_PATH,
BULK_IMPORT_PATH,
EDIT_ITEM_PATH,
FORGOT_PASSWORD_PATH,
HEALTH_PAGE_PATH,
Expand Down Expand Up @@ -275,6 +276,11 @@ export const APP_ROUTES: Route[] = [
loadChildren: () => import('./audit-page/audit-page-routes').then((m) => m.ROUTES),
canActivate: [siteAdministratorGuard, endUserAgreementCurrentUserGuard],
},
{
path: BULK_IMPORT_PATH,
loadChildren: () => import('./bulk-import/bulk-import-page-routes').then((m) => m.ROUTES),
canActivate: [authenticatedGuard, endUserAgreementCurrentUserGuard],
},
{
path: 'subscriptions',
loadChildren: () => import('./subscriptions-page/subscriptions-page-routes')
Expand Down
7 changes: 7 additions & 0 deletions src/app/app-routing-paths.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Collection } from './core/shared/collection.model';

export const COAR_NOTIFY_SUPPORT = 'coar-notify-support';

export const ADMIN_MODULE_PATH = 'admin';
Expand Down Expand Up @@ -57,3 +59,8 @@ export function getEditItemPageRoute() {
}
export const CORRECTION_TYPE_PATH = 'corrections';

export const BULK_IMPORT_PATH = 'bulk-import';

export function getBulkImportRoute(collection: Collection): string {
return `/${BULK_IMPORT_PATH}/${collection.id}`;
}
4 changes: 4 additions & 0 deletions src/app/app.menus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { AdminSearchMenuProvider } from './shared/menu/providers/admin-search.me
import { AuditLogsMenuProvider } from './shared/menu/providers/audit-item.menu';
import { AuditOverviewMenuProvider } from './shared/menu/providers/audit-overview.menu';
import { BrowseMenuProvider } from './shared/menu/providers/browse.menu';
import { BulkImportMenuProvider } from './shared/menu/providers/bulk-import.menu';
import { CoarNotifyMenuProvider } from './shared/menu/providers/coar-notify.menu';
import { SubscribeMenuProvider } from './shared/menu/providers/comcol-subscribe.menu';
import { CommunityListMenuProvider } from './shared/menu/providers/community-list.menu';
Expand Down Expand Up @@ -112,6 +113,9 @@ export const MENUS = buildMenuStructure({
ClaimMenuProvider.onRoute(
MenuRoute.ITEM_PAGE,
),
BulkImportMenuProvider.onRoute(
MenuRoute.COLLECTION_PAGE,
),
]),
],
});
23 changes: 23 additions & 0 deletions src/app/bulk-import/bulk-import-page-routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Route } from '@angular/router';

import { i18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
import { bulkImportGuard } from './bulk-import.guard';
import { BulkImportPageComponent } from './bulk-import-page.component';
import { bulkImportPageResolver } from './bulk-import-page.resolver';

/**
* RouterModule to help navigate to the page with the bulk import.
*/
export const ROUTES: Route[] = [
{
path: ':id',
component: BulkImportPageComponent,
resolve: {
collection: bulkImportPageResolver,
breadcrumb: i18nBreadcrumbResolver,
},
pathMatch: 'full',
data: { title: 'bulk-import.title', breadcrumbKey: 'bulk-import' },
canActivate: [bulkImportGuard],
},
];
27 changes: 27 additions & 0 deletions src/app/bulk-import/bulk-import-page.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="container">
<h2 class="mb-3">{{ 'bulk-import.title' | translate }}</h2>
<form [formGroup]="form" (ngSubmit)="submit()">
<div class="form-group mb-2">
<label for="name">{{ 'bulk-import.collection-name' | translate }}</label>
<input type="text" class="form-control" id="name" formControlName="name">
</div>
<div class="form-group mb-2">
<label for="file">{{ 'bulk-import.file' | translate }}</label>
<input type="file" (change)="handleFileInput($event)" formControlName="file" id="file" class="form-control-file d-block" requireFile/>
</div>
<div class="form-check">
<input type="checkbox" formControlName="abortOnError" id="abortOnError" class="form-check-input" />
<label for="abortOnError" class="me-5">{{ 'bulk-import.abort-on-error' | translate }}</label>
</div>

<button type="submit" class="btn btn-primary float-end" [dsBtnDisabled]="form.invalid" >
<span>
{{'bulk-import.submit' | translate}}
</span>
</button>
<button type="button" class="btn btn-outline-secondary float-end me-2" (click)="goBack()">
{{'bulk-import.back' | translate}}
</button>

</form>
</div>
151 changes: 151 additions & 0 deletions src/app/bulk-import/bulk-import-page.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { CommonModule } from '@angular/common';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
ComponentFixture,
fakeAsync,
inject,
TestBed,
tick,
} from '@angular/core/testing';
import {
FormsModule,
ReactiveFormsModule,
} from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { NotificationsService } from '@dspace/core/notification-system/notifications.service';
import { ActivatedRouteStub } from '@dspace/core/testing/active-router.stub';
import { NotificationsServiceStub } from '@dspace/core/testing/notifications-service.stub';
import { getMockRequestService } from '@dspace/core/testing/request.service.mock';
import { RouterMock } from '@dspace/core/testing/router.mock';
import { TranslateLoaderMock } from '@dspace/core/testing/translate-loader.mock';
import { createSuccessfulRemoteDataObject } from '@dspace/core/utilities/remote-data.utils';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import {
TranslateLoader,
TranslateModule,
} from '@ngx-translate/core';
import { of } from 'rxjs';

import { AuthService } from '../core/auth/auth.service';
import { DSONameService } from '../core/breadcrumbs/dso-name.service';
import { RestResponse } from '../core/cache/response.models';
import { ScriptDataService } from '../core/data/processes/script-data.service';
import { RequestService } from '../core/data/request.service';
import { RequestEntry } from '../core/data/request-entry.model';
import { Collection } from '../core/shared/collection.model';
import { BulkImportPageComponent } from './bulk-import-page.component';

describe('BulkImportPageComponent', () => {

let component: BulkImportPageComponent;
let fixture: ComponentFixture<BulkImportPageComponent>;

let requestService: any;
let scriptDataService: any;
let notificationsService: any;
let route: any;
let router: RouterMock;

const collection: Collection = Object.assign(new Collection(), {
id: '626b80c5-ef15-4b29-8e69-bda89b0a7acf',
name: 'Test collection',
});

const file: File = new File(['test'], 'test.xls');

const fileList: any = {
item: (index: number) => file,
length: 10,
};

const authService = jasmine.createSpyObj('authService', {
isAuthenticated: of(true),
setRedirectUrl: {},
});

beforeEach(() => {
requestService = getMockRequestService();
scriptDataService = jasmine.createSpyObj('scriptDataService', {
invoke: of(Object.assign(new RequestEntry(), {
response: new RestResponse(true, 200, 'OK'),
})),
});
notificationsService = new NotificationsServiceStub();

route = new ActivatedRouteStub({}, {
collection: createSuccessfulRemoteDataObject( collection ),
});
router = new RouterMock();

TestBed.configureTestingModule({
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule, RouterTestingModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderMock,
},
}), BulkImportPageComponent],
providers: [
BulkImportPageComponent,
DSONameService,
{ provide: RequestService, useValue: requestService },
{ provide: RequestService, useValue: requestService },
{ provide: ScriptDataService, useValue: scriptDataService },
{ provide: NotificationsService, useValue: notificationsService },
{ provide: ActivatedRoute, useValue: route },
{ provide: Router, useValue: router },
{ provide: AuthService, useValue: authService },
],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();

});

beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(BulkImportPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
tick();
}));

it('should create BulkImportPageComponent', inject([BulkImportPageComponent], (comp: BulkImportPageComponent) => {
expect(comp).toBeDefined();
}));

describe('when the user submit the form', () => {

beforeEach(() => {
component.form.value.abortOnError = true;
component.form.value.file = fileList;
component.setFile(fileList);
component.submit();
});

it('should invoke the bulk-import script', () => {
expect(scriptDataService.invoke).toHaveBeenCalledWith('bulk-import', [
{ name: '-c', value: '626b80c5-ef15-4b29-8e69-bda89b0a7acf' },
{ name: '-f', value: 'test.xls' },
{ name: '-er', value: true },
], [file]);
});

});

describe('when the user click on back button', () => {

beforeEach(() => {
component.goBack();
});

it('should nagivate to collection page', () => {
expect(router.navigateByUrl).toHaveBeenCalledWith('/collections/626b80c5-ef15-4b29-8e69-bda89b0a7acf');
});

});

});
Loading
Loading