Skip to content

Commit cd42fde

Browse files
NikitaKr1vonosovvins01-4science
authored andcommitted
[DSC-1437] Extend lucky search for supporting bitstream
1 parent 19a26ec commit cd42fde

4 files changed

Lines changed: 254 additions & 77 deletions

File tree

src/app/lucky-search/search/lucky-search.component.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,18 @@ <h5 class="text-center">{{'lucky.search.results.notfound' | translate}} {{curren
2929
</div>
3030
</div>
3131
</div>
32+
33+
<div class="w-100" *ngIf="bitstreamFilters?.length">
34+
<div *ngFor="let attachment of (bitstreams$ | async)" class="mb-3 mx-auto" [style.width]="'33%'">
35+
<ds-truncatable [id]="attachment.id">
36+
<ds-file-download-link [bitstream]="attachment" [enableRequestACopy]="true" [item]="(item$ | async)" [showIcon]="true">
37+
<span data-test="title" *ngIf="fileName(attachment)">
38+
{{fileName(attachment)}} ({{getSize(attachment) | dsFileSize}})
39+
</span>
40+
</ds-file-download-link>
41+
<ds-truncatable-part [id]="attachment.id" [minLines]="1">
42+
<span *ngIf="getDescription(attachment)" data-test="description">{{getDescription(attachment)}}</span>
43+
</ds-truncatable-part>
44+
</ds-truncatable>
45+
</div>
46+
</div>

src/app/lucky-search/search/lucky-search.component.spec.ts

Lines changed: 139 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ import { TranslateModule } from '@ngx-translate/core';
1515
import { By } from '@angular/platform-browser';
1616
import { SearchResult } from '../../shared/search/models/search-result.model';
1717
import { DSpaceObject } from '../../core/shared/dspace-object.model';
18+
import { BitstreamDataService, MetadataFilter } from '../../core/data/bitstream-data.service';
19+
import { RemoteData } from '../../core/data/remote-data';
20+
import { PaginatedList } from '../../core/data/paginated-list.model';
21+
import { Bitstream } from '../../core/shared/bitstream.model';
22+
import { RouterMock } from '../../shared/mocks/router.mock';
23+
import { MetadataMap, MetadataValue } from '../../core/shared/metadata.models';
1824

1925
describe('SearchComponent', () => {
2026
let fixture: ComponentFixture<LuckySearchComponent>;
@@ -39,6 +45,9 @@ describe('SearchComponent', () => {
3945
}
4046
]))
4147
});
48+
const bitstreamDataService = jasmine.createSpyObj('bitstreamDataService', {
49+
findByItem: jasmine.createSpy('findByItem')
50+
});
4251
const mockSearchOptions = observableOf(new PaginatedSearchOptions({
4352
pagination: Object.assign(new PaginationComponentOptions(), {
4453
id: 'search-page-configuration',
@@ -52,18 +61,12 @@ describe('SearchComponent', () => {
5261
};
5362
let component: LuckySearchComponent;
5463

55-
const itemPageUrl = '/lucky-search?index=xxx&value=yyyy';
5664
const urlTree = new UrlTree();
5765
urlTree.queryParams = {
5866
index: 'test',
5967
'value': 'test'
6068
};
61-
const routerStub = jasmine.createSpyObj('router', {
62-
parseUrl: urlTree,
63-
createUrlTree: new UrlTree(),
64-
url: itemPageUrl,
65-
navigateByUrl: void {}
66-
});
69+
const routerStub = new RouterMock();
6770
beforeEach(async () => {
6871
await TestBed.configureTestingModule({
6972
declarations: [LuckySearchComponent],
@@ -72,7 +75,7 @@ describe('SearchComponent', () => {
7275
{provide: Router, useValue: routerStub},
7376
{provide: SearchConfigurationService, useValue: searchConfigServiceStub},
7477
{provide: LuckySearchService, useValue: searchServiceStub},
75-
78+
{provide: BitstreamDataService, useValue: bitstreamDataService}
7679
],
7780
})
7881
.compileComponents();
@@ -84,61 +87,144 @@ describe('SearchComponent', () => {
8487
fixture.detectChanges();
8588
});
8689

87-
it('should create', () => {
88-
expect(component).toBeTruthy();
89-
});
90+
describe('should search items', () => {
9091

91-
it('should show multiple results', () => {
92-
expect(component.showMultipleSearchSection).toEqual(true);
93-
});
92+
beforeEach(() => {
93+
spyOn(routerStub, 'parseUrl').and.returnValue(urlTree);
94+
});
9495

95-
it('should display basic search form results', () => {
96-
expect(fixture.debugElement.query(By.css('ds-search-results')))
97-
.toBeTruthy();
98-
});
96+
it('should create', () => {
97+
expect(component).toBeTruthy();
98+
});
9999

100-
beforeEach(() => {
101-
fixture = TestBed.createComponent(LuckySearchComponent);
102-
component = fixture.componentInstance;
103-
const firstSearchResult = Object.assign(new SearchResult(), {
104-
indexableObject: Object.assign(new DSpaceObject(), {
105-
id: 'd317835d-7b06-4219-91e2-1191900cb897',
106-
uuid: 'd317835d-7b06-4219-91e2-1191900cb897',
107-
name: 'My first publication',
108-
metadata: {
109-
'dspace.entity.type': [
110-
{value: 'Publication'}
111-
]
112-
}
113-
})
100+
it('should show multiple results', () => {
101+
expect(component.showMultipleSearchSection).toEqual(true);
114102
});
115103

116-
const data = createSuccessfulRemoteDataObject(createPaginatedList([
117-
firstSearchResult
118-
]));
119-
component.resultsRD$.next(data as any);
120-
fixture.detectChanges();
121-
});
104+
it('should display basic search form results', () => {
105+
expect(fixture.debugElement.query(By.css('ds-search-results')))
106+
.toBeTruthy();
107+
});
122108

123-
it('should call navigate or router', () => {
124-
expect(routerStub.navigateByUrl).toHaveBeenCalled();
125-
});
109+
beforeEach(() => {
110+
fixture = TestBed.createComponent(LuckySearchComponent);
111+
component = fixture.componentInstance;
112+
const firstSearchResult = Object.assign(new SearchResult(), {
113+
indexableObject: Object.assign(new DSpaceObject(), {
114+
id: 'd317835d-7b06-4219-91e2-1191900cb897',
115+
uuid: 'd317835d-7b06-4219-91e2-1191900cb897',
116+
name: 'My first publication',
117+
metadata: {
118+
'dspace.entity.type': [
119+
{value: 'Publication'}
120+
]
121+
}
122+
})
123+
});
124+
125+
const data = createSuccessfulRemoteDataObject(createPaginatedList([
126+
firstSearchResult
127+
]));
128+
component.resultsRD$.next(data as any);
129+
fixture.detectChanges();
130+
});
126131

132+
it('should call navigate or router', () => {
133+
expect(routerStub.navigateByUrl).toHaveBeenCalled();
134+
});
127135

128-
beforeEach(() => {
129-
fixture = TestBed.createComponent(LuckySearchComponent);
130-
component = fixture.componentInstance;
131-
const data = createSuccessfulRemoteDataObject(createPaginatedList([]));
132-
component.resultsRD$.next(data as any);
133-
fixture.detectChanges();
134-
});
136+
beforeEach(() => {
137+
fixture = TestBed.createComponent(LuckySearchComponent);
138+
component = fixture.componentInstance;
139+
const data = createSuccessfulRemoteDataObject(createPaginatedList([]));
140+
component.resultsRD$.next(data as any);
141+
fixture.detectChanges();
142+
});
135143

136-
it('should not have results', () => {
137-
expect(component.showEmptySearchSection).toEqual(true);
144+
it('should not have results', () => {
145+
expect(component.showEmptySearchSection).toEqual(true);
146+
});
147+
148+
it('should display basic search form', () => {
149+
expect(fixture.debugElement.query(By.css('ds-search-form')))
150+
.toBeTruthy();
151+
});
138152
});
139153

140-
it('should display basic search form', () => {
141-
expect(fixture.debugElement.query(By.css('ds-search-form')))
142-
.toBeTruthy();
154+
describe('should search bitstreams', () => {
155+
156+
const bitstreamMetadata = {
157+
'dc.title': [{ value: 'test.pdf' } as MetadataValue],
158+
'dc.description': [{ value: 'TestDescription' } as MetadataValue]
159+
} as MetadataMap;
160+
const bitstream = Object.assign(
161+
new Bitstream(),
162+
{ _name: 'test.pdf', sizeBytes: 15, uuid: 'fa272dbf-e458-4ad2-868b-b4a27c6eac15', metadata: bitstreamMetadata }
163+
) as Bitstream;
164+
165+
beforeEach(() => {
166+
fixture = TestBed.createComponent(LuckySearchComponent);
167+
component = fixture.componentInstance;
168+
169+
const bitstreamSearchTree = new UrlTree();
170+
bitstreamSearchTree.queryParams = {
171+
index: 'testIndex',
172+
value: 'testValue',
173+
bitstreamMetadata: 'testMetadata',
174+
bitstreamValue: 'testMetadataValue'
175+
};
176+
177+
const itemUUID = 'd317835d-7b06-4219-91e2-1191900cb897';
178+
const firstSearchResult = Object.assign(new SearchResult(), {
179+
indexableObject: Object.assign(new DSpaceObject(), {
180+
id: 'd317835d-7b06-4219-91e2-1191900cb897',
181+
uuid: itemUUID,
182+
name: 'My first publication',
183+
metadata: {
184+
'dspace.entity.type': [
185+
{ value: 'Publication' }
186+
]
187+
}
188+
})
189+
});
190+
const data = createSuccessfulRemoteDataObject(createPaginatedList([firstSearchResult]));
191+
const metadataFilters = [{ metadataName: 'dc.title', metadataValue: 'test.pdf' }] as MetadataFilter[];
192+
component.bitstreamFilters = metadataFilters;
193+
bitstreamDataService.findByItem.withArgs(itemUUID, 'ORIGINAL', metadataFilters, {}).and.returnValue(observableOf({
194+
state: 'Success',
195+
payload: { page: [bitstream] },
196+
get hasSucceeded(): boolean {
197+
return true;
198+
}
199+
} as RemoteData<PaginatedList<Bitstream>>));
200+
201+
spyOn(component, 'redirect');
202+
spyOn(component.bitstreams$, 'next');
203+
spyOn(routerStub, 'parseUrl').and.returnValue(bitstreamSearchTree);
204+
205+
component.resultsRD$.next(data as any);
206+
207+
fixture.detectChanges();
208+
});
209+
210+
it('should load item bitstreams', () => {
211+
expect(component.bitstreams$.next).toHaveBeenCalledWith([bitstream]);
212+
});
213+
214+
it('should redirect to bitstream', () => {
215+
expect(component.redirect).toHaveBeenCalledWith('/bitstreams/fa272dbf-e458-4ad2-868b-b4a27c6eac15/download');
216+
});
217+
218+
it('should return bitstream filename', () => {
219+
expect(component.fileName(bitstream)).toEqual('test.pdf');
220+
});
221+
222+
it('should return bitstream description', () => {
223+
expect(component.getDescription(bitstream)).toEqual('TestDescription');
224+
});
225+
226+
it('should return bitstream file size', () => {
227+
expect(component.getSize(bitstream)).toEqual(15);
228+
});
143229
});
144230
});

0 commit comments

Comments
 (0)