1
0

first tests and docs

This commit is contained in:
Lotte Hofstede
2017-05-23 10:21:26 +02:00
parent 0f472fb06b
commit 6aff818dcd
8 changed files with 255 additions and 1 deletions

View File

@@ -0,0 +1,19 @@
import { ProtractorPage } from './simple-item-page.po';
describe('protractor Simple Item Page', function() {
let page: ProtractorPage;
beforeEach(() => {
page = new ProtractorPage();
page.navigateToSimpleItemPage();
});
it('should contain element ds-thumbnail"', () => {
expect(page.elementTagExists("ds-thumbnail")).toEqual(true);
});
it('should contain element h1.item-page-title-field"', () => {
expect(page.elementSelectorExists("h1.selector")).toEqual(true);
});
});

View File

@@ -0,0 +1,19 @@
import { browser, element, by } from 'protractor';
export class ProtractorPage {
ITEMPAGE : string = "/items/8766";
navigateToSimpleItemPage() {
return browser.get(this.ITEMPAGE);
}
elementTagExists(tag : string) {
return element(by.tagName(tag)).isPresent();
}
elementSelectorExists(selector : string) {
return element(by.css(selector)).isPresent();
}
}

View File

@@ -0,0 +1,120 @@
import { TestBed, async } from '@angular/core/testing';
import { Item } from "./item.model";
import { Bundle } from "./bundle.model";
import { Observable } from "rxjs";
import { RemoteData } from "../data/remote-data";
import { Bitstream } from "./bitstream.model";
describe('Item', () => {
let item: Item;
const thumbnailBundleName = "THUMBNAIL";
const originalBundleName = "ORIGINAL";
const thumbnailPath = "thumbnail.jpg";
const bitstream1Path = "document.pdf";
const bitstream2Path = "otherfile.doc";
const nonExistingBundleName = "c1e568f7-d14e-496b-bdd7-07026998cc00";
let remoteThumbnailBundle;
let remoteOriginalBundle;
let thumbnailBundle;
let originalBundle;
beforeEach(() => {
const thumbnail = {
retrieve: thumbnailPath
};
const bitstream1 = {
retrieve: bitstream1Path
};
const bitstream2 = {
retrieve: bitstream2Path
};
const remoteDataThumbnail = createRemoteDataObject(thumbnail);
const remoteDataFile1 = createRemoteDataObject(bitstream1);
const remoteDataFile2 = createRemoteDataObject(bitstream2);
// Create Bundles
thumbnailBundle = {
name: thumbnailBundleName,
primaryBitstream: remoteDataThumbnail
};
originalBundle = {
name: originalBundleName,
bitstreams: [remoteDataFile1, remoteDataFile2]
};
remoteThumbnailBundle = createRemoteDataObject(thumbnailBundle);
remoteOriginalBundle = createRemoteDataObject(originalBundle);
item = Object.assign(new Item(), { bundles: [remoteThumbnailBundle, remoteOriginalBundle] });
});
it('should return the bundle with the given name of this item when the bundle exists', () => {
let name: string = thumbnailBundleName;
let bundle: Observable<Bundle> = item.getBundle(name);
bundle.map(b => expect(b.name).toBe(name));
});
it('should return null when no bundle with this name exists for this item', () => {
let name: string = nonExistingBundleName;
let bundle: Observable<Bundle> = item.getBundle(name);
bundle.map(b => expect(b).toBeNull());
});
describe("get thumbnail", () => {
beforeEach(() => {
spyOn(item, 'getBundle').and.returnValue(Observable.of(thumbnailBundle));
});
it('should return the thumbnail (the primaryBitstream in the bundle "THUMBNAIL") of this item', () => {
let path: string = thumbnailPath;
let bitstream: Observable<Bitstream> = item.getThumbnail();
bitstream.map(b => expect(b.retrieve).toBe(path));
});
});
describe("get files", () => {
beforeEach(() => {
spyOn(item, 'getBundle').and.returnValue(Observable.of(originalBundle));
});
it('should return all files in the ORIGINAL bundle', () => {
let paths = [bitstream1Path, bitstream2Path];
let files: Observable<Array<Observable<Bitstream>>> = item.getFiles();
let index = 0;
files.map(f => expect(f.length).toBe(2));
files.subscribe(
array => array.forEach(
observableFile => observableFile.subscribe(
file => {
expect(file.retrieve).toBe(paths[index]);
index++;
}
)
)
)
});
});
});
function createRemoteDataObject(object: Object) {
return new RemoteData("", Observable.of(false), Observable.of(false), Observable.of(true), Observable.of(undefined), Observable.of(object));
}

View File

