1
0

Merge branch 'master' into improve-support-for-hal-links

This commit is contained in:
Art Lowel
2017-10-17 10:25:23 +02:00
35 changed files with 1231 additions and 308 deletions

View File

@@ -7,9 +7,9 @@ describe('protractor App', () => {
page = new ProtractorPage(); page = new ProtractorPage();
}); });
it('should display title "DSpace"', () => { it('should display translated title "DSpace Angular :: Home"', () => {
page.navigateTo(); page.navigateTo();
expect<any>(page.getPageTitleText()).toEqual('DSpace'); expect<any>(page.getPageTitleText()).toEqual('DSpace Angular :: Home');
}); });
it('should display header "Welcome to DSpace"', () => { it('should display header "Welcome to DSpace"', () => {

View File

@@ -12,15 +12,14 @@
}, },
"scripts": { "scripts": {
"global": "npm install -g @angular/cli marked node-gyp nodemon node-nightly npm-check-updates npm-run-all rimraf typescript ts-node typedoc webpack webpack-bundle-analyzer pm2 rollup", "global": "npm install -g @angular/cli marked node-gyp nodemon node-nightly npm-check-updates npm-run-all rimraf typescript ts-node typedoc webpack webpack-bundle-analyzer pm2 rollup",
"clean:coverage": "yarn run rimraf coverage", "clean:coverage": "rimraf coverage",
"clean:dist": "yarn run rimraf dist", "clean:dist": "rimraf dist",
"clean:doc": "yarn run rimraf doc", "clean:doc": "rimraf doc",
"clean:log": "yarn run rimraf *.log*", "clean:log": "rimraf *.log*",
"clean:json": "yarn run rimraf *.records.json", "clean:json": "rimraf *.records.json",
"clean:node": "yarn run rimraf node_modules", "clean:node": "rimraf node_modules",
"clean:prod": "yarn run clean:coverage && yarn run clean:doc && yarn run clean:dist && yarn run clean:log && yarn run clean:json", "clean:prod": "yarn run clean:coverage && yarn run clean:doc && yarn run clean:dist && yarn run clean:log && yarn run clean:json",
"clean": "yarn run clean:prod && yarn run clean:node", "clean": "yarn run clean:prod && yarn run clean:node",
"rimraf": "rimraf",
"prebuild": "yarn run clean:dist", "prebuild": "yarn run clean:dist",
"prebuild:aot": "yarn run prebuild", "prebuild:aot": "yarn run prebuild",
"prebuild:prod": "yarn run prebuild", "prebuild:prod": "yarn run prebuild",
@@ -69,15 +68,15 @@
"coverage": "http-server -c-1 -o -p 9875 ./coverage" "coverage": "http-server -c-1 -o -p 9875 ./coverage"
}, },
"dependencies": { "dependencies": {
"@angular/animations": "4.4.4", "@angular/animations": "4.4.5",
"@angular/common": "4.4.4", "@angular/common": "4.4.5",
"@angular/core": "4.4.4", "@angular/core": "4.4.5",
"@angular/forms": "4.4.4", "@angular/forms": "4.4.5",
"@angular/http": "4.4.4", "@angular/http": "4.4.5",
"@angular/platform-browser": "4.4.4", "@angular/platform-browser": "4.4.5",
"@angular/platform-browser-dynamic": "4.4.4", "@angular/platform-browser-dynamic": "4.4.5",
"@angular/platform-server": "4.4.4", "@angular/platform-server": "4.4.5",
"@angular/router": "4.4.4", "@angular/router": "4.4.5",
"@angularclass/bootloader": "1.0.1", "@angularclass/bootloader": "1.0.1",
"@angularclass/idle-preload": "1.0.4", "@angularclass/idle-preload": "1.0.4",
"@ng-bootstrap/ng-bootstrap": "1.0.0-beta.5", "@ng-bootstrap/ng-bootstrap": "1.0.0-beta.5",
@@ -111,10 +110,10 @@
"zone.js": "0.8.18" "zone.js": "0.8.18"
}, },
"devDependencies": { "devDependencies": {
"@angular/compiler": "4.4.4", "@angular/compiler": "4.4.5",
"@angular/compiler-cli": "4.4.4", "@angular/compiler-cli": "4.4.5",
"@ngrx/store-devtools": "4.0.0", "@ngrx/store-devtools": "4.0.0",
"@ngtools/webpack": "1.7.2", "@ngtools/webpack": "1.7.4",
"@types/cookie-parser": "1.4.1", "@types/cookie-parser": "1.4.1",
"@types/deep-freeze": "0.1.1", "@types/deep-freeze": "0.1.1",
"@types/express": "4.0.37", "@types/express": "4.0.37",

View File

@@ -65,12 +65,16 @@
} }
}, },
"home": { "home": {
"title": "DSpace Angular :: Home",
"description": "",
"top-level-communities": { "top-level-communities": {
"head": "Communities in DSpace", "head": "Communities in DSpace",
"help": "Select a community to browse its collections." "help": "Select a community to browse its collections."
} }
}, },
"search": { "search": {
"title": "DSpace Angular :: Search",
"description": "",
"form": { "form": {
"search": "Search", "search": "Search",
"search_dspace": "Search DSpace" "search_dspace": "Search DSpace"

View File

@@ -10,4 +10,6 @@ import { CollectionPageComponent } from './collection-page.component';
]) ])
] ]
}) })
export class CollectionPageRoutingModule { } export class CollectionPageRoutingModule {
}

View File

@@ -12,6 +12,8 @@ import { Bitstream } from '../core/shared/bitstream.model';
import { Collection } from '../core/shared/collection.model'; import { Collection } from '../core/shared/collection.model';
import { Item } from '../core/shared/item.model'; import { Item } from '../core/shared/item.model';
import { MetadataService } from '../core/metadata/metadata.service';
import { fadeIn, fadeInOut } from '../shared/animations/fade'; import { fadeIn, fadeInOut } from '../shared/animations/fade';
import { hasValue, isNotEmpty } from '../shared/empty.util'; import { hasValue, isNotEmpty } from '../shared/empty.util';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
@@ -35,9 +37,12 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
private subs: Subscription[] = []; private subs: Subscription[] = [];
private collectionId: string; private collectionId: string;
constructor(private collectionDataService: CollectionDataService, constructor(
private itemDataService: ItemDataService, private collectionDataService: CollectionDataService,
private route: ActivatedRoute) { private itemDataService: ItemDataService,
private metadata: MetadataService,
private route: ActivatedRoute
) {
this.paginationConfig = new PaginationComponentOptions(); this.paginationConfig = new PaginationComponentOptions();
this.paginationConfig.id = 'collection-page-pagination'; this.paginationConfig.id = 'collection-page-pagination';
this.paginationConfig.pageSize = 5; this.paginationConfig.pageSize = 5;
@@ -50,12 +55,13 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
Observable.combineLatest( Observable.combineLatest(
this.route.params, this.route.params,
this.route.queryParams, this.route.queryParams,
(params, queryParams,) => { (params, queryParams, ) => {
return Object.assign({}, params, queryParams); return Object.assign({}, params, queryParams);
}) })
.subscribe((params) => { .subscribe((params) => {
this.collectionId = params.id; this.collectionId = params.id;
this.collectionData = this.collectionDataService.findById(this.collectionId); this.collectionData = this.collectionDataService.findById(this.collectionId);
this.metadata.processRemoteData(this.collectionData);
this.subs.push(this.collectionData.payload.subscribe((collection) => this.logoData = collection.logo)); this.subs.push(this.collectionData.payload.subscribe((collection) => this.logoData = collection.logo));
const page = +params.page || this.paginationConfig.currentPage; const page = +params.page || this.paginationConfig.currentPage;

View File

@@ -10,4 +10,6 @@ import { CommunityPageComponent } from './community-page.component';
]) ])
] ]
}) })
export class CommunityPageRoutingModule { } export class CommunityPageRoutingModule {
}

View File

@@ -8,6 +8,8 @@ import { Bitstream } from '../core/shared/bitstream.model';
import { Community } from '../core/shared/community.model'; import { Community } from '../core/shared/community.model';
import { MetadataService } from '../core/metadata/metadata.service';
import { fadeInOut } from '../shared/animations/fade'; import { fadeInOut } from '../shared/animations/fade';
import { hasValue } from '../shared/empty.util'; import { hasValue } from '../shared/empty.util';
@@ -25,6 +27,7 @@ export class CommunityPageComponent implements OnInit, OnDestroy {
constructor( constructor(
private communityDataService: CommunityDataService, private communityDataService: CommunityDataService,
private metadata: MetadataService,
private route: ActivatedRoute private route: ActivatedRoute
) { ) {
@@ -33,15 +36,13 @@ export class CommunityPageComponent implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
this.route.params.subscribe((params: Params) => { this.route.params.subscribe((params: Params) => {
this.communityData = this.communityDataService.findById(params.id); this.communityData = this.communityDataService.findById(params.id);
this.subs.push(this.communityData.payload this.metadata.processRemoteData(this.communityData);
.subscribe((community) => this.logoData = community.logo)); this.subs.push(this.communityData.payload.subscribe((community) => this.logoData = community.logo));
}); });
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.subs this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
.filter((sub) => hasValue(sub))
.forEach((sub) => sub.unsubscribe());
} }
} }

