Skip to content

Commit aafe354

Browse files
authored
Merge pull request DSpace#1759 from 4Science/CST-6035_external-provider-query-error
External provider query error
2 parents cd1d409 + 310237d commit aafe354

3 files changed

Lines changed: 334 additions & 3 deletions

File tree

src/app/submission/import-external/submission-import-external.component.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ <h3 *ngIf="entriesRD && entriesRD?.payload?.page?.length !== 0">{{ 'submission.s
2424
</ds-viewable-collection>
2525
<ds-themed-loading *ngIf="(isLoading$ | async)"
2626
message="{{'loading.search-results' | translate}}"></ds-themed-loading>
27-
<div *ngIf="!(isLoading$ | async) && entriesRD?.payload?.page?.length === 0" id="empty-external-entry-list">
27+
<div *ngIf="!(isLoading$ | async) && entriesRD?.payload?.page?.length === 0" data-test="empty-external-entry-list">
2828
<ds-alert [type]="'alert-info'">{{ 'search.results.empty' | translate }}</ds-alert>
2929
</div>
30+
<div *ngIf="!(isLoading$ | async) && entriesRD.statusCode === 500" data-test="empty-external-error-500">
31+
<ds-alert [type]="'alert-info'">{{ 'search.results.response.500' | translate }}</ds-alert>
32+
</div>
3033
</ng-container>
3134
</div>
3235
<div *ngIf="reload$.value.sourceId === ''" class="col-md-12">

src/app/submission/import-external/submission-import-external.component.spec.ts

Lines changed: 329 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ import { VarDirective } from '../../shared/utils/var.directive';
1919
import { routeServiceStub } from '../../shared/testing/route-service.stub';
2020
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
2121
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
22-
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
22+
import {
23+
createFailedRemoteDataObject$,
24+
createSuccessfulRemoteDataObject,
25+
createSuccessfulRemoteDataObject$
26+
} from '../../shared/remote-data.utils';
2327
import { ExternalSourceEntry } from '../../core/shared/external-source-entry.model';
2428
import { SubmissionImportExternalPreviewComponent } from './import-external-preview/submission-import-external-preview.component';
29+
import { By } from '@angular/platform-browser';
30+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
2531

2632
describe('SubmissionImportExternalComponent test suite', () => {
2733
let comp: SubmissionImportExternalComponent;
@@ -44,7 +50,8 @@ describe('SubmissionImportExternalComponent test suite', () => {
4450
beforeEach(waitForAsync (() => {
4551
TestBed.configureTestingModule({
4652
imports: [
47-
TranslateModule.forRoot()
53+
TranslateModule.forRoot(),
54+
BrowserAnimationsModule
4855
],
4956
declarations: [
5057
SubmissionImportExternalComponent,
@@ -177,6 +184,326 @@ describe('SubmissionImportExternalComponent test suite', () => {
177184
});
178185
});
179186

187+
describe('handle backend response for search query', () => {
188+
const paginatedData: any = {
189+
'timeCompleted': 1657009282990,
190+
'msToLive': 900000,
191+
'lastUpdated': 1657009282990,
192+
'state': 'Success',
193+
'errorMessage': null,
194+
'payload': {
195+
'type': {
196+
'value': 'paginated-list'
197+
},
198+
'pageInfo': {
199+
'elementsPerPage': 10,
200+
'totalElements': 11971608,
201+
'totalPages': 1197161,
202+
'currentPage': 1
203+
},
204+
'_links': {
205+
'first': {
206+
'href': 'https://example.com/server/api/integration/externalsources/scopus/entries?query=test&page=0&size=10&sort=id,asc'
207+
},
208+
'self': {
209+
'href': 'https://example.com/server/api/integration/externalsources/scopus/entries?sort=id,ASC&page=0&size=10&query=test'
210+
},
211+
'next': {
212+
'href': 'https://example.com/server/api/integration/externalsources/scopus/entries?query=test&page=1&size=10&sort=id,asc'
213+
},
214+
'last': {
215+
'href': 'https://example.com/server/api/integration/externalsources/scopus/entries?query=test&page=1197160&size=10&sort=id,asc'
216+
},
217+
'page': [
218+
{
219+
'href': 'https://example.com/server/api/integration/externalsources/scopus/entryValues/2-s2.0-85130258665'
220+
}
221+
]
222+
},
223+
'page': [
224+
{
225+
'id': '2-s2.0-85130258665',
226+
'type': 'externalSourceEntry',
227+
'display': 'Biological activities of endophytic fungi isolated from Annona muricata Linnaeus: a systematic review',
228+
'value': 'Biological activities of endophytic fungi isolated from Annona muricata Linnaeus: a systematic review',
229+
'externalSource': 'scopus',
230+
'metadata': {
231+
'dc.contributor.author': [
232+
{
233+
'uuid': 'cbceba09-4c12-4968-ab02-2f77a985b422',
234+
'language': null,
235+
'value': 'Silva I.M.M.',
236+
'place': -1,
237+
'authority': null,
238+
'confidence': -1
239+
}
240+
],
241+
'dc.date.issued': [
242+
{
243+
'uuid': 'e8d3c306-ce21-43e2-8a80-5f257cc3b7ea',
244+
'language': null,
245+
'value': '2024-01-01',
246+
'place': -1,
247+
'authority': null,
248+
'confidence': -1
249+
}
250+
],
251+
'dc.description.abstract': [
252+
{
253+
'uuid': 'c9ee4076-c602-4c1d-ab1a-60bbdd0dd511',
254+
'language': null,
255+
'value': 'This systematic review integrates the data available in the literature regarding the biological activities of the extracts of endophytic fungi isolated from Annona muricata and their secondary metabolites. The search was performed using four electronic databases, and studies’ quality was evaluated using an adapted assessment tool. The initial database search yielded 436 results; ten studies were selected for inclusion. The leaf was the most studied part of the plant (in nine studies); Periconia sp. was the most tested fungus (n = 4); the most evaluated biological activity was anticancer (n = 6), followed by antiviral (n = 3). Antibacterial, antifungal, and antioxidant activities were also tested. Terpenoids or terpenoid hybrid compounds were the most abundant chemical metabolites. Phenolic compounds, esters, alkaloids, saturated and unsaturated fatty acids, aromatic compounds, and peptides were also reported. The selected studies highlighted the biotechnological potentiality of the endophytic fungi extracts from A. muricata. Consequently, it can be considered a promising source of biological compounds with antioxidant effects and active against different microorganisms and cancer cells. Further research is needed involving different plant tissues, other microorganisms, such as SARS-CoV-2, and different cancer cells.',
256+
'place': -1,
257+
'authority': null,
258+
'confidence': -1
259+
}
260+
],
261+
'dc.identifier.doi': [
262+
{
263+
'uuid': '95ec26be-c1b4-4c4a-b12d-12421a4f181d',
264+
'language': null,
265+
'value': '10.1590/1519-6984.259525',
266+
'place': -1,
267+
'authority': null,
268+
'confidence': -1
269+
}
270+
],
271+
'dc.identifier.pmid': [
272+
{
273+
'uuid': 'd6913cd6-1007-4013-b486-3f07192bc739',
274+
'language': null,
275+
'value': '35588520',
276+
'place': -1,
277+
'authority': null,
278+
'confidence': -1
279+
}
280+
],
281+
'dc.identifier.scopus': [
282+
{
283+
'uuid': '6386a1f6-84ba-431d-a583-e16d19af8db0',
284+
'language': null,
285+
'value': '2-s2.0-85130258665',
286+
'place': -1,
287+
'authority': null,
288+
'confidence': -1
289+
}
290+
],
291+
'dc.relation.grantno': [
292+
{
293+
'uuid': 'bcafd7b0-827d-4abb-8608-95dc40a8e58a',
294+
'language': null,
295+
'value': 'undefined',
296+
'place': -1,
297+
'authority': null,
298+
'confidence': -1
299+
}
300+
],
301+
'dc.relation.ispartof': [
302+
{
303+
'uuid': '680819c8-c143-405f-9d09-f84d2d5cd338',
304+
'language': null,
305+
'value': 'Brazilian Journal of Biology',
306+
'place': -1,
307+
'authority': null,
308+
'confidence': -1
309+
}
310+
],
311+
'dc.relation.ispartofseries': [
312+
{
313+
'uuid': '06634104-127b-44f6-9dcc-efae24b74bd1',
314+
'language': null,
315+
'value': 'Brazilian Journal of Biology',
316+
'place': -1,
317+
'authority': null,
318+
'confidence': -1
319+
}
320+
],
321+
'dc.relation.issn': [
322+
{
323+
'uuid': '5f6cce46-2538-49e9-8ed0-a3988dcac6c5',
324+
'language': null,
325+
'value': '15196984',
326+
'place': -1,
327+
'authority': null,
328+
'confidence': -1
329+
}
330+
],
331+
'dc.subject': [
332+
{
333+
'uuid': '0b6fbc77-de54-4f4a-b317-3d74a429f22a',
334+
'language': null,
335+
'value': 'biological products | biotechnology | mycology | soursop',
336+
'place': -1,
337+
'authority': null,
338+
'confidence': -1
339+
}
340+
],
341+
'dc.title': [
342+
{
343+
'uuid': '4c0fa3d3-1a8c-4302-a772-4a4d0408df35',
344+
'language': null,
345+
'value': 'Biological activities of endophytic fungi isolated from Annona muricata Linnaeus: a systematic review',
346+
'place': -1,
347+
'authority': null,
348+
'confidence': -1
349+
}
350+
],
351+
'dc.type': [
352+
{
353+
'uuid': '5b6e0337-6f79-4574-a720-536816d1dc6e',
354+
'language': null,
355+
'value': 'Journal',
356+
'place': -1,
357+
'authority': null,
358+
'confidence': -1
359+
}
360+
],
361+
'oaire.citation.volume': [
362+
{
363+
'uuid': 'b88b0246-61a9-4aca-917f-68afc8ead7d8',
364+
'language': null,
365+
'value': '84',
366+
'place': -1,
367+
'authority': null,
368+
'confidence': -1
369+
}
370+
],
371+
'oairecerif.affiliation.orgunit': [
372+
{
373+
'uuid': '487c0fbc-3622-4cc7-a5fa-4edf780c6a21',
374+
'language': null,
375+
'value': 'Universidade Federal do Reconcavo da Bahia',
376+
'place': -1,
377+
'authority': null,
378+
'confidence': -1
379+
}
380+
],
381+
'oairecerif.citation.number': [
382+
{
383+
'uuid': '90808bdd-f456-4ba3-91aa-b82fb3c453f6',
384+
'language': null,
385+
'value': 'e259525',
386+
'place': -1,
387+
'authority': null,
388+
'confidence': -1
389+
}
390+
],
391+
'person.identifier.orcid': [
392+
{
393+
'uuid': 'e533d0d2-cf26-4c3e-b5ae-cabf497dfb6b',
394+
'language': null,
395+
'value': '#PLACEHOLDER_PARENT_METADATA_VALUE#',
396+
'place': -1,
397+
'authority': null,
398+
'confidence': -1
399+
}
400+
],
401+
'person.identifier.scopus-author-id': [
402+
{
403+
'uuid': '4faf0be5-0226-4d4f-92a0-938397c4ec02',
404+
'language': null,
405+
'value': '42561627000',
406+
'place': -1,
407+
'authority': null,
408+
'confidence': -1
409+
}
410+
]
411+
},
412+
'_links': {
413+
'self': {
414+
'href': 'https://example.com/server/api/integration/externalsources/scopus/entryValues/2-s2.0-85130258665'
415+
}
416+
}
417+
}
418+
]
419+
},
420+
'statusCode': 200
421+
};
422+
const errorObj = {
423+
errorMessage: 'Http failure response for ' +
424+
'https://example.com/server/api/integration/externalsources/pubmed/entries?sort=id,ASC&page=0&size=10&query=test: 500 OK',
425+
statusCode: 500,
426+
timeCompleted: 1656950434666,
427+
errors: [{
428+
'message': 'Internal Server Error', 'paths': ['/server/api/integration/externalsources/pubmed/entries']
429+
}]
430+
};
431+
beforeEach(() => {
432+
fixture = TestBed.createComponent(SubmissionImportExternalComponent);
433+
comp = fixture.componentInstance;
434+
compAsAny = comp;
435+
scheduler = getTestScheduler();
436+
});
437+
438+
afterEach(() => {
439+
fixture.destroy();
440+
comp = null;
441+
compAsAny = null;
442+
});
443+
444+
it('REST endpoint returns a 200 response with valid content', () => {
445+
mockExternalSourceService.getExternalSourceEntries.and.returnValue(createSuccessfulRemoteDataObject$(paginatedData.payload));
446+
const expectedEntries = createSuccessfulRemoteDataObject(paginatedData.payload);
447+
spyOn(routeServiceStub, 'getQueryParameterValue').and.callFake((param) => {
448+
if (param === 'entity') {
449+
return observableOf('Publication');
450+
} else if (param === 'sourceId') {
451+
return observableOf('scopus');
452+
} else if (param === 'query') {
453+
return observableOf('test');
454+
}
455+
return observableOf({});
456+
});
457+
fixture.detectChanges();
458+
459+
expect(comp.isLoading$.value).toBe(false);
460+
expect(comp.entriesRD$.value).toEqual(expectedEntries);
461+
const viewableCollection = fixture.debugElement.query(By.css('ds-viewable-collection'));
462+
expect(viewableCollection).toBeTruthy();
463+
});
464+
465+
it('REST endpoint returns a 200 response with no results', () => {
466+
mockExternalSourceService.getExternalSourceEntries.and.returnValue(createSuccessfulRemoteDataObject$(createPaginatedList([])));
467+
const expectedEntries = createSuccessfulRemoteDataObject(createPaginatedList([]));
468+
spyOn(routeServiceStub, 'getQueryParameterValue').and.callFake((param) => {
469+
if (param === 'entity') {
470+
return observableOf('Publication');
471+
}
472+
return observableOf({});
473+
});
474+
fixture.detectChanges();
475+
476+
expect(comp.isLoading$.value).toBe(false);
477+
expect(comp.entriesRD$.value).toEqual(expectedEntries);
478+
const noDataAlert = fixture.debugElement.query(By.css('[data-test="empty-external-entry-list"]'));
479+
expect(noDataAlert).toBeTruthy();
480+
});
481+
482+
it('REST endpoint returns a 500 error', () => {
483+
mockExternalSourceService.getExternalSourceEntries.and.returnValue(createFailedRemoteDataObject$(
484+
errorObj.errorMessage,
485+
errorObj.statusCode,
486+
errorObj.timeCompleted
487+
));
488+
spyOn(routeServiceStub, 'getQueryParameterValue').and.callFake((param) => {
489+
if (param === 'entity') {
490+
return observableOf('Publication');
491+
} else if (param === 'sourceId') {
492+
return observableOf('pubmed');
493+
} else if (param === 'query') {
494+
return observableOf('test');
495+
}
496+
return observableOf({});
497+
});
498+
fixture.detectChanges();
499+
500+
expect(comp.isLoading$.value).toBe(false);
501+
expect(comp.entriesRD$.value.statusCode).toEqual(500);
502+
const noDataAlert = fixture.debugElement.query(By.css('[data-test="empty-external-error-500"]'));
503+
expect(noDataAlert).toBeTruthy();
504+
});
505+
});
506+
180507
});
181508

182509
// declare a test component

src/assets/i18n/en.json5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3618,6 +3618,7 @@
36183618

36193619
"search.results.view-result": "View",
36203620

3621+
"search.results.response.500": "An error occurred during query execution, please try again later",
36213622

36223623
"default.search.results.head": "Search Results",
36233624

0 commit comments

Comments
 (0)