@@ -4,6 +4,7 @@ import { RemoteData } from "../data/remote-data";
import { Bundle } from "./bundle.model"; import { Bundle } from "./bundle.model";
import { Bitstream } from "./bitstream.model"; import { Bitstream } from "./bitstream.model";
import { Observable } from "rxjs"; import { Observable } from "rxjs";
import { hasValue } from "../../shared/empty.util";
export class Item extends DSpaceObject { export class Item extends DSpaceObject {
@@ -39,6 +40,11 @@ export class Item extends DSpaceObject {
bundles: Array<RemoteData<Bundle>>; bundles: Array<RemoteData<Bundle>>;
/**
* Retrieves the thumbnail of this item
* @returns {Observable<Bitstream>} the primaryBitstream of the "THUMBNAIL" bundle
*/
getThumbnail(): Observable<Bitstream> { getThumbnail(): Observable<Bitstream> {
const bundle: Observable<Bundle> = this.getBundle("THUMBNAIL"); const bundle: Observable<Bundle> = this.getBundle("THUMBNAIL");
return bundle.flatMap( return bundle.flatMap(
@@ -53,15 +59,24 @@ export class Item extends DSpaceObject {
); );
} }
/**
* Retrieves all files that should be displayed on the item page of this item
* @returns {Observable<Array<Observable<Bitstream>>>} an array of all Bitstreams in the "ORIGINAL" bundle
*/
getFiles(): Observable<Array<Observable<Bitstream>>> { getFiles(): Observable<Array<Observable<Bitstream>>> {
const bundle: Observable <Bundle> = this.getBundle("ORIGINAL"); const bundle: Observable <Bundle> = this.getBundle("ORIGINAL");
return bundle.map(bundle => { return bundle.map(bundle => {
if (bundle != null) { if (hasValue(bundle) && Array.isArray(bundle.bitstreams)) {
return bundle.bitstreams.map(bitstream => bitstream.payload) return bundle.bitstreams.map(bitstream => bitstream.payload)
} }
}); });
} }
/**
* Retrieves the bundle of this item by its name
* @param name The name of the Bundle that should be returned
* @returns {Observable<Bundle>} the Bundle that belongs to this item with the given name
*/
getBundle(name: String): Observable<Bundle> { getBundle(name: String): Observable<Bundle> {
return Observable.combineLatest( return Observable.combineLatest(
...this.bundles.map(b => b.payload), ...this.bundles.map(b => b.payload),
@@ -73,6 +88,10 @@ export class Item extends DSpaceObject {
}); });
} }
/**
* Retrieves all direct parent collections of this item
* @returns {Array<Observable<Collection>>} an array of all Collections that contain this item
*/
getCollections(): Array<Observable<Collection>> { getCollections(): Array<Observable<Collection>> {
return this.parents.map(collection => collection.payload.map(parent => parent)); return this.parents.map(collection => collection.payload.map(parent => parent));
} }

View File

@@ -6,6 +6,12 @@ import { RemoteData } from "../core/data/remote-data";
import { Observable } from "rxjs"; import { Observable } from "rxjs";
import { Bitstream } from "../core/shared/bitstream.model"; import { Bitstream } from "../core/shared/bitstream.model";
/**
* This component renders a simple item page.
* The route parameter 'id' is used to request the item it represents.
* All fields of the item that should be displayed, are defined in its template.
*/
@Component({ @Component({
selector: 'ds-item-page', selector: 'ds-item-page',
styleUrls: ['./item-page.component.css'], styleUrls: ['./item-page.component.css'],

View File

@@ -1,6 +1,12 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { Item } from "../../core/shared/item.model"; import { Item } from "../../core/shared/item.model";
/**
* This component can be used to represent metadata on a simple item page.
* It expects one input parameter of type Item to which the metadata belongs.
* This class can be extended to print certain metadata.
*/
@Component({ @Component({
templateUrl: './item-page-specific-field.component.html' templateUrl: './item-page-specific-field.component.html'
}) })
@@ -8,10 +14,20 @@ export class ItemPageSpecificFieldComponent {
@Input() item: Item; @Input() item: Item;
/**
* Fields (schema.element.qualifier) used to render their values.
*/
fields : string[]; fields : string[];
/**
* Label i18n key for the rendered metadata
*/
label : string; label : string;
/**
* Separator string between multiple values of the metadata fields defined
* @type {string}
*/
separator : string = "<br/>"; separator : string = "<br/>";
constructor() { constructor() {

View File

@@ -0,0 +1,49 @@
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ThumbnailComponent } from "./thumbnail.component";
import { Bitstream } from "../core/shared/bitstream.model";
import { SafeUrlPipe } from "../shared/utils/safe-url-pipe";
describe('ThumbnailComponent', () => {
let comp: ThumbnailComponent;
let fixture: ComponentFixture<ThumbnailComponent>;
let de: DebugElement;
let el: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ThumbnailComponent, SafeUrlPipe]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ThumbnailComponent);
comp = fixture.componentInstance; // BannerComponent test instance
de = fixture.debugElement.query(By.css('div.thumbnail'));
el = de.nativeElement;
});
it('should display image', () => {
comp.thumbnail = new Bitstream();
comp.thumbnail.retrieve = "test.url";
fixture.detectChanges();
let image : HTMLElement = de.query(By.css('img')).nativeElement;
expect(image.getAttribute("src")).toBe(comp.thumbnail.retrieve);
});
it('should display placeholder', () => {
fixture.detectChanges();
let image : HTMLElement = de.query(By.css('img')).nativeElement;
expect(image.getAttribute("src")).toBe(comp.holderSource);
});
});

View File

@@ -1,6 +1,12 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { Bitstream } from "../core/shared/bitstream.model"; import { Bitstream } from "../core/shared/bitstream.model";
/**
* This component renders a given Bitstream as a thumbnail.
* One input parameter of type Bitstream is expected.
* If no Bitstream is provided, a holderjs image will be rendered instead.
*/
@Component({ @Component({
selector: 'ds-thumbnail', selector: 'ds-thumbnail',
styleUrls: ['./thumbnail.component.css'], styleUrls: ['./thumbnail.component.css'],