View File

@@ -6,7 +6,7 @@ import { HomePageComponent } from './home-page.component';
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forChild([ RouterModule.forChild([
{ path: '', component: HomePageComponent, pathMatch: 'full' } { path: '', component: HomePageComponent, pathMatch: 'full', data: { title: 'home.title' } }
]) ])
] ]
}) })

View File

@@ -1,15 +1,17 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { animate, state, transition, trigger, style, keyframes } from '@angular/animations'; import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { ItemPageComponent } from '../simple/item-page.component'; import { ItemPageComponent } from '../simple/item-page.component';
import { Metadatum } from '../../core/shared/metadatum.model'; import { Metadatum } from '../../core/shared/metadatum.model';
import { ItemDataService } from '../../core/data/item-data.service'; import { ItemDataService } from '../../core/data/item-data.service';
import { ActivatedRoute } from '@angular/router';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { MetadataService } from '../../core/metadata/metadata.service';
import { fadeInOut } from '../../shared/animations/fade'; import { fadeInOut } from '../../shared/animations/fade';
/** /**
@@ -30,8 +32,8 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit {
metadata: Observable<Metadatum[]>; metadata: Observable<Metadatum[]>;
constructor(route: ActivatedRoute, items: ItemDataService) { constructor(route: ActivatedRoute, items: ItemDataService, metadataService: MetadataService) {
super(route, items); super(route, items, metadataService);
} }
/*** AoT inheritance fix, will hopefully be resolved in the near future **/ /*** AoT inheritance fix, will hopefully be resolved in the near future **/

View File

@@ -8,6 +8,8 @@ import { Bitstream } from '../../core/shared/bitstream.model';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { MetadataService } from '../../core/metadata/metadata.service';
import { fadeInOut } from '../../shared/animations/fade'; import { fadeInOut } from '../../shared/animations/fade';
/** /**
@@ -32,7 +34,11 @@ export class ItemPageComponent implements OnInit {
thumbnail: Observable<Bitstream>; thumbnail: Observable<Bitstream>;
constructor(private route: ActivatedRoute, private items: ItemDataService) { constructor(
private route: ActivatedRoute,
private items: ItemDataService,
private metadataService: MetadataService
) {
} }
@@ -45,6 +51,7 @@ export class ItemPageComponent implements OnInit {
initialize(params) { initialize(params) {
this.id = +params.id; this.id = +params.id;
this.item = this.items.findById(params.id); this.item = this.items.findById(params.id);
this.metadataService.processRemoteData(this.item);
this.thumbnail = this.item.payload.flatMap((i) => i.getThumbnail()); this.thumbnail = this.item.payload.flatMap((i) => i.getThumbnail());
} }

View File

@@ -6,7 +6,7 @@ import { SearchPageComponent } from './search-page.component';
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forChild([ RouterModule.forChild([
{ path: '', component: SearchPageComponent } { path: '', component: SearchPageComponent, data: { title: 'search.title' } }
]) ])
] ]
}) })

View File

@@ -104,7 +104,7 @@ describe('SearchPageComponent', () => {
(comp as any).updateSearchResults({}); (comp as any).updateSearchResults({});
expect(comp.results as any).toBe(mockResults); expect(comp.results as any).toBe(mockResults);
}); });
}); });
}); });

View File

@@ -1,4 +1,3 @@
// ... test imports
import { import {
async, async,
ComponentFixture, ComponentFixture,
@@ -23,14 +22,18 @@ import { AppComponent } from './app.component';
import { HostWindowState } from './shared/host-window.reducer'; import { HostWindowState } from './shared/host-window.reducer';
import { HostWindowResizeAction } from './shared/host-window.actions'; import { HostWindowResizeAction } from './shared/host-window.actions';
import { MockTranslateLoader } from './shared/testing/mock-translate-loader';
import { BrowserTransferStateModule } from '../modules/transfer-state/browser-transfer-state.module'; import { BrowserTransferStateModule } from '../modules/transfer-state/browser-transfer-state.module';
import { BrowserTransferStoreModule } from '../modules/transfer-store/browser-transfer-store.module'; import { BrowserTransferStoreModule } from '../modules/transfer-store/browser-transfer-store.module';
import { MetadataService } from './core/metadata/metadata.service';
import { GLOBAL_CONFIG, ENV_CONFIG } from '../config'; import { GLOBAL_CONFIG, ENV_CONFIG } from '../config';
import { NativeWindowRef, NativeWindowService } from './shared/window.service'; import { NativeWindowRef, NativeWindowService } from './shared/window.service';
import { MockTranslateLoader } from './shared/mocks/mock-translate-loader';
import { MockMetadataService } from './shared/mocks/mock-metadata-service';
let comp: AppComponent; let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>; let fixture: ComponentFixture<AppComponent>;
let de: DebugElement; let de: DebugElement;
@@ -57,6 +60,7 @@ describe('App component', () => {
providers: [ providers: [
{ provide: GLOBAL_CONFIG, useValue: ENV_CONFIG }, { provide: GLOBAL_CONFIG, useValue: ENV_CONFIG },
{ provide: NativeWindowService, useValue: new NativeWindowRef() }, { provide: NativeWindowService, useValue: new NativeWindowRef() },
{ provide: MetadataService, useValue: new MockMetadataService() },
AppComponent AppComponent
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]

View File

@@ -12,12 +12,10 @@ import { TranslateService } from '@ngx-translate/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { TransferState } from '../modules/transfer-state/transfer-state'; import { TransferState } from '../modules/transfer-state/transfer-state';
import { HostWindowState } from './shared/host-window.reducer'; import { HostWindowState } from './shared/host-window.reducer';
import { HostWindowResizeAction } from './shared/host-window.actions'; import { HostWindowResizeAction } from './shared/host-window.actions';
import { NativeWindowRef, NativeWindowService } from './shared/window.service'; import { NativeWindowRef, NativeWindowService } from './shared/window.service';
import { MetadataService } from './core/metadata/metadata.service';
import { GLOBAL_CONFIG, GlobalConfig } from '../config'; import { GLOBAL_CONFIG, GlobalConfig } from '../config';
@@ -35,13 +33,16 @@ export class AppComponent implements OnInit {
@Inject(NativeWindowService) private _window: NativeWindowRef, @Inject(NativeWindowService) private _window: NativeWindowRef,
private translate: TranslateService, private translate: TranslateService,
private cache: TransferState, private cache: TransferState,
private store: Store<HostWindowState> private store: Store<HostWindowState>,
private metadata: MetadataService
) { ) {
// this language will be used as a fallback when a translation isn't found in the current language // this language will be used as a fallback when a translation isn't found in the current language
translate.setDefaultLang('en'); translate.setDefaultLang('en');
// the lang to use, if the lang isn't available, it will use the current loader to get them // the lang to use, if the lang isn't available, it will use the current loader to get them
translate.use('en'); translate.use('en');
metadata.listenForRouteChange();
if (config.debug) { if (config.debug) {
console.info(config); console.info(config);
} }

View File

@@ -1,13 +1,30 @@
import { inheritSerialization } from 'cerialize'; import { inheritSerialization, autoserialize } from 'cerialize';
import { mapsTo } from '../builders/build-decorators';
import { BitstreamFormat } from '../../shared/bitstream-format.model';
import { NormalizedObject } from './normalized-object.model'; import { NormalizedObject } from './normalized-object.model';
@mapsTo(BitstreamFormat)
@inheritSerialization(NormalizedObject) @inheritSerialization(NormalizedObject)
export class NormalizedBitstreamFormat extends NormalizedObject { export class NormalizedBitstreamFormat extends NormalizedObject {
// TODO: this class was created as a placeholder when we connected to the live rest api
get uuid(): string { @autoserialize
return this.self; shortDescription: string;
}
@autoserialize
description: string;
@autoserialize
mimetype: string;
@autoserialize
supportLevel: number;
@autoserialize
internal: boolean;
@autoserialize
extensions: string;
} }

View File

@@ -21,16 +21,11 @@ export class NormalizedBitstream extends NormalizedDSpaceObject {
@autoserialize @autoserialize
content: string; content: string;
/**
* The mime type of this Bitstream
*/
@autoserialize
mimetype: string;
/** /**
* The format of this Bitstream * The format of this Bitstream
*/ */
@autoserialize @autoserialize
@relationship(ResourceType.BitstreamFormat, false)
format: string; format: string;
/** /**

View File

@@ -15,11 +15,9 @@ export class NormalizedObjectFactory {
case ResourceType.Bitstream: { case ResourceType.Bitstream: {
return NormalizedBitstream return NormalizedBitstream
} }
// commented out for now, bitstreamformats aren't used in the UI yet case ResourceType.BitstreamFormat: {
// and slow things down noticeably return NormalizedBitstreamFormat
// case ResourceType.BitstreamFormat: { }
// return NormalizedBitstreamFormat
// }
case ResourceType.Bundle: { case ResourceType.Bundle: {
return NormalizedBundle return NormalizedBundle
} }

View File

@@ -1,29 +1,35 @@
import { NgModule, Optional, SkipSelf, ModuleWithProviders } from '@angular/core'; import {
NgModule,
Optional,
SkipSelf,
ModuleWithProviders
} from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { isNotEmpty } from '../shared/empty.util';
import { DSpaceRESTv2Service } from './dspace-rest-v2/dspace-rest-v2.service';
import { ObjectCacheService } from './cache/object-cache.service';
import { ResponseCacheService } from './cache/response-cache.service';
import { CollectionDataService } from './data/collection-data.service';
import { ItemDataService } from './data/item-data.service';
import { RequestService } from './data/request.service';
import { RemoteDataBuildService } from './cache/builders/remote-data-build.service';
import { CommunityDataService } from './data/community-data.service';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
import { coreEffects } from './core.effects';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store'; import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { coreEffects } from './core.effects';
import { coreReducers } from './core.reducers'; import { coreReducers } from './core.reducers';
import { DSOResponseParsingService } from './data/dso-response-parsing.service';
import { RootResponseParsingService } from './data/root-response-parsing.service'; import { isNotEmpty } from '../shared/empty.util';
import { ApiService } from '../shared/api.service'; import { ApiService } from '../shared/api.service';
import { CollectionDataService } from './data/collection-data.service';
import { CommunityDataService } from './data/community-data.service';
import { DSOResponseParsingService } from './data/dso-response-parsing.service';
import { DSpaceRESTv2Service } from './dspace-rest-v2/dspace-rest-v2.service';
import { HostWindowService } from '../shared/host-window.service'; import { HostWindowService } from '../shared/host-window.service';
import { NativeWindowFactory, NativeWindowService } from '../shared/window.service'; import { ItemDataService } from './data/item-data.service';
import { MetadataService } from './metadata/metadata.service';
import { ObjectCacheService } from './cache/object-cache.service';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
import { RemoteDataBuildService } from './cache/builders/remote-data-build.service';
import { RequestService } from './data/request.service';
import { ResponseCacheService } from './cache/response-cache.service';
import { RootResponseParsingService } from './data/root-response-parsing.service';
import { ServerResponseService } from '../shared/server-response.service'; import { ServerResponseService } from '../shared/server-response.service';
import { NativeWindowFactory, NativeWindowService } from '../shared/window.service';
import { BrowseService } from './browse/browse.service'; import { BrowseService } from './browse/browse.service';
import { BrowseResponseParsingService } from './data/browse-response-parsing.service'; import { BrowseResponseParsingService } from './data/browse-response-parsing.service';
@@ -49,6 +55,7 @@ const PROVIDERS = [
DSpaceRESTv2Service, DSpaceRESTv2Service,
HostWindowService, HostWindowService,
ItemDataService, ItemDataService,
MetadataService,
ObjectCacheService, ObjectCacheService,
PaginationComponentOptions, PaginationComponentOptions,
RemoteDataBuildService, RemoteDataBuildService,

View File

@@ -0,0 +1,226 @@
import { ComponentFixture, TestBed, async, fakeAsync, inject, tick } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { Location, CommonModule } from '@angular/common';
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { By, Meta, MetaDefinition, Title } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { Store, StoreModule } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { MetadataService } from './metadata.service';
import { CoreState } from '../core.reducers';
import { GlobalConfig } from '../../../config/global-config.interface';
import { ENV_CONFIG, GLOBAL_CONFIG } from '../../../config';
import { ItemDataService } from '../data/item-data.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RequestService } from '../data/request.service';
import { ResponseCacheService } from '../cache/response-cache.service';
import { RemoteData } from '../../core/data/remote-data';
import { Item } from '../../core/shared/item.model';
import { MockItem } from '../../shared/mocks/mock-item';
import { MockTranslateLoader } from '../../shared/mocks/mock-translate-loader';
/* tslint:disable:max-classes-per-file */
@Component({
template: `<router-outlet></router-outlet>`
})
class TestComponent {
constructor(private metadata: MetadataService) {
metadata.listenForRouteChange();
}
}
@Component({ template: '' }) class DummyItemComponent {
constructor(private route: ActivatedRoute, private items: ItemDataService, private metadata: MetadataService) {
this.route.params.subscribe((params) => {
this.metadata.processRemoteData(this.items.findById(params.id));
});
}
}
/* tslint:enable:max-classes-per-file */
describe('MetadataService', () => {
let metadataService: MetadataService;
let meta: Meta;
let title: Title;
let store: Store<CoreState>;
let objectCacheService: ObjectCacheService;
let responseCacheService: ResponseCacheService;
let requestService: RequestService;
let remoteDataBuildService: RemoteDataBuildService;
let itemDataService: ItemDataService;
let location: Location;
let router: Router;
let fixture: ComponentFixture<TestComponent>;
let tagStore: Map<string, MetaDefinition[]>;
let envConfig: GlobalConfig;
beforeEach(() => {
store = new Store<CoreState>(undefined, undefined, undefined);
spyOn(store, 'dispatch');
objectCacheService = new ObjectCacheService(store);
responseCacheService = new ResponseCacheService(store);
requestService = new RequestService(objectCacheService, responseCacheService, store);
remoteDataBuildService = new RemoteDataBuildService(objectCacheService, responseCacheService, requestService);
TestBed.configureTestingModule({
imports: [
CommonModule,
StoreModule.forRoot({}),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: MockTranslateLoader
}
}),
RouterTestingModule.withRoutes([
{ path: 'items/:id', component: DummyItemComponent, pathMatch: 'full' },
{ path: 'other', component: DummyItemComponent, pathMatch: 'full', data: { title: 'Dummy Title', description: 'This is a dummy item component for testing!' } }
])
],
declarations: [
TestComponent,
DummyItemComponent
],
providers: [
{ provide: ObjectCacheService, useValue: objectCacheService },
{ provide: ResponseCacheService, useValue: responseCacheService },
{ provide: RequestService, useValue: requestService },
{ provide: RemoteDataBuildService, useValue: remoteDataBuildService },
{ provide: GLOBAL_CONFIG, useValue: ENV_CONFIG },
Meta,
Title,
ItemDataService,
MetadataService
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
meta = TestBed.get(Meta);
title = TestBed.get(Title);
itemDataService = TestBed.get(ItemDataService);
metadataService = TestBed.get(MetadataService);
envConfig = TestBed.get(GLOBAL_CONFIG);
router = TestBed.get(Router);
location = TestBed.get(Location);
fixture = TestBed.createComponent(TestComponent);
tagStore = metadataService.getTagStore();
});
it('items page should set meta tags', fakeAsync(() => {
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(MockItem));
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
tick();
expect(title.getTitle()).toEqual('Test PowerPoint Document');
expect(tagStore.get('citation_title')[0].content).toEqual('Test PowerPoint Document');
expect(tagStore.get('citation_author')[0].content).toEqual('Doe, Jane');
expect(tagStore.get('citation_date')[0].content).toEqual('1650-06-26T19:58:25Z');
expect(tagStore.get('citation_issn')[0].content).toEqual('123456789');
expect(tagStore.get('citation_language')[0].content).toEqual('en');
expect(tagStore.get('citation_keywords')[0].content).toEqual('keyword1; keyword2; keyword3');
}));
it('items page should set meta tags as published Thesis', fakeAsync(() => {
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(mockPublisher(mockType(MockItem, 'Thesis'))));
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
tick();
expect(tagStore.get('citation_dissertation_name')[0].content).toEqual('Test PowerPoint Document');
expect(tagStore.get('citation_dissertation_institution')[0].content).toEqual('Mock Publisher');
expect(tagStore.get('citation_abstract_html_url')[0].content).toEqual([envConfig.ui.baseUrl, router.url].join(''));
expect(tagStore.get('citation_pdf_url')[0].content).toEqual('https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28/content');
}));
it('items page should set meta tags as published Technical Report', fakeAsync(() => {
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(mockPublisher(mockType(MockItem, 'Technical Report'))));
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
tick();
expect(tagStore.get('citation_technical_report_institution')[0].content).toEqual('Mock Publisher');
}));
it('other navigation should title and description', fakeAsync(() => {
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(MockItem));
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
tick();
expect(tagStore.size).toBeGreaterThan(0)
router.navigate(['/other']);
tick();
expect(tagStore.size).toEqual(2);
expect(title.getTitle()).toEqual('Dummy Title');
expect(tagStore.get('title')[0].content).toEqual('Dummy Title');
expect(tagStore.get('description')[0].content).toEqual('This is a dummy item component for testing!');
}));
const mockRemoteData = (mockItem: Item): RemoteData<Item> => {
return new RemoteData<Item>(
Observable.create((observer) => {
observer.next('');
}),
Observable.create((observer) => {
observer.next(false);
}),
Observable.create((observer) => {
observer.next(false);
}),
Observable.create((observer) => {
observer.next(true);
}),
Observable.create((observer) => {
observer.next('');
}),
Observable.create((observer) => {
observer.next(200);
}),
Observable.create((observer) => {
observer.next({});
}),
Observable.create((observer) => {
observer.next(MockItem);
})
);
}
const mockType = (mockItem: Item, type: string): Item => {
const typedMockItem = Object.assign(new Item(), mockItem) as Item;
for (const metadatum of typedMockItem.metadata) {
if (metadatum.key === 'dc.type') {
metadatum.value = type;
break;
}
}
return typedMockItem;
}
const mockPublisher = (mockItem: Item): Item => {
const publishedMockItem = Object.assign(new Item(), mockItem) as Item;
publishedMockItem.metadata.push({
key: 'dc.publisher',
language: 'en_US',
value: 'Mock Publisher'
});
return publishedMockItem;
}
});

View File

@@ -0,0 +1,400 @@
import 'rxjs/add/operator/first'
import 'rxjs/add/operator/take'
import { Inject, Injectable } from '@angular/core';
import {
ActivatedRoute,
Event,
NavigationEnd,
Params,
Router
} from '@angular/router';
import { Meta, MetaDefinition, Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { RemoteData } from '../data/remote-data';
import { Bitstream } from '../shared/bitstream.model';
import { CacheableObject } from '../cache/object-cache.reducer';
import { DSpaceObject } from '../shared/dspace-object.model';
import { Item } from '../shared/item.model';
import { Metadatum } from '../shared/metadatum.model';
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
@Injectable()
export class MetadataService {
private initialized: boolean;
private tagStore: Map<string, MetaDefinition[]>;
private currentObject: BehaviorSubject<DSpaceObject>;
constructor(
private router: Router,
private translate: TranslateService,
private meta: Meta,
private title: Title,
@Inject(GLOBAL_CONFIG) private envConfig: GlobalConfig
) {
// TODO: determine what open graph meta tags are needed and whether
// the differ per route. potentially add image based on DSpaceObject
this.meta.addTags([
{ property: 'og:title', content: 'DSpace Angular Universal' },
{ property: 'og:description', content: 'The modern front-end for DSpace 7.' }
]);
this.initialized = false;
this.tagStore = new Map<string, MetaDefinition[]>();
}
public listenForRouteChange(): void {
this.router.events
.filter((event) => event instanceof NavigationEnd)
.map(() => this.router.routerState.root)
.map((route: ActivatedRoute) => {
route = this.getCurrentRoute(route);
return { params: route.params, data: route.data };
}).subscribe((routeInfo: any) => {
this.processRouteChange(routeInfo);
});
}
public processRemoteData(remoteData: RemoteData<CacheableObject>): void {
remoteData.payload.take(1).subscribe((dspaceObject: DSpaceObject) => {
if (!this.initialized) {
this.initialize(dspaceObject);
}
this.currentObject.next(dspaceObject);
});
}
private processRouteChange(routeInfo: any): void {
if (routeInfo.params.value.id === undefined) {
this.clearMetaTags();
}
if (routeInfo.data.value.title) {
this.translate.get(routeInfo.data.value.title).take(1).subscribe((translatedTitle: string) => {
this.addMetaTag('title', translatedTitle);
this.title.setTitle(translatedTitle);
});
}
if (routeInfo.data.value.description) {
this.translate.get(routeInfo.data.value.description).take(1).subscribe((translatedDescription: string) => {
this.addMetaTag('description', translatedDescription);
});
}
}
private initialize(dspaceObject: DSpaceObject): void {
this.currentObject = new BehaviorSubject<DSpaceObject>(dspaceObject);
this.currentObject.asObservable().distinctUntilKeyChanged('uuid').subscribe(() => {
this.setMetaTags();
});
this.initialized = true;
}
private getCurrentRoute(route: ActivatedRoute): ActivatedRoute {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}
private setMetaTags(): void {
this.clearMetaTags();
this.setTitleTag();
this.setDescriptionTag();
this.setCitationTitleTag();
this.setCitationAuthorTags();
this.setCitationDateTag();
this.setCitationISSNTag();
this.setCitationISBNTag();
this.setCitationLanguageTag();
this.setCitationKeywordsTag();
this.setCitationAbstractUrlTag();
this.setCitationPdfUrlTag();
if (this.isDissertation()) {
this.setCitationDissertationNameTag();
this.setCitationDissertationInstitutionTag();
}
if (this.isTechReport()) {
this.setCitationTechReportInstitutionTag();
}
// this.setCitationJournalTitleTag();
// this.setCitationVolumeTag();
// this.setCitationIssueTag();
// this.setCitationFirstPageTag();
// this.setCitationLastPageTag();
// this.setCitationDOITag();
// this.setCitationPMIDTag();
// this.setCitationFullTextTag();
// this.setCitationConferenceTag();
// this.setCitationPatentCountryTag();
// this.setCitationPatentNumberTag();
}
/**
* Add <meta name="title" ... > to the <head>
*/
private setTitleTag(): void {
const value = this.getMetaTagValue('dc.title');
this.addMetaTag('title', value);
this.title.setTitle(value);
}
/**
* Add <meta name="description" ... > to the <head>
*/
private setDescriptionTag(): void {
// TODO: truncate abstract
const value = this.getMetaTagValue('dc.description.abstract');
this.addMetaTag('desciption', value);
}
/**
* Add <meta name="citation_title" ... > to the <head>
*/
private setCitationTitleTag(): void {
const value = this.getMetaTagValue('dc.title');
this.addMetaTag('citation_title', value);
}
/**
* Add <meta name="citation_author" ... > to the <head>
*/
private setCitationAuthorTags(): void {
const values: string[] = this.getMetaTagValues(['dc.author', 'dc.contributor.author', 'dc.creator']);
this.addMetaTags('citation_author', values);
}
/**
* Add <meta name="citation_date" ... > to the <head>
*/
private setCitationDateTag(): void {
const value = this.getFirstMetaTagValue(['dc.date.copyright', 'dc.date.issued', 'dc.date.available', 'dc.date.accessioned']);
this.addMetaTag('citation_date', value);
}
/**
* Add <meta name="citation_issn" ... > to the <head>
*/
private setCitationISSNTag(): void {
const value = this.getMetaTagValue('dc.identifier.issn');
this.addMetaTag('citation_issn', value);
}
/**
* Add <meta name="citation_isbn" ... > to the <head>
*/
private setCitationISBNTag(): void {
const value = this.getMetaTagValue('dc.identifier.isbn');
this.addMetaTag('citation_isbn', value);
}
/**
* Add <meta name="citation_language" ... > to the <head>
*/
private setCitationLanguageTag(): void {
const value = this.getFirstMetaTagValue(['dc.language', 'dc.language.iso']);
this.addMetaTag('citation_language', value);
}
/**
* Add <meta name="citation_dissertation_name" ... > to the <head>
*/
private setCitationDissertationNameTag(): void {
const value = this.getMetaTagValue('dc.title');
this.addMetaTag('citation_dissertation_name', value);
}
/**
* Add <meta name="citation_dissertation_institution" ... > to the <head>
*/
private setCitationDissertationInstitutionTag(): void {
const value = this.getMetaTagValue('dc.publisher');
this.addMetaTag('citation_dissertation_institution', value);
}
/**
* Add <meta name="citation_technical_report_institution" ... > to the <head>
*/
private setCitationTechReportInstitutionTag(): void {
const value = this.getMetaTagValue('dc.publisher');
this.addMetaTag('citation_technical_report_institution', value);
}
/**
* Add <meta name="citation_keywords" ... > to the <head>
*/
private setCitationKeywordsTag(): void {
const value = this.getMetaTagValuesAndCombine('dc.subject');
this.addMetaTag('citation_keywords', value);
}
/**
* Add <meta name="citation_abstract_html_url" ... > to the <head>
*/
private setCitationAbstractUrlTag(): void {
if (this.currentObject.value instanceof Item) {
const value = [this.envConfig.ui.baseUrl, this.router.url].join('');
this.addMetaTag('citation_abstract_html_url', value);
}
}
/**
* Add <meta name="citation_pdf_url" ... > to the <head>
*/
private setCitationPdfUrlTag(): void {
if (this.currentObject.value instanceof Item) {
const item = this.currentObject.value as Item;
// NOTE: Observable resolves many times with same data
// taking only two, fist one is empty array
item.getFiles().take(2).subscribe((bitstreams: Bitstream[]) => {
for (const bitstream of bitstreams) {
bitstream.format.payload.take(1).subscribe((format) => {
if (format.mimetype === 'application/pdf') {
this.addMetaTag('citation_pdf_url', bitstream.content);
}
});
}
});
}
}
/**
* Returns true if this._item is a dissertation
*
* @returns {boolean}
* true if this._item has a dc.type equal to 'Thesis'
*/
private isDissertation(): boolean {
let isDissertation = false;
for (const metadatum of this.currentObject.value.metadata) {
if (metadatum.key === 'dc.type') {
isDissertation = metadatum.value.toLowerCase() === 'thesis';
break;
}
}
return isDissertation;
}
/**
* Returns true if this._item is a technical report
*
* @returns {boolean}
* true if this._item has a dc.type equal to 'Technical Report'
*/
private isTechReport(): boolean {
let isTechReport = false;
for (const metadatum of this.currentObject.value.metadata) {
if (metadatum.key === 'dc.type') {
isTechReport = metadatum.value.toLowerCase() === 'technical report';
break;
}
}
return isTechReport;
}
private getMetaTagValue(key: string): string {
let value: string;
for (const metadatum of this.currentObject.value.metadata) {
if (metadatum.key === key) {
value = metadatum.value;
}
}
return value;
}
private getFirstMetaTagValue(keys: string[]): string {
let value: string;
for (const metadatum of this.currentObject.value.metadata) {
for (const key of keys) {
if (key === metadatum.key) {
value = metadatum.value;
break;
}
}
if (value !== undefined) {
break;
}
}
return value;
}
private getMetaTagValuesAndCombine(key: string): string {
return this.getMetaTagValues([key]).join('; ');
}
private getMetaTagValues(keys: string[]): string[] {
const values: string[] = [];
for (const metadatum of this.currentObject.value.metadata) {
for (const key of keys) {
if (key === metadatum.key) {
values.push(metadatum.value);
}
}
}
return values;
}
private addMetaTag(property: string, content: string): void {
if (content) {
const tag = { property, content } as MetaDefinition;
this.meta.addTag(tag);
this.storeTag(property, tag);
}
}
private addMetaTags(property: string, content: string[]): void {
for (const value of content) {
this.addMetaTag(property, value);
}
}
private storeTag(key: string, tag: MetaDefinition): void {
const tags: MetaDefinition[] = this.getTags(key);
tags.push(tag);
this.setTags(key, tags);
}
private getTags(key: string): MetaDefinition[] {
let tags: MetaDefinition[] = this.tagStore.get(key);
if (tags === undefined) {
tags = [];
}
return tags;
}
private setTags(key: string, tags: MetaDefinition[]): void {
this.tagStore.set(key, tags);
}
public clearMetaTags() {
this.tagStore.forEach((tags: MetaDefinition[], property: string) => {
this.meta.removeTag("property='" + property + "'");
});
this.tagStore.clear();
}
public getTagStore(): Map<string, MetaDefinition[]> {
return this.tagStore;
}
}

View File

@@ -0,0 +1,17 @@
import { DSpaceObject } from './dspace-object.model';
export class BitstreamFormat extends DSpaceObject {
shortDescription: string;
description: string;
mimetype: string;
supportLevel: number;
internal: boolean;
extensions: string;
}

View File

@@ -1,6 +1,7 @@
import { DSpaceObject } from './dspace-object.model'; import { DSpaceObject } from './dspace-object.model';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { Item } from './item.model'; import { Item } from './item.model';
import { BitstreamFormat } from './bitstream-format.model';
export class Bitstream extends DSpaceObject { export class Bitstream extends DSpaceObject {
@@ -9,11 +10,6 @@ export class Bitstream extends DSpaceObject {
*/ */
sizeBytes: number; sizeBytes: number;
/**
* The mime type of this Bitstream
*/
mimetype: string;
/** /**
* The description of this Bitstream * The description of this Bitstream
*/ */
@@ -24,6 +20,11 @@ export class Bitstream extends DSpaceObject {
*/ */
bundleName: string; bundleName: string;
/**
* An array of Bitstream Format of this Bitstream
*/
format: RemoteData<BitstreamFormat>;
/** /**
* An array of Items that are direct parents of this Bitstream * An array of Items that are direct parents of this Bitstream
*/ */

View File

@@ -21,7 +21,7 @@ import { Store, StoreModule } from '@ngrx/store';
// Load the implementations that should be tested // Load the implementations that should be tested
import { FooterComponent } from './footer.component'; import { FooterComponent } from './footer.component';
import { MockTranslateLoader } from '../shared/testing/mock-translate-loader'; import { MockTranslateLoader } from '../shared/mocks/mock-translate-loader';
let comp: FooterComponent; let comp: FooterComponent;
let fixture: ComponentFixture<FooterComponent>; let fixture: ComponentFixture<FooterComponent>;

View File

@@ -4,7 +4,7 @@ import { DebugElement } from '@angular/core';
import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core'; import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core';
import { MockTranslateLoader } from '../testing/mock-translate-loader'; import { MockTranslateLoader } from '../mocks/mock-translate-loader';
import { ErrorComponent } from './error.component'; import { ErrorComponent } from './error.component';
@@ -25,8 +25,8 @@ describe('ErrorComponent (inline template)', () => {
} }
}), }),
], ],
declarations: [ ErrorComponent ], // declare the test component declarations: [ErrorComponent], // declare the test component
providers: [ TranslateService ] providers: [TranslateService]
}).compileComponents(); // compile template and css }).compileComponents(); // compile template and css
})); }));

View File

@@ -4,7 +4,7 @@ import { DebugElement } from '@angular/core';
import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core'; import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core';
import { MockTranslateLoader } from '../testing/mock-translate-loader'; import { MockTranslateLoader } from '../mocks/mock-translate-loader';
import { LoadingComponent } from './loading.component'; import { LoadingComponent } from './loading.component';
@@ -25,8 +25,8 @@ describe('LoadingComponent (inline template)', () => {
} }
}), }),
], ],
declarations: [ LoadingComponent ], // declare the test component declarations: [LoadingComponent], // declare the test component
providers: [ TranslateService ] providers: [TranslateService]
}).compileComponents(); // compile template and css }).compileComponents(); // compile template and css
})); }));

View File

@@ -0,0 +1,6 @@
import { Action } from '@ngrx/store';
export class MockAction implements Action {
type = null;
payload: {};
}

View File

@@ -0,0 +1,34 @@
import { Params } from '@angular/router';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
export class MockActivatedRoute {
private _testParams?: any;
// ActivatedRoute.params is Observable
private subject?: BehaviorSubject<any> = new BehaviorSubject(this.testParams);
params = this.subject.asObservable();
queryParams = this.subject.asObservable();
constructor(params?: Params) {
if (params) {
this.testParams = params;
} else {
this.testParams = {};
}
}
// Test parameters
get testParams() { return this._testParams; }
set testParams(params: {}) {
this._testParams = params;
this.subject.next(params);
}
// ActivatedRoute.snapshot.params
get snapshot() {
return { params: this.testParams };
}
}

View File

@@ -0,0 +1,19 @@
import { Observable } from 'rxjs/Observable';
// declare a stub service
export class MockHostWindowService {
private width: number;
constructor(width) {
this.setWidth(width);
}
setWidth(width) {
this.width = width;
}
isXs(): Observable<boolean> {
return Observable.of(this.width < 576);
}
}

View File

@@ -0,0 +1,273 @@
import { Observable } from 'rxjs/Observable';
import { Item } from '../../core/shared/item.model';
/* tslint:disable:no-shadowed-variable */
export const MockItem: Item = Object.assign(new Item(), {
handle: '10673/6',
lastModified: '2017-04-24T19:44:08.178+0000',
isArchived: true,
isDiscoverable: true,
isWithdrawn: false,
bitstreams: {
self: {
_isScalar: true,
value: '1507836003548',
scheduler: null
},
requestPending: Observable.create((observer) => {
observer.next(false);
}),
responsePending: Observable.create((observer) => {
observer.next(false);
}),
isSuccessFul: Observable.create((observer) => {
observer.next(true);
}),
errorMessage: Observable.create((observer) => {
observer.next('');
}),
statusCode: Observable.create((observer) => {
observer.next(202);
}),
pageInfo: Observable.create((observer) => {
observer.next({});
}),
payload: Observable.create((observer) => {
observer.next([
{
sizeBytes: 10201,
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713/content',
format: {
self: {
_isScalar: true,
value: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10',
scheduler: null
},
requestPending: Observable.create((observer) => {
observer.next(false);
}),
responsePending: Observable.create((observer) => {
observer.next(false);
}),
isSuccessFul: Observable.create((observer) => {
observer.next(true);
}),
errorMessage: Observable.create((observer) => {
observer.next('');
}),
statusCode: Observable.create((observer) => {
observer.next(202);
}),
pageInfo: Observable.create((observer) => {
observer.next({});
}),
payload: Observable.create((observer) => {
observer.next({
shortDescription: 'Microsoft Word XML',
description: 'Microsoft Word XML',
mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
supportLevel: 0,
internal: false,
extensions: null,
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10'
});
})
},
bundleName: 'ORIGINAL',
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713',
id: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
uuid: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
type: 'bitstream',
name: 'test_word.docx',
metadata: [
{
key: 'dc.title',
language: null,
value: 'test_word.docx'
}
]
},
{
sizeBytes: 31302,
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28/content',
format: {
self: {
_isScalar: true,
value: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4',
scheduler: null
},
requestPending: Observable.create((observer) => {
observer.next(false);
}),
responsePending: Observable.create((observer) => {
observer.next(false);
}),
isSuccessFul: Observable.create((observer) => {
observer.next(true);
}),
errorMessage: Observable.create((observer) => {
observer.next('');
}),
statusCode: Observable.create((observer) => {
observer.next(202);
}),
pageInfo: Observable.create((observer) => {
observer.next({});
}),
payload: Observable.create((observer) => {
observer.next({
shortDescription: 'Adobe PDF',
description: 'Adobe Portable Document Format',
mimetype: 'application/pdf',
supportLevel: 0,
internal: false,
extensions: null,
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4'
});
})
},
bundleName: 'ORIGINAL',
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28',
id: '99b00f3c-1cc6-4689-8158-91965bee6b28',
uuid: '99b00f3c-1cc6-4689-8158-91965bee6b28',
type: 'bitstream',
name: 'test_pdf.pdf',
metadata: [
{
key: 'dc.title',
language: null,
value: 'test_pdf.pdf'
}
]
}
]);
})
},
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357',
id: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',
uuid: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',
type: 'item',
name: 'Test PowerPoint Document',
metadata: [
{
key: 'dc.creator',
language: 'en_US',
value: 'Doe, Jane'
},
{
key: 'dc.date.accessioned',
language: null,
value: '1650-06-26T19:58:25Z'
},
{
key: 'dc.date.available',
language: null,
value: '1650-06-26T19:58:25Z'
},
{
key: 'dc.date.issued',
language: null,
value: '1650-06-26'
},
{
key: 'dc.identifier.issn',
language: 'en_US',
value: '123456789'
},
{
key: 'dc.identifier.uri',
language: null,
value: 'http://dspace7.4science.it/xmlui/handle/10673/6'
},
{
key: 'dc.description.abstract',
language: 'en_US',
value: 'This is really just a sample abstract. If it was a real abstract it would contain useful information about this test document. Sorry though, nothing useful in this paragraph. You probably shouldn\'t have even bothered to read it!'
},
{
key: 'dc.description.provenance',
language: 'en',
value: 'Made available in DSpace on 2012-06-26T19:58:25Z (GMT). No. of bitstreams: 2\r\ntest_ppt.ppt: 12707328 bytes, checksum: a353fc7d29b3c558c986f7463a41efd3 (MD5)\r\ntest_ppt.pptx: 12468572 bytes, checksum: 599305edb4ebee329667f2c35b14d1d6 (MD5)'
},
{
key: 'dc.description.provenance',
language: 'en',
value: 'Restored into DSpace on 2013-06-13T09:17:34Z (GMT).'
},
{
key: 'dc.description.provenance',
language: 'en',
value: 'Restored into DSpace on 2013-06-13T11:04:16Z (GMT).'
},
{
key: 'dc.description.provenance',
language: 'en',
value: 'Restored into DSpace on 2017-04-24T19:44:08Z (GMT).'
},
{
key: 'dc.language',
language: 'en_US',
value: 'en'
},
{
key: 'dc.rights',
language: 'en_US',
value: '© Jane Doe'
},
{
key: 'dc.subject',
language: 'en_US',
value: 'keyword1'
},
{
key: 'dc.subject',
language: 'en_US',
value: 'keyword2'
},
{
key: 'dc.subject',
language: 'en_US',
value: 'keyword3'
},
{
key: 'dc.title',
language: 'en_US',
value: 'Test PowerPoint Document'
},
{
key: 'dc.type',
language: 'en_US',
value: 'text'
}
],
owningCollection: {
self: {
_isScalar: true,
value: 'https://dspace7.4science.it/dspace-spring-rest/api/core/collections/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb',
scheduler: null
},
requestPending: Observable.create((observer) => {
observer.next(false);
}),
responsePending: Observable.create((observer) => {
observer.next(false);
}),
isSuccessFul: Observable.create((observer) => {
observer.next(true);
}),
errorMessage: Observable.create((observer) => {
observer.next('');
}),
statusCode: Observable.create((observer) => {
observer.next(202);
}),
pageInfo: Observable.create((observer) => {
observer.next({});
}),
payload: Observable.create((observer) => {
observer.next([]);
})
}
})
/* tslint:enable:no-shadowed-variable */

View File

@@ -0,0 +1,9 @@
export class MockMetadataService {
// tslint:disable-next-line:no-empty
public listenForRouteChange(): void {
}
}

View File

@@ -0,0 +1,4 @@
export class MockRouter {
// noinspection TypeScriptUnresolvedFunction
navigate = jasmine.createSpy('navigate');
}

View File

@@ -0,0 +1,23 @@
import { Action } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
export class MockStore<T> extends BehaviorSubject<T> {
constructor(private _initialState: T) {
super(_initialState);
}
dispatch = (action: Action): void => {
console.info();
}
select = <R>(pathOrMapFn: any): Observable<T> => {
return Observable.of(this.getValue());
}
nextState(_newState: T) {
this.next(_newState);
}
}

View File

@@ -0,0 +1,8 @@
import { TranslateLoader } from '@ngx-translate/core';
import { Observable } from 'rxjs/Observable';
export class MockTranslateLoader implements TranslateLoader {
getTranslation(lang: string): Observable<any> {
return Observable.of({});
}
}

View File

@@ -34,10 +34,10 @@ import Spy = jasmine.Spy;
import { PaginationComponent } from './pagination.component'; import { PaginationComponent } from './pagination.component';
import { PaginationComponentOptions } from './pagination-component-options.model'; import { PaginationComponentOptions } from './pagination-component-options.model';
import { MockTranslateLoader } from '../testing/mock-translate-loader'; import { MockTranslateLoader } from '../mocks/mock-translate-loader';
import { HostWindowServiceStub } from '../testing/host-window-service-stub'; import { MockHostWindowService } from '../mocks/mock-host-window-service';
import { ActivatedRouteStub } from '../testing/active-router-stub'; import { MockActivatedRoute } from '../mocks/mock-active-router';
import { RouterStub } from '../testing/router-stub'; import { MockRouter } from '../mocks/mock-router';
import { HostWindowService } from '../host-window.service'; import { HostWindowService } from '../host-window.service';
import { EnumKeysPipe } from '../utils/enum-keys-pipe'; import { EnumKeysPipe } from '../utils/enum-keys-pipe';
@@ -45,7 +45,7 @@ import { SortOptions } from '../../core/cache/models/sort-options.model';
import { GLOBAL_CONFIG, ENV_CONFIG } from '../../../config'; import { GLOBAL_CONFIG, ENV_CONFIG } from '../../../config';
function createTestComponent<T>(html: string, type: { new (...args: any[]): T }): ComponentFixture<T> { function createTestComponent<T>(html: string, type: { new(...args: any[]): T }): ComponentFixture<T> {
TestBed.overrideComponent(type, { TestBed.overrideComponent(type, {
set: { template: html } set: { template: html }
}); });
@@ -123,19 +123,19 @@ describe('Pagination component', () => {
let testFixture: ComponentFixture<TestComponent>; let testFixture: ComponentFixture<TestComponent>;
let de: DebugElement; let de: DebugElement;
let html; let html;
let hostWindowServiceStub: HostWindowServiceStub; let hostWindowServiceStub: MockHostWindowService;
let activatedRouteStub: ActivatedRouteStub; let activatedRouteStub: MockActivatedRoute;
let routerStub: RouterStub; let routerStub: MockRouter;
// Define initial state and test state // Define initial state and test state
const _initialState = { width: 1600, height: 770 }; const _initialState = { width: 1600, height: 770 };
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
activatedRouteStub = new ActivatedRouteStub(); activatedRouteStub = new MockActivatedRoute();
routerStub = new RouterStub(); routerStub = new MockRouter();
hostWindowServiceStub = new HostWindowServiceStub(_initialState.width); hostWindowServiceStub = new MockHostWindowService(_initialState.width);
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [

268
yarn.lock
View File

@@ -2,79 +2,79 @@
# yarn lockfile v1 # yarn lockfile v1
"@angular/animations@4.4.4": "@angular/animations@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.4.4.tgz#a2f9353604347abe15df98292058842f52f08bc2" resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.4.5.tgz#5a5a551d757e5a5560098f6f8535c102d93954d7"
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@angular/common@4.4.4": "@angular/common@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.4.4.tgz#ae0a818aaa0c6a3f0901e7b80bd94e1c22eb9365" resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.4.5.tgz#bd5179dc922adbf4c3ea6dfb19e73cb849ffdc37"
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@angular/compiler-cli@4.4.4": "@angular/compiler-cli@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-4.4.4.tgz#063080a497d9175396825050222c717da184f6cf" resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-4.4.5.tgz#61fa0336acd1a208c5f1c5c6d4df679e99953248"
dependencies: dependencies:
"@angular/tsc-wrapped" "4.4.4" "@angular/tsc-wrapped" "4.4.5"
minimist "^1.2.0" minimist "^1.2.0"
reflect-metadata "^0.1.2" reflect-metadata "^0.1.2"
"@angular/compiler@4.4.4": "@angular/compiler@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.4.4.tgz#326eb0029d9a3541aaca124def9adc51c36f2b41" resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.4.5.tgz#8721a5910f2bb52f09e2d404cad264f35ede5902"
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@angular/core@4.4.4": "@angular/core@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.4.4.tgz#bd37ecf54158f97489996c9386bd222f80a32f5c" resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.4.5.tgz#54acbcbda11719f883c786a906974abeb132f1a0"
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@angular/forms@4.4.4": "@angular/forms@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.4.4.tgz#4db3790509b6b10f1db8a7c1b7f52187cf64cfd4" resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.4.5.tgz#e9552086232aab2ce1d08ef198b62204ea13c43b"
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@angular/http@4.4.4": "@angular/http@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.4.4.tgz#667faf616bb624168eafae6ee92e5eba23a9d1f2" resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.4.5.tgz#2c735ed842401fc2356419268e288dcf2396e84f"
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@angular/platform-browser-dynamic@4.4.4": "@angular/platform-browser-dynamic@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.4.4.tgz#c3c9eb854a528556a07054127932e527fa932e14" resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.4.5.tgz#774dbdc1d90f775dbf1e319f6ed42b260623b61f"
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@angular/platform-browser@4.4.4": "@angular/platform-browser@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.4.4.tgz#a3898e2e7ba9d84ffa0d47144c6971179c75aee6" resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.4.5.tgz#74eb91c0b758126f26d53ee56c7cf4668bd9cac5"
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@angular/platform-server@4.4.4": "@angular/platform-server@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-4.4.4.tgz#73ee41fa1cec8628fcc03174727b27cb0031b22a" resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-4.4.5.tgz#76f23b2c384ed7395dc1793cf85978883ba2cb50"
dependencies: dependencies:
parse5 "^3.0.1" parse5 "^3.0.1"
tslib "^1.7.1" tslib "^1.7.1"
xhr2 "^0.1.4" xhr2 "^0.1.4"
"@angular/router@4.4.4": "@angular/router@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.4.4.tgz#7be391096e843cb3e04f9f05d1d65a88df9bc7cf" resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.4.5.tgz#f73130cf487d9a32cc1988afda59665f44a28a89"
dependencies: dependencies:
tslib "^1.7.1" tslib "^1.7.1"
"@angular/tsc-wrapped@4.4.4": "@angular/tsc-wrapped@4.4.5":
version "4.4.4" version "4.4.5"
resolved "https://registry.yarnpkg.com/@angular/tsc-wrapped/-/tsc-wrapped-4.4.4.tgz#9841821e55616b826ca160250fe85e15fc74ffc3" resolved "https://registry.yarnpkg.com/@angular/tsc-wrapped/-/tsc-wrapped-4.4.5.tgz#30a0cbb43a663aa75dca984894be4813778ddc9c"
dependencies: dependencies:
tsickle "^0.21.0" tsickle "^0.21.0"
@@ -106,9 +106,9 @@
version "4.0.3" version "4.0.3"
resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-4.0.3.tgz#36abacdfa19bfb8506e40de80bae06050a1e15e9" resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-4.0.3.tgz#36abacdfa19bfb8506e40de80bae06050a1e15e9"
"@ngtools/webpack@1.7.2": "@ngtools/webpack@1.7.4":
version "1.7.2" version "1.7.4"
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-1.7.2.tgz#3fc4de01786dcc2f50d8cbaaa117311e56799977" resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-1.7.4.tgz#5015c47ebd339045dd89a1bef0497f4524d2c8ed"
dependencies: dependencies:
enhanced-resolve "^3.1.0" enhanced-resolve "^3.1.0"
loader-utils "^1.0.2" loader-utils "^1.0.2"
@@ -192,11 +192,7 @@
version "2.0.29" version "2.0.29"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-2.0.29.tgz#5002e14f75e2d71e564281df0431c8c1b4a2a36a" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-2.0.29.tgz#5002e14f75e2d71e564281df0431c8c1b4a2a36a"
"@types/node@*": "@types/node@*", "@types/node@8.0.34":
version "8.0.31"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.31.tgz#d9af61093cf4bfc9f066ca34de0175012cfb0ce9"
"@types/node@8.0.34":
version "8.0.34" version "8.0.34"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.34.tgz#55f801fa2ddb2a40dd6dfc15ecfe1dde9c129fe9" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.34.tgz#55f801fa2ddb2a40dd6dfc15ecfe1dde9c129fe9"
@@ -233,11 +229,7 @@
version "1.6.29" version "1.6.29"
resolved "https://registry.yarnpkg.com/@types/webfontloader/-/webfontloader-1.6.29.tgz#c6b5f6eb8ca31d0aae6b02b6c1300349dd93ea8e" resolved "https://registry.yarnpkg.com/@types/webfontloader/-/webfontloader-1.6.29.tgz#c6b5f6eb8ca31d0aae6b02b6c1300349dd93ea8e"
abbrev@1: abbrev@1, abbrev@1.0.x:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
abbrev@1.0.x:
version "1.0.9" version "1.0.9"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
@@ -554,7 +546,7 @@ async@2.0.1:
dependencies: dependencies:
lodash "^4.8.0" lodash "^4.8.0"
async@2.4.1: async@2.4.1, async@^2.0.0, async@^2.1.2, async@^2.1.5:
version "2.4.1" version "2.4.1"
resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7" resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7"
dependencies: dependencies:
@@ -564,12 +556,6 @@ async@^0.9.0, async@~0.9.0:
version "0.9.2" version "0.9.2"
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
async@^2.0.0, async@^2.1.2, async@^2.1.5:
version "2.5.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d"
dependencies:
lodash "^4.14.0"
asynckit@^0.4.0: asynckit@^0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -582,7 +568,7 @@ atob@~1.1.0:
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773" resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773"
autoprefixer@7.1.5: autoprefixer@7.1.5, autoprefixer@^7.1.1:
version "7.1.5" version "7.1.5"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.5.tgz#d65d14b83c7cd1dd7bc801daa00557addf5a06b2" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.5.tgz#d65d14b83c7cd1dd7bc801daa00557addf5a06b2"
dependencies: dependencies:
@@ -604,17 +590,6 @@ autoprefixer@^6.3.1:
postcss "^5.2.16" postcss "^5.2.16"
postcss-value-parser "^3.2.3" postcss-value-parser "^3.2.3"
autoprefixer@^7.1.1:
version "7.1.4"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.4.tgz#960847dbaa4016bc8e8e52ec891cbf8f1257a748"
dependencies:
browserslist "^2.4.0"
caniuse-lite "^1.0.30000726"
normalize-range "^0.1.2"
num2fraction "^1.2.2"
postcss "^6.0.11"
postcss-value-parser "^3.2.3"
awesome-typescript-loader@3.2.3: awesome-typescript-loader@3.2.3:
version "3.2.3" version "3.2.3"
resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-3.2.3.tgz#aa2119b7c808a031e2b28945b031450a8975367f" resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-3.2.3.tgz#aa2119b7c808a031e2b28945b031450a8975367f"
@@ -807,11 +782,7 @@ blocking-proxy@0.0.5:
dependencies: dependencies:
minimist "^1.2.0" minimist "^1.2.0"
bluebird@^3.3.0, bluebird@^3.4.7: bluebird@^3.3.0, bluebird@^3.4.7, bluebird@^3.5.1:
version "3.5.0"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c"
bluebird@^3.5.1:
version "3.5.1" version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
@@ -989,14 +960,7 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
caniuse-db "^1.0.30000639" caniuse-db "^1.0.30000639"
electron-to-chromium "^1.2.7" electron-to-chromium "^1.2.7"
browserslist@^2.0.0, browserslist@^2.4.0: browserslist@^2.0.0, browserslist@^2.5.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.4.0.tgz#693ee93d01e66468a6348da5498e011f578f87f8"
dependencies:
caniuse-lite "^1.0.30000718"
electron-to-chromium "^1.3.18"
browserslist@^2.5.0:
version "2.5.1" version "2.5.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.5.1.tgz#68e4bc536bbcc6086d62843a2ffccea8396821c6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.5.1.tgz#68e4bc536bbcc6086d62843a2ffccea8396821c6"
dependencies: dependencies:
@@ -1109,13 +1073,13 @@ caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
version "1.0.30000740" version "1.0.30000740"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000740.tgz#03fcaaa176e3ed075895f72d46c1a12149bbeac9" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000740.tgz#03fcaaa176e3ed075895f72d46c1a12149bbeac9"
caniuse-lite@1.0.30000746, caniuse-lite@^1.0.30000744: caniuse-lite@1.0.30000746:
version "1.0.30000746" version "1.0.30000746"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000746.tgz#c64f95a3925cfd30207a308ed76c1ae96ea09ea0" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000746.tgz#c64f95a3925cfd30207a308ed76c1ae96ea09ea0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000718, caniuse-lite@^1.0.30000726: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000744:
version "1.0.30000740" version "1.0.30000745"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000740.tgz#f2c4c04d6564eb812e61006841700ad557f6f973" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000745.tgz#20d6fede1157a4935133502946fc7e0e6b880da5"
capture-stack-trace@^1.0.0: capture-stack-trace@^1.0.0:
version "1.0.0" version "1.0.0"
@@ -1550,14 +1514,10 @@ crc32-stream@^2.0.0:
crc "^3.4.4" crc "^3.4.4"
readable-stream "^2.0.0" readable-stream "^2.0.0"
crc@3.4.4: crc@3.4.4, crc@^3.4.4:
version "3.4.4" version "3.4.4"
resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b" resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b"
crc@^3.4.4:
version "3.5.0"
resolved "https://registry.yarnpkg.com/crc/-/crc-3.5.0.tgz#98b8ba7d489665ba3979f59b21381374101a1964"
create-ecdh@^4.0.0: create-ecdh@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d"
@@ -2056,14 +2016,10 @@ ejs@^2.5.6:
version "2.5.7" version "2.5.7"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a"
electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.18: electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.24:
version "1.3.24" version "1.3.24"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz#9b7b88bb05ceb9fa016a177833cc2dde388f21b6" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz#9b7b88bb05ceb9fa016a177833cc2dde388f21b6"
electron-to-chromium@^1.3.24:
version "1.3.26"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.26.tgz#996427294861a74d9c7c82b9260ea301e8c02d66"
elliptic@^6.0.0: elliptic@^6.0.0:
version "6.4.0" version "6.4.0"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df"
@@ -2432,7 +2388,7 @@ express-session@1.15.6:
uid-safe "~2.1.5" uid-safe "~2.1.5"
utils-merge "1.0.1" utils-merge "1.0.1"
express@4.16.2: express@4.16.2, express@^4.13.3, express@^4.15.2:
version "4.16.2" version "4.16.2"
resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c"
dependencies: dependencies:
@@ -2467,41 +2423,6 @@ express@4.16.2:
utils-merge "1.0.1" utils-merge "1.0.1"
vary "~1.1.2" vary "~1.1.2"
express@^4.13.3, express@^4.15.2:
version "4.16.0"
resolved "https://registry.yarnpkg.com/express/-/express-4.16.0.tgz#b519638e4eb58e7178c81b498ef22f798cb2e255"
dependencies:
accepts "~1.3.4"
array-flatten "1.1.1"
body-parser "1.18.2"
content-disposition "0.5.2"
content-type "~1.0.4"
cookie "0.3.1"
cookie-signature "1.0.6"
debug "2.6.9"
depd "~1.1.1"
encodeurl "~1.0.1"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "1.1.0"
fresh "0.5.2"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "~2.3.0"
parseurl "~1.3.2"
path-to-regexp "0.1.7"
proxy-addr "~2.0.2"
qs "6.5.1"
range-parser "~1.2.0"
safe-buffer "5.1.1"
send "0.16.0"
serve-static "1.13.0"
setprototypeof "1.1.0"
statuses "~1.3.1"
type-is "~1.6.15"
utils-merge "1.0.1"
vary "~1.1.2"
extend-shallow@^2.0.1: extend-shallow@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
@@ -5009,7 +4930,7 @@ os-locale@^2.0.0:
lcid "^1.0.0" lcid "^1.0.0"
mem "^1.1.0" mem "^1.1.0"
os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@@ -5808,7 +5729,7 @@ postcss-zindex@^2.0.1:
postcss "^5.0.4" postcss "^5.0.4"
uniqs "^2.0.0" uniqs "^2.0.0"
postcss@6.0.13, postcss@^6.0.13: postcss@6.0.13, postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.11, postcss@^6.0.13, postcss@^6.0.3, postcss@^6.0.5, postcss@^6.0.6, postcss@^6.0.8:
version "6.0.13" version "6.0.13"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.13.tgz#b9ecab4ee00c89db3ec931145bd9590bbf3f125f" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.13.tgz#b9ecab4ee00c89db3ec931145bd9590bbf3f125f"
dependencies: dependencies:
@@ -5825,14 +5746,6 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0
source-map "^0.5.6" source-map "^0.5.6"
supports-color "^3.2.3" supports-color "^3.2.3"
postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.11, postcss@^6.0.3, postcss@^6.0.5, postcss@^6.0.6, postcss@^6.0.8:
version "6.0.12"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.12.tgz#6b0155089d2d212f7bd6a0cecd4c58c007403535"
dependencies:
chalk "^2.1.0"
source-map "^0.5.7"
supports-color "^4.4.0"
prelude-ls@~1.1.2: prelude-ls@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@@ -5950,14 +5863,10 @@ punycode@^1.2.4, punycode@^1.4.1:
version "1.4.1" version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
q@1.4.1: q@1.4.1, q@^1.1.2, q@^1.4.1:
version "1.4.1" version "1.4.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
q@^1.1.2, q@^1.4.1:
version "1.5.0"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1"
qjobs@^1.1.4: qjobs@^1.1.4:
version "1.1.5" version "1.1.5"
resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73" resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73"
@@ -6089,7 +5998,7 @@ readable-stream@1.0, readable-stream@~1.0.2:
isarray "0.0.1" isarray "0.0.1"
string_decoder "~0.10.x" string_decoder "~0.10.x"
readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9: readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9:
version "2.3.3" version "2.3.3"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
dependencies: dependencies:
@@ -6639,24 +6548,6 @@ semver@~5.3.0:
version "5.3.0" version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
send@0.16.0:
version "0.16.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.16.0.tgz#16338dbb9a2ede4ad57b48420ec3b82d8e80a57b"
dependencies:
debug "2.6.9"
depd "~1.1.1"
destroy "~1.0.4"
encodeurl "~1.0.1"
escape-html "~1.0.3"
etag "~1.8.1"
fresh "0.5.2"
http-errors "~1.6.2"
mime "1.4.1"
ms "2.0.0"
on-finished "~2.3.0"
range-parser "~1.2.0"
statuses "~1.3.1"
send@0.16.1: send@0.16.1:
version "0.16.1" version "0.16.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3"
@@ -6687,15 +6578,6 @@ serve-index@^1.7.2:
mime-types "~2.1.17" mime-types "~2.1.17"
parseurl "~1.3.2" parseurl "~1.3.2"
serve-static@1.13.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.0.tgz#810c91db800e94ba287eae6b4e06caab9fdc16f1"
dependencies:
encodeurl "~1.0.1"
escape-html "~1.0.3"
parseurl "~1.3.2"
send "0.16.0"
serve-static@1.13.1: serve-static@1.13.1:
version "1.13.1" version "1.13.1"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719"
@@ -6953,7 +6835,7 @@ source-map-url@~0.3.0:
version "0.3.0" version "0.3.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9"
source-map@0.5.x, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.3: source-map@0.5.x, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3:
version "0.5.7" version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@@ -7038,11 +6920,7 @@ split@0.3:
dependencies: dependencies:
through "2" through "2"
sprintf-js@^1.0.3: sprintf-js@^1.0.3, sprintf-js@~1.0.2:
version "1.1.1"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c"
sprintf-js@~1.0.2:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@@ -7266,20 +7144,13 @@ throttleit@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
through2@2.0.1: through2@2.0.1, through2@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.1.tgz#384e75314d49f32de12eebb8136b8eb6b5d59da9" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.1.tgz#384e75314d49f32de12eebb8136b8eb6b5d59da9"
dependencies: dependencies:
readable-stream "~2.0.0" readable-stream "~2.0.0"
xtend "~4.0.0" xtend "~4.0.0"
through2@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
dependencies:
readable-stream "^2.1.5"
xtend "~4.0.1"
through@2, through@X.X.X, through@~2.3, through@~2.3.1: through@2, through@X.X.X, through@~2.3, through@~2.3.1:
version "2.3.8" version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
@@ -7320,18 +7191,12 @@ tmp@0.0.30:
dependencies: dependencies:
os-tmpdir "~1.0.1" os-tmpdir "~1.0.1"
tmp@0.0.31: tmp@0.0.31, tmp@0.0.x:
version "0.0.31" version "0.0.31"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7"
dependencies: dependencies:
os-tmpdir "~1.0.1" os-tmpdir "~1.0.1"
tmp@0.0.x:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
dependencies:
os-tmpdir "~1.0.2"
to-array@0.1.4: to-array@0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
@@ -8045,20 +7910,13 @@ write-file-atomic@^2.0.0:
imurmurhash "^0.1.4" imurmurhash "^0.1.4"
signal-exit "^3.0.2" signal-exit "^3.0.2"
ws@1.1.2: ws@1.1.2, ws@^1.0.1:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.2.tgz#8a244fa052401e08c9886cf44a85189e1fd4067f" resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.2.tgz#8a244fa052401e08c9886cf44a85189e1fd4067f"
dependencies: dependencies:
options ">=0.0.5" options ">=0.0.5"
ultron "1.0.x" ultron "1.0.x"
ws@^1.0.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.4.tgz#57f40d036832e5f5055662a397c4de76ed66bf61"
dependencies:
options ">=0.0.5"
ultron "1.0.x"
ws@^2.3.1: ws@^2.3.1:
version "2.3.1" version "2.3.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-2.3.1.tgz#6b94b3e447cb6a363f785eaf94af6359e8e81c80" resolved "https://registry.yarnpkg.com/ws/-/ws-2.3.1.tgz#6b94b3e447cb6a363f785eaf94af6359e8e81c80"
@@ -8104,7 +7962,7 @@ xmlhttprequest-ssl@1.5.3:
version "1.5.3" version "1.5.3"
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d"
xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: xtend@^4.0.0, xtend@~4.0.0:
version "4.0.1" version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"