55143: fixed all tests

This commit is contained in:
lotte
2018-10-11 12:02:40 +02:00
parent 7c16ccafd3
commit 3a8f7754fa
56 changed files with 1389 additions and 1256 deletions

View File

@@ -41,8 +41,8 @@
"server:watch": "nodemon dist/server.js", "server:watch": "nodemon dist/server.js",
"server:watch:debug": "nodemon --debug dist/server.js", "server:watch:debug": "nodemon --debug dist/server.js",
"webpack:watch": "webpack -w --mode development", "webpack:watch": "webpack -w --mode development",
"watch": "yarn run build && npm-run-all -p webpack:watch server:watch --mode development", "watch": "yarn run build && npm-run-all -p webpack:watch server:watch",
"watch:debug": "yarn run build && npm-run-all -p webpack:watch server:watch:debug --mode development", "watch:debug": "yarn run build && npm-run-all -p webpack:watch server:watch:debug",
"predebug": "yarn run build", "predebug": "yarn run build",
"predebug:server": "yarn run build", "predebug:server": "yarn run build",
"debug": "node --debug-brk dist/server.js", "debug": "node --debug-brk dist/server.js",

View File

@@ -14,7 +14,6 @@ import { PaginationComponent } from '../../../shared/pagination/pagination.compo
import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub'; import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub';
import { HostWindowService } from '../../../shared/host-window.service'; import { HostWindowService } from '../../../shared/host-window.service';
describe('MetadataRegistryComponent', () => { describe('MetadataRegistryComponent', () => {
let comp: MetadataRegistryComponent; let comp: MetadataRegistryComponent;
let fixture: ComponentFixture<MetadataRegistryComponent>; let fixture: ComponentFixture<MetadataRegistryComponent>;
@@ -68,5 +67,4 @@ describe('MetadataRegistryComponent', () => {
const mockName: HTMLElement = fixture.debugElement.query(By.css('#metadata-schemas tr:nth-child(2) td:nth-child(3)')).nativeElement; const mockName: HTMLElement = fixture.debugElement.query(By.css('#metadata-schemas tr:nth-child(2) td:nth-child(3)')).nativeElement;
expect(mockName.textContent).toBe('mock'); expect(mockName.textContent).toBe('mock');
}); });
}); });

View File

@@ -1,8 +1,9 @@
import {combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { PaginatedList } from '../../core/data/paginated-list'; import { PaginatedList } from '../../core/data/paginated-list';
import { ItemDataService } from '../../core/data/item-data.service'; import { ItemDataService } from '../../core/data/item-data.service';
import { Observable, Subscription } from 'rxjs';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
@@ -45,7 +46,7 @@ export class BrowseByAuthorPageComponent implements OnInit {
sort: this.sortConfig sort: this.sortConfig
}); });
this.subs.push( this.subs.push(
Observable.combineLatest( observableCombineLatest(
this.route.params, this.route.params,
this.route.queryParams, this.route.queryParams,
(params, queryParams, ) => { (params, queryParams, ) => {

View File

@@ -1,9 +1,10 @@
import {combineLatest as observableCombineLatest, Observable , Subscription } from 'rxjs';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model';
import { PaginatedList } from '../../core/data/paginated-list'; import { PaginatedList } from '../../core/data/paginated-list';
import { ItemDataService } from '../../core/data/item-data.service'; import { ItemDataService } from '../../core/data/item-data.service';
import { Observable , Subscription } from 'rxjs';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
@@ -44,7 +45,7 @@ export class BrowseByTitlePageComponent implements OnInit {
sort: this.sortConfig sort: this.sortConfig
}); });
this.subs.push( this.subs.push(
Observable.combineLatest( observableCombineLatest(
this.route.params, this.route.params,
this.route.queryParams, this.route.queryParams,
(params, queryParams, ) => { (params, queryParams, ) => {

View File

@@ -159,7 +159,7 @@ export class SearchConfigurationService implements OnDestroy {
Object.keys(filterParams).forEach((key) => { Object.keys(filterParams).forEach((key) => {
if (key.endsWith('.min') || key.endsWith('.max')) { if (key.endsWith('.min') || key.endsWith('.max')) {
const realKey = key.slice(0, -4); const realKey = key.slice(0, -4);
if (hasNoValue(filters.find((filter) => filter.key === realKey))) { if (hasNoValue(filters.find((f) => f.key === realKey))) {
const min = filterParams[realKey + '.min'] ? filterParams[realKey + '.min'][0] : '*'; const min = filterParams[realKey + '.min'] ? filterParams[realKey + '.min'][0] : '*';
const max = filterParams[realKey + '.max'] ? filterParams[realKey + '.max'][0] : '*'; const max = filterParams[realKey + '.max'] ? filterParams[realKey + '.max'][0] : '*';
filters.push(new SearchFilter(realKey, ['[' + min + ' TO ' + max + ']'])); filters.push(new SearchFilter(realKey, ['[' + min + ' TO ' + max + ']']));

View File

@@ -1,5 +1,4 @@
import { Observable, of as observableOf, throwError as observableThrowError } from 'rxjs'; import { Observable, of as observableOf, throwError as observableThrowError } from 'rxjs';
import { distinctUntilChanged, filter, map, mergeMap, tap } from 'rxjs/operators'; import { distinctUntilChanged, filter, map, mergeMap, tap } from 'rxjs/operators';
import { Inject, Injectable } from '@angular/core'; import { Inject, Injectable } from '@angular/core';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';

View File

@@ -2,20 +2,18 @@ import { AuthStatusResponse } from '../cache/response-cache.models';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { GlobalConfig } from '../../../config/global-config.interface'; import { GlobalConfig } from '../../../config/global-config.interface';
import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { AuthStatus } from './models/auth-status.model'; import { AuthStatus } from './models/auth-status.model';
import { AuthResponseParsingService } from './auth-response-parsing.service'; import { AuthResponseParsingService } from './auth-response-parsing.service';
import { AuthGetRequest, AuthPostRequest } from '../data/request.models'; import { AuthGetRequest, AuthPostRequest } from '../data/request.models';
import { getMockStore } from '../../shared/mocks/mock-store'; import { MockStore } from '../../shared/testing/mock-store';
import { ObjectCacheState } from '../cache/object-cache.reducer';
describe('AuthResponseParsingService', () => { describe('AuthResponseParsingService', () => {
let service: AuthResponseParsingService; let service: AuthResponseParsingService;
const EnvConfig = {cache: {msToLive: 1000}} as GlobalConfig; const EnvConfig = { cache: { msToLive: 1000 } } as GlobalConfig;
const store = getMockStore() as Store<CoreState>; const store = new MockStore<ObjectCacheState>({});
const objectCacheService = new ObjectCacheService(store); const objectCacheService = new ObjectCacheService(store as any);
beforeEach(() => { beforeEach(() => {
service = new AuthResponseParsingService(EnvConfig, objectCacheService); service = new AuthResponseParsingService(EnvConfig, objectCacheService);

View File

@@ -4,8 +4,7 @@ import { provideMockActions } from '@ngrx/effects/testing';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { cold, hot } from 'jasmine-marbles'; import { cold, hot } from 'jasmine-marbles';
import { Observable } from 'rxjs'; import { Observable, of as observableOf, throwError as observableThrow } from 'rxjs';
import { of as observableOf, throwError as observableThrow } from 'rxjs';
import { AuthEffects } from './auth.effects'; import { AuthEffects } from './auth.effects';
import { import {
@@ -30,16 +29,21 @@ import { EPersonMock } from '../../shared/testing/eperson-mock';
describe('AuthEffects', () => { describe('AuthEffects', () => {
let authEffects: AuthEffects; let authEffects: AuthEffects;
let actions: Observable<any>; let actions: Observable<any>;
const authServiceStub = new AuthServiceStub(); let authServiceStub;
const store: Store<TruncatablesState> = jasmine.createSpyObj('store', { const store: Store<TruncatablesState> = jasmine.createSpyObj('store', {
/* tslint:disable:no-empty */ /* tslint:disable:no-empty */
dispatch: {}, dispatch: {},
/* tslint:enable:no-empty */ /* tslint:enable:no-empty */
select: observableOf(true) select: observableOf(true)
}); });
const token = authServiceStub.getToken(); let token;
function init() {
authServiceStub = new AuthServiceStub();
token = authServiceStub.getToken();
}
beforeEach(() => { beforeEach(() => {
init();
TestBed.configureTestingModule({ TestBed.configureTestingModule({
providers: [ providers: [
AuthEffects, AuthEffects,
@@ -138,7 +142,7 @@ describe('AuthEffects', () => {
describe('when check token failed', () => { describe('when check token failed', () => {
it('should return a CHECK_AUTHENTICATION_TOKEN_ERROR action in response to a CHECK_AUTHENTICATION_TOKEN action', () => { it('should return a CHECK_AUTHENTICATION_TOKEN_ERROR action in response to a CHECK_AUTHENTICATION_TOKEN action', () => {
spyOn((authEffects as any).authService, 'hasValidAuthenticationToken').and.returnValue(Observable.throw('')); spyOn((authEffects as any).authService, 'hasValidAuthenticationToken').and.returnValue(observableThrow(''));
actions = hot('--a-', {a: {type: AuthActionTypes.CHECK_AUTHENTICATION_TOKEN, payload: token}}); actions = hot('--a-', {a: {type: AuthActionTypes.CHECK_AUTHENTICATION_TOKEN, payload: token}});

View File

@@ -1,4 +1,4 @@
import { of as observableOf, throwError as observableThrowError , Observable } from 'rxjs'; import { Observable, of as observableOf, throwError as observableThrowError } from 'rxjs';
import { catchError, filter, map } from 'rxjs/operators'; import { catchError, filter, map } from 'rxjs/operators';
import { Injectable, Injector } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
@@ -11,8 +11,6 @@ import {
HttpResponse, HttpResponse,
HttpResponseBase HttpResponseBase
} from '@angular/common/http'; } from '@angular/common/http';
import { find } from 'lodash'; import { find } from 'lodash';
import { AppState } from '../../app.reducer'; import { AppState } from '../../app.reducer';

View File

@@ -31,38 +31,50 @@ describe('AuthService test', () => {
pipe: observableOf(true) pipe: observableOf(true)
}); });
let authService: AuthService; let authService: AuthService;
const authRequest = new AuthRequestServiceStub(); let authRequest;
const window = new NativeWindowRef(); const window = new NativeWindowRef();
const routerStub = new RouterStub(); const routerStub = new RouterStub();
const routeStub = new ActivatedRouteStub(); let routeStub;
let storage: CookieService; let storage: CookieService;
const token: AuthTokenInfo = new AuthTokenInfo('test_token'); let token: AuthTokenInfo;
token.expires = Date.now() + (1000 * 60 * 60); let authenticatedState;
let authenticatedState = {
authenticated: true,
loaded: true,
loading: false,
authToken: token,
user: EPersonMock
};
const rdbService = getMockRemoteDataBuildService(); const rdbService = getMockRemoteDataBuildService();
describe('', () => {
function init() {
token = new AuthTokenInfo('test_token');
token.expires = Date.now() + (1000 * 60 * 60);
authenticatedState = {
authenticated: true,
loaded: true,
loading: false,
authToken: token,
user: EPersonMock
};
authRequest = new AuthRequestServiceStub();
routeStub = new ActivatedRouteStub();
}
beforeEach(() => {
init();
});
describe('', () => {
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CommonModule, CommonModule,
StoreModule.forRoot({authReducer}), StoreModule.forRoot({ authReducer }),
], ],
declarations: [], declarations: [],
providers: [ providers: [
{provide: AuthRequestService, useValue: authRequest}, { provide: AuthRequestService, useValue: authRequest },
{provide: NativeWindowService, useValue: window}, { provide: NativeWindowService, useValue: window },
{provide: REQUEST, useValue: {}}, { provide: REQUEST, useValue: {} },
{provide: Router, useValue: routerStub}, { provide: Router, useValue: routerStub },
{provide: ActivatedRoute, useValue: routeStub}, { provide: ActivatedRoute, useValue: routeStub },
{provide: Store, useValue: mockStore}, {provide: Store, useValue: mockStore},
{provide: RemoteDataBuildService, useValue: rdbService}, { provide: RemoteDataBuildService, useValue: rdbService },
CookieService, CookieService,
AuthService AuthService
], ],
@@ -115,15 +127,16 @@ describe('AuthService test', () => {
describe('', () => { describe('', () => {
beforeEach(async(() => { beforeEach(async(() => {
init();
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
StoreModule.forRoot({authReducer}) StoreModule.forRoot({ authReducer })
], ],
providers: [ providers: [
{provide: AuthRequestService, useValue: authRequest}, { provide: AuthRequestService, useValue: authRequest },
{provide: REQUEST, useValue: {}}, { provide: REQUEST, useValue: {} },
{provide: Router, useValue: routerStub}, { provide: Router, useValue: routerStub },
{provide: RemoteDataBuildService, useValue: rdbService}, { provide: RemoteDataBuildService, useValue: rdbService },
CookieService CookieService
] ]
}).compileComponents(); }).compileComponents();
@@ -167,12 +180,12 @@ describe('AuthService test', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
StoreModule.forRoot({authReducer}) StoreModule.forRoot({ authReducer })
], ],
providers: [ providers: [
{provide: AuthRequestService, useValue: authRequest}, { provide: AuthRequestService, useValue: authRequest },
{provide: REQUEST, useValue: {}}, { provide: REQUEST, useValue: {} },
{provide: Router, useValue: routerStub}, { provide: Router, useValue: routerStub },
ClientCookieService, ClientCookieService,
CookieService CookieService
] ]

View File

@@ -1,13 +1,14 @@
import { of as observableOf, Observable , Observable } from 'rxjs'; import { Observable, of as observableOf } from 'rxjs';
import { import {
take,
filter,
startWith,
first,
distinctUntilChanged, distinctUntilChanged,
filter,
first,
map, map,
startWith,
switchMap,
take,
withLatestFrom withLatestFrom
, map, switchMap, withLatestFrom } from 'rxjs/operators'; } from 'rxjs/operators';
import { Inject, Injectable } from '@angular/core'; import { Inject, Injectable } from '@angular/core';
import { PRIMARY_OUTLET, Router, UrlSegmentGroup, UrlTree } from '@angular/router'; import { PRIMARY_OUTLET, Router, UrlSegmentGroup, UrlTree } from '@angular/router';
import { HttpHeaders } from '@angular/common/http'; import { HttpHeaders } from '@angular/common/http';

View File

@@ -140,7 +140,7 @@ export class ErrorResponse extends RestResponse {
constructor(error: RequestError) { constructor(error: RequestError) {
super(false, error.statusText); super(false, error.statusText);
console.error(error); // console.error(error);
this.errorMessage = error.message; this.errorMessage = error.message;
} }
} }

View File

@@ -10,134 +10,148 @@ describe('BrowseResponseParsingService', () => {
beforeEach(() => { beforeEach(() => {
service = new BrowseResponseParsingService(); service = new BrowseResponseParsingService();
}); });
let validRequest;
let validResponse;
let invalidResponse1;
let invalidResponse2;
let invalidResponse3;
let definitions;
describe('parse', () => { describe('parse', () => {
const validRequest = new BrowseEndpointRequest('client/b186e8ce-e99c-4183-bc9a-42b4821bdb78', 'https://rest.api/discover/browses'); beforeEach(() => {
validRequest = new BrowseEndpointRequest('client/b186e8ce-e99c-4183-bc9a-42b4821bdb78', 'https://rest.api/discover/browses');
const validResponse = { validResponse = {
payload: { payload: {
_embedded: { _embedded: {
browses: [{ browses: [{
metadataBrowse: false, metadataBrowse: false,
sortOptions: [{ name: 'title', metadata: 'dc.title' }, { sortOptions: [{ name: 'title', metadata: 'dc.title' }, {
name: 'dateissued',
metadata: 'dc.date.issued'
}, { name: 'dateaccessioned', metadata: 'dc.date.accessioned' }],
order: 'ASC',
type: 'browse',
metadata: ['dc.date.issued'],
_links: {
self: { href: 'https://rest.api/discover/browses/dateissued' },
items: { href: 'https://rest.api/discover/browses/dateissued/items' }
}
}, {
metadataBrowse: true,
sortOptions: [{ name: 'title', metadata: 'dc.title' }, {
name: 'dateissued',
metadata: 'dc.date.issued'
}, { name: 'dateaccessioned', metadata: 'dc.date.accessioned' }],
order: 'ASC',
type: 'browse',
metadata: ['dc.contributor.*', 'dc.creator'],
_links: {
self: { href: 'https://rest.api/discover/browses/author' },
entries: { href: 'https://rest.api/discover/browses/author/entries' },
items: { href: 'https://rest.api/discover/browses/author/items' }
}
}]
},
_links: { self: { href: 'https://rest.api/discover/browses' } },
page: { size: 20, totalElements: 2, totalPages: 1, number: 0 }
}, statusCode: '200'
} as DSpaceRESTV2Response;
invalidResponse1 = {
payload: {
_embedded: {
browse: {
metadataBrowse: false,
sortOptions: [{ name: 'title', metadata: 'dc.title' }, {
name: 'dateissued',
metadata: 'dc.date.issued'
}, { name: 'dateaccessioned', metadata: 'dc.date.accessioned' }],
order: 'ASC',
type: 'browse',
metadata: ['dc.date.issued'],
_links: {
self: { href: 'https://rest.api/discover/browses/dateissued' },
items: { href: 'https://rest.api/discover/browses/dateissued/items' }
}
}
},
_links: { self: { href: 'https://rest.api/discover/browses' } },
page: { size: 20, totalElements: 2, totalPages: 1, number: 0 }
}, statusCode: '200'
} as DSpaceRESTV2Response;
invalidResponse2 = {
payload: {
_links: { self: { href: 'https://rest.api/discover/browses' } },
page: { size: 20, totalElements: 2, totalPages: 1, number: 0 }
}, statusCode: '200'
} as DSpaceRESTV2Response;
invalidResponse3 = {
payload: {
_links: { self: { href: 'https://rest.api/discover/browses' } },
page: { size: 20, totalElements: 2, totalPages: 1, number: 0 }
}, statusCode: '500'
} as DSpaceRESTV2Response;
definitions = [
Object.assign(new BrowseDefinition(), {
metadataBrowse: false,
sortOptions: [
{
name: 'title',
metadata: 'dc.title'
},
{
name: 'dateissued', name: 'dateissued',
metadata: 'dc.date.issued' metadata: 'dc.date.issued'
}, { name: 'dateaccessioned', metadata: 'dc.date.accessioned' }], },
order: 'ASC', {
type: 'browse', name: 'dateaccessioned',
metadata: ['dc.date.issued'], metadata: 'dc.date.accessioned'
_links: {
self: { href: 'https://rest.api/discover/browses/dateissued' },
items: { href: 'https://rest.api/discover/browses/dateissued/items' }
} }
}, { ],
metadataBrowse: true, defaultSortOrder: 'ASC',
sortOptions: [{ name: 'title', metadata: 'dc.title' }, { type: 'browse',
metadataKeys: [
'dc.date.issued'
],
_links: {
self: 'https://rest.api/discover/browses/dateissued',
items: 'https://rest.api/discover/browses/dateissued/items'
}
}),
Object.assign(new BrowseDefinition(), {
metadataBrowse: true,
sortOptions: [
{
name: 'title',
metadata: 'dc.title'
},
{
name: 'dateissued', name: 'dateissued',
metadata: 'dc.date.issued' metadata: 'dc.date.issued'
}, { name: 'dateaccessioned', metadata: 'dc.date.accessioned' }], },
order: 'ASC', {
type: 'browse', name: 'dateaccessioned',
metadata: ['dc.contributor.*', 'dc.creator'], metadata: 'dc.date.accessioned'
_links: {
self: { href: 'https://rest.api/discover/browses/author' },
entries: { href: 'https://rest.api/discover/browses/author/entries' },
items: { href: 'https://rest.api/discover/browses/author/items' }
}
}]
},
_links: { self: { href: 'https://rest.api/discover/browses' } },
page: { size: 20, totalElements: 2, totalPages: 1, number: 0 }
}, statusCode: '200'
} as DSpaceRESTV2Response;
const invalidResponse1 = {
payload: {
_embedded: {
browse: {
metadataBrowse: false,
sortOptions: [{ name: 'title', metadata: 'dc.title' }, {
name: 'dateissued',
metadata: 'dc.date.issued'
}, { name: 'dateaccessioned', metadata: 'dc.date.accessioned' }],
order: 'ASC',
type: 'browse',
metadata: ['dc.date.issued'],
_links: {
self: { href: 'https://rest.api/discover/browses/dateissued' },
items: { href: 'https://rest.api/discover/browses/dateissued/items' }
} }
],
defaultSortOrder: 'ASC',
type: 'browse',
metadataKeys: [
'dc.contributor.*',
'dc.creator'
],
_links: {
self: 'https://rest.api/discover/browses/author',
entries: 'https://rest.api/discover/browses/author/entries',
items: 'https://rest.api/discover/browses/author/items'
} }
}, })
_links: { self: { href: 'https://rest.api/discover/browses' } }, ];
page: { size: 20, totalElements: 2, totalPages: 1, number: 0 } });
}, statusCode: '200'
} as DSpaceRESTV2Response;
const invalidResponse2 = {
payload: {
_links: { self: { href: 'https://rest.api/discover/browses' } },
page: { size: 20, totalElements: 2, totalPages: 1, number: 0 }
}, statusCode: '200'
} as DSpaceRESTV2Response ;
const invalidResponse3 = {
payload: {
_links: { self: { href: 'https://rest.api/discover/browses' } },
page: { size: 20, totalElements: 2, totalPages: 1, number: 0 }
}, statusCode: '500'
} as DSpaceRESTV2Response;
const definitions = [
Object.assign(new BrowseDefinition(), {
metadataBrowse: false,
sortOptions: [
{
name: 'title',
metadata: 'dc.title'
},
{
name: 'dateissued',
metadata: 'dc.date.issued'
},
{
name: 'dateaccessioned',
metadata: 'dc.date.accessioned'
}
],
defaultSortOrder: 'ASC',
type: 'browse',
metadataKeys: [
'dc.date.issued'
],
_links: { }
}),
Object.assign(new BrowseDefinition(), {
metadataBrowse: true,
sortOptions: [
{
name: 'title',
metadata: 'dc.title'
},
{
name: 'dateissued',
metadata: 'dc.date.issued'
},
{
name: 'dateaccessioned',
metadata: 'dc.date.accessioned'
}
],
defaultSortOrder: 'ASC',
type: 'browse',
metadataKeys: [
'dc.contributor.*',
'dc.creator'
],
_links: { }
})
];
it('should return a GenericSuccessResponse if data contains a valid browse endpoint response', () => { it('should return a GenericSuccessResponse if data contains a valid browse endpoint response', () => {
const response = service.parse(validRequest, validResponse); const response = service.parse(validRequest, validResponse);
expect(response.constructor).toBe(GenericSuccessResponse); expect(response.constructor).toBe(GenericSuccessResponse);

View File

@@ -1,5 +1,5 @@
import { Observable, throwError as observableThrowError, merge as observableMerge } from 'rxjs'; import { distinctUntilChanged, filter, map, mergeMap, take, tap } from 'rxjs/operators';
import { distinctUntilChanged, filter, first, map, mergeMap, tap } from 'rxjs/operators'; import { merge as observableMerge, Observable, throwError as observableThrowError } from 'rxjs';
import { isEmpty, isNotEmpty } from '../../shared/empty.util'; import { isEmpty, isNotEmpty } from '../../shared/empty.util';
import { NormalizedCommunity } from '../cache/models/normalized-community.model'; import { NormalizedCommunity } from '../cache/models/normalized-community.model';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
@@ -10,7 +10,6 @@ import { DataService } from './data.service';
import { FindAllOptions, FindByIDRequest } from './request.models'; import { FindAllOptions, FindByIDRequest } from './request.models';
import { NormalizedObject } from '../cache/models/normalized-object.model'; import { NormalizedObject } from '../cache/models/normalized-object.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { DSOSuccessResponse } from '../cache/response-cache.models';
export abstract class ComColDataService<TNormalized extends NormalizedObject, TDomain> extends DataService<TNormalized, TDomain> { export abstract class ComColDataService<TNormalized extends NormalizedObject, TDomain> extends DataService<TNormalized, TDomain> {
protected abstract cds: CommunityDataService; protected abstract cds: CommunityDataService;
@@ -31,14 +30,14 @@ export abstract class ComColDataService<TNormalized extends NormalizedObject, TD
if (isEmpty(options.scopeID)) { if (isEmpty(options.scopeID)) {
return this.halService.getEndpoint(this.linkPath); return this.halService.getEndpoint(this.linkPath);
} else { } else {
const scopeCommunityHrefObs = this.cds.getEndpoint() const scopeCommunityHrefObs = this.cds.getEndpoint().pipe(
.flatMap((endpoint: string) => this.cds.getFindByIDHref(endpoint, options.scopeID)) mergeMap((endpoint: string) => this.cds.getFindByIDHref(endpoint, options.scopeID)),
.filter((href: string) => isNotEmpty(href)) filter((href: string) => isNotEmpty(href)),
.take(1) take(1),
.do((href: string) => { tap((href: string) => {
const request = new FindByIDRequest(this.requestService.generateRequestId(), href, options.scopeID); const request = new FindByIDRequest(this.requestService.generateRequestId(), href, options.scopeID);
this.requestService.configure(request); this.requestService.configure(request);
}); }),);
// return scopeCommunityHrefObs.pipe( // return scopeCommunityHrefObs.pipe(
// mergeMap((href: string) => this.responseCache.get(href)), // mergeMap((href: string) => this.responseCache.get(href)),

View File

@@ -41,7 +41,7 @@ export class CommunityDataService extends ComColDataService<NormalizedCommunity,
findTop(options: FindAllOptions = {}): Observable<RemoteData<PaginatedList<Community>>> { findTop(options: FindAllOptions = {}): Observable<RemoteData<PaginatedList<Community>>> {
const hrefObs = this.halService.getEndpoint(this.topLinkPath).pipe(filter((href: string) => isNotEmpty(href)), const hrefObs = this.halService.getEndpoint(this.topLinkPath).pipe(filter((href: string) => isNotEmpty(href)),
mergeMap((endpoint: string) => this.getFindAllHref(endpoint, options)),); mergeMap((endpoint: string) => this.getFindAllHref(options)),);
hrefObs.pipe( hrefObs.pipe(
filter((href: string) => hasValue(href)), filter((href: string) => hasValue(href)),

View File

@@ -9,6 +9,7 @@ import { HALEndpointService } from '../shared/hal-endpoint.service';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { FindAllOptions } from './request.models'; import { FindAllOptions } from './request.models';
import { SortOptions, SortDirection } from '../cache/models/sort-options.model'; import { SortOptions, SortDirection } from '../cache/models/sort-options.model';
import { of as observableOf } from 'rxjs';
const endpoint = 'https://rest.api/core'; const endpoint = 'https://rest.api/core';
@@ -17,107 +18,107 @@ class NormalizedTestObject extends NormalizedObject {
} }
class TestService extends DataService<NormalizedTestObject, any> { class TestService extends DataService<NormalizedTestObject, any> {
constructor( constructor(
protected responseCache: ResponseCacheService, protected responseCache: ResponseCacheService,
protected requestService: RequestService, protected requestService: RequestService,
protected rdbService: RemoteDataBuildService, protected rdbService: RemoteDataBuildService,
protected store: Store<CoreState>, protected store: Store<CoreState>,
protected linkPath: string, protected linkPath: string,
protected halService: HALEndpointService protected halService: HALEndpointService
) { ) {
super(); super();
} }
public getBrowseEndpoint(options: FindAllOptions): Observable<string> { public getBrowseEndpoint(options: FindAllOptions): Observable<string> {
return Observable.of(endpoint); return observableOf(endpoint);
} }
} }
describe('DataService', () => { describe('DataService', () => {
let service: TestService; let service: TestService;
let options: FindAllOptions; let options: FindAllOptions;
const responseCache = {} as ResponseCacheService; const responseCache = {} as ResponseCacheService;
const requestService = {} as RequestService; const requestService = {} as RequestService;
const halService = {} as HALEndpointService; const halService = {} as HALEndpointService;
const rdbService = {} as RemoteDataBuildService; const rdbService = {} as RemoteDataBuildService;
const store = {} as Store<CoreState>; const store = {} as Store<CoreState>;
function initTestService(): TestService { function initTestService(): TestService {
return new TestService( return new TestService(
responseCache, responseCache,
requestService, requestService,
rdbService, rdbService,
store, store,
endpoint, endpoint,
halService halService
); );
} }
service = initTestService(); service = initTestService();
describe('getFindAllHref', () => { describe('getFindAllHref', () => {
it('should return an observable with the endpoint', () => { it('should return an observable with the endpoint', () => {
options = {}; options = {};
(service as any).getFindAllHref(options).subscribe((value) => { (service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(endpoint); expect(value).toBe(endpoint);
} }
); );
});
it('should include page in href if currentPage provided in options', () => {
options = { currentPage: 2 };
const expected = `${endpoint}?page=${options.currentPage - 1}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
});
it('should include size in href if elementsPerPage provided in options', () => {
options = { elementsPerPage: 5 };
const expected = `${endpoint}?size=${options.elementsPerPage}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
});
it('should include sort href if SortOptions provided in options', () => {
const sortOptions = new SortOptions('field1', SortDirection.ASC);
options = { sort: sortOptions};
const expected = `${endpoint}?sort=${sortOptions.field},${sortOptions.direction}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
});
it('should include startsWith in href if startsWith provided in options', () => {
options = { startsWith: 'ab' };
const expected = `${endpoint}?startsWith=${options.startsWith}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
});
it('should include all provided options in href', () => {
const sortOptions = new SortOptions('field1', SortDirection.DESC)
options = {
currentPage: 6,
elementsPerPage: 10,
sort: sortOptions,
startsWith: 'ab'
}
const expected = `${endpoint}?page=${options.currentPage - 1}&size=${options.elementsPerPage}` +
`&sort=${sortOptions.field},${sortOptions.direction}&startsWith=${options.startsWith}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
})
}); });
it('should include page in href if currentPage provided in options', () => {
options = { currentPage: 2 };
const expected = `${endpoint}?page=${options.currentPage - 1}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
});
it('should include size in href if elementsPerPage provided in options', () => {
options = { elementsPerPage: 5 };
const expected = `${endpoint}?size=${options.elementsPerPage}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
});
it('should include sort href if SortOptions provided in options', () => {
const sortOptions = new SortOptions('field1', SortDirection.ASC);
options = { sort: sortOptions };
const expected = `${endpoint}?sort=${sortOptions.field},${sortOptions.direction}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
});
it('should include startsWith in href if startsWith provided in options', () => {
options = { startsWith: 'ab' };
const expected = `${endpoint}?startsWith=${options.startsWith}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
});
it('should include all provided options in href', () => {
const sortOptions = new SortOptions('field1', SortDirection.DESC)
options = {
currentPage: 6,
elementsPerPage: 10,
sort: sortOptions,
startsWith: 'ab'
}
const expected = `${endpoint}?page=${options.currentPage - 1}&size=${options.elementsPerPage}` +
`&sort=${sortOptions.field},${sortOptions.direction}&startsWith=${options.startsWith}`;
(service as any).getFindAllHref(options).subscribe((value) => {
expect(value).toBe(expected);
});
})
});
}); });

View File

@@ -1,5 +1,5 @@
import { filter, take, first } from 'rxjs/operators'; import { distinctUntilChanged, filter, take, first, map } from 'rxjs/operators';
import {of as observableOf, Observable } from 'rxjs'; import { of as observableOf, Observable } from 'rxjs';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { hasValue, isNotEmpty } from '../../shared/empty.util';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
@@ -12,8 +12,6 @@ import { RemoteData } from './remote-data';
import { FindAllOptions, FindAllRequest, FindByIDRequest, GetRequest } from './request.models'; import { FindAllOptions, FindAllRequest, FindByIDRequest, GetRequest } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { NormalizedObject } from '../cache/models/normalized-object.model'; import { NormalizedObject } from '../cache/models/normalized-object.model';
import { promise } from 'selenium-webdriver';
import map = promise.map;
export abstract class DataService<TNormalized extends NormalizedObject, TDomain> { export abstract class DataService<TNormalized extends NormalizedObject, TDomain> {
protected abstract responseCache: ResponseCacheService; protected abstract responseCache: ResponseCacheService;
@@ -29,7 +27,7 @@ export abstract class DataService<TNormalized extends NormalizedObject, TDomain>
let result: Observable<string>; let result: Observable<string>;
const args = []; const args = [];
result = this.getBrowseEndpoint(options).distinctUntilChanged(); result = this.getBrowseEndpoint(options).pipe(distinctUntilChanged());
if (hasValue(options.currentPage) && typeof options.currentPage === 'number') { if (hasValue(options.currentPage) && typeof options.currentPage === 'number') {
/* TODO: this is a temporary fix for the pagination start index (0 or 1) discrepancy between the rest and the frontend respectively */ /* TODO: this is a temporary fix for the pagination start index (0 or 1) discrepancy between the rest and the frontend respectively */

View File

@@ -1,3 +1,5 @@
import {distinctUntilChanged, map, filter} from 'rxjs/operators';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@@ -40,10 +42,10 @@ export class ItemDataService extends DataService<NormalizedItem, Item> {
if (options.sort && options.sort.field) { if (options.sort && options.sort.field) {
field = options.sort.field; field = options.sort.field;
} }
return this.bs.getBrowseURLFor(field, this.linkPath) return this.bs.getBrowseURLFor(field, this.linkPath).pipe(
.filter((href: string) => isNotEmpty(href)) filter((href: string) => isNotEmpty(href)),
.map((href: string) => new URLCombiner(href, `?scope=${options.scopeID}`).toString()) map((href: string) => new URLCombiner(href, `?scope=${options.scopeID}`).toString()),
.distinctUntilChanged(); distinctUntilChanged(),);
} }
} }

View File

@@ -1,37 +0,0 @@
import { select } from '@ngrx/store';
import * as ngrx from '@ngrx/store';
import { cold, hot } from 'jasmine-marbles';
import { Observable } from 'rxjs';
import { count, take } from 'rxjs/operators';
class TestClass {
selectSomething(input$: Observable<any>) {
return input$.pipe(
select('something'),
take(1)
)
}
}
describe('mockSelect', () => {
let testClass;
beforeEach(() => {
spyOnProperty(ngrx, 'select').and.callFake(() => {
return () => {
return () => cold('a', { a: 'bingo!' });
};
});
testClass = new TestClass();
});
it('should mock select', () => {
const input$ = hot('a', { a: '' });
const expected$ = hot('(b|)', { b: 'bingo!' });
const result$ = testClass.selectSomething(input$);
result$.pipe(count()).subscribe((t) => console.log('resykts', t));
expected$.pipe(count()).subscribe((t) => console.log('expected', t));
result$.subscribe((v) => console.log('result$', v));
expected$.subscribe((v) => console.log('expected$', v));
expect(result$).toBeObservable(expected$)
});
})

View File

@@ -1,29 +1,18 @@
import { distinctUntilKeyChanged, filter, first, map, take } from 'rxjs/operators';
import {distinctUntilKeyChanged, map, filter, first, take} from 'rxjs/operators';
import { Inject, Injectable } from '@angular/core'; import { Inject, Injectable } from '@angular/core';
import { import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
ActivatedRoute,
Event,
NavigationEnd,
Params,
Router
} from '@angular/router';
import { Meta, MetaDefinition, Title } from '@angular/platform-browser'; import { Meta, MetaDefinition, Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject , Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { Bitstream } from '../shared/bitstream.model'; import { Bitstream } from '../shared/bitstream.model';
import { CacheableObject } from '../cache/object-cache.reducer'; import { CacheableObject } from '../cache/object-cache.reducer';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { Item } from '../shared/item.model'; import { Item } from '../shared/item.model';
import { Metadatum } from '../shared/metadatum.model';
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
import { BitstreamFormat } from '../shared/bitstream-format.model'; import { BitstreamFormat } from '../shared/bitstream-format.model';

View File

@@ -22,23 +22,28 @@ describe('AuthNavMenuComponent', () => {
let deNavMenuItem: DebugElement; let deNavMenuItem: DebugElement;
let fixture: ComponentFixture<AuthNavMenuComponent>; let fixture: ComponentFixture<AuthNavMenuComponent>;
const notAuthState: AuthState = { let notAuthState: AuthState;
authenticated: false, let authState: AuthState;
loaded: false,
loading: false
};
const authState: AuthState = {
authenticated: true,
loaded: true,
loading: false,
authToken: new AuthTokenInfo('test_token'),
user: EPersonMock
};
let routerState = { let routerState = {
url: '/home' url: '/home'
}; };
function init() {
notAuthState = {
authenticated: false,
loaded: false,
loading: false
};
authState = {
authenticated: true,
loaded: true,
loading: false,
authToken: new AuthTokenInfo('test_token'),
user: EPersonMock
};
}
describe('when is a not mobile view', () => { describe('when is a not mobile view', () => {
beforeEach(async(() => { beforeEach(async(() => {
const window = new HostWindowServiceStub(800); const window = new HostWindowServiceStub(800);
@@ -53,8 +58,13 @@ describe('AuthNavMenuComponent', () => {
AuthNavMenuComponent AuthNavMenuComponent
], ],
providers: [ providers: [
{provide: HostWindowService, useValue: window}, { provide: HostWindowService, useValue: window },
{provide: AuthService, useValue: {setRedirectUrl: () => { /*empty*/ }}} {
provide: AuthService, useValue: {
setRedirectUrl: () => { /*empty*/
}
}
}
], ],
schemas: [ schemas: [
CUSTOM_ELEMENTS_SCHEMA CUSTOM_ELEMENTS_SCHEMA
@@ -64,11 +74,14 @@ describe('AuthNavMenuComponent', () => {
})); }));
beforeEach(() => {
init();
});
describe('when route is /login and user is not authenticated', () => { describe('when route is /login and user is not authenticated', () => {
routerState = {
url: '/login'
};
beforeEach(inject([Store], (store: Store<AppState>) => { beforeEach(inject([Store], (store: Store<AppState>) => {
routerState = {
url: '/login'
};
store store
.subscribe((state) => { .subscribe((state) => {
(state as any).router = Object.create({}); (state as any).router = Object.create({});
@@ -91,7 +104,9 @@ describe('AuthNavMenuComponent', () => {
const navMenuItemSelector = 'li'; const navMenuItemSelector = 'li';
deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector));
})); }));
afterEach(() => {
fixture.destroy();
});
it('should not render', () => { it('should not render', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
expect(deNavMenu.nativeElement).toBeDefined(); expect(deNavMenu.nativeElement).toBeDefined();
@@ -101,10 +116,10 @@ describe('AuthNavMenuComponent', () => {
}); });
describe('when route is /logout and user is authenticated', () => { describe('when route is /logout and user is authenticated', () => {
routerState = {
url: '/logout'
};
beforeEach(inject([Store], (store: Store<AppState>) => { beforeEach(inject([Store], (store: Store<AppState>) => {
routerState = {
url: '/logout'
};
store store
.subscribe((state) => { .subscribe((state) => {
(state as any).router = Object.create({}); (state as any).router = Object.create({});
@@ -128,6 +143,10 @@ describe('AuthNavMenuComponent', () => {
deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector));
})); }));
afterEach(() => {
fixture.destroy();
});
it('should not render', () => { it('should not render', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
expect(deNavMenu.nativeElement).toBeDefined(); expect(deNavMenu.nativeElement).toBeDefined();
@@ -166,6 +185,11 @@ describe('AuthNavMenuComponent', () => {
deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector));
})); }));
afterEach(() => {
fixture.destroy();
component = null;
});
it('should render login dropdown menu', () => { it('should render login dropdown menu', () => {
const loginDropdownMenu = deNavMenuItem.query(By.css('div[id=loginDropdownMenu]')); const loginDropdownMenu = deNavMenuItem.query(By.css('div[id=loginDropdownMenu]'));
expect(loginDropdownMenu.nativeElement).toBeDefined(); expect(loginDropdownMenu.nativeElement).toBeDefined();
@@ -200,6 +224,10 @@ describe('AuthNavMenuComponent', () => {
deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector));
})); }));
afterEach(() => {
fixture.destroy();
component = null;
});
it('should render logout dropdown menu', () => { it('should render logout dropdown menu', () => {
const logoutDropdownMenu = deNavMenuItem.query(By.css('div[id=logoutDropdownMenu]')); const logoutDropdownMenu = deNavMenuItem.query(By.css('div[id=logoutDropdownMenu]'));
expect(logoutDropdownMenu.nativeElement).toBeDefined(); expect(logoutDropdownMenu.nativeElement).toBeDefined();
@@ -223,8 +251,13 @@ describe('AuthNavMenuComponent', () => {
AuthNavMenuComponent AuthNavMenuComponent
], ],
providers: [ providers: [
{provide: HostWindowService, useValue: window}, { provide: HostWindowService, useValue: window },
{provide: AuthService, useValue: {setRedirectUrl: () => { /*empty*/ }}} {
provide: AuthService, useValue: {
setRedirectUrl: () => { /*empty*/
}
}
}
], ],
schemas: [ schemas: [
CUSTOM_ELEMENTS_SCHEMA CUSTOM_ELEMENTS_SCHEMA
@@ -234,6 +267,9 @@ describe('AuthNavMenuComponent', () => {
})); }));
beforeEach(() => {
init();
});
describe('when user is not authenticated', () => { describe('when user is not authenticated', () => {
beforeEach(inject([Store], (store: Store<AppState>) => { beforeEach(inject([Store], (store: Store<AppState>) => {
@@ -260,6 +296,11 @@ describe('AuthNavMenuComponent', () => {
deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector));
})); }));
afterEach(() => {
fixture.destroy();
component = null;
});
it('should render login link', () => { it('should render login link', () => {
const loginDropdownMenu = deNavMenuItem.query(By.css('a[id=loginLink]')); const loginDropdownMenu = deNavMenuItem.query(By.css('a[id=loginLink]'));
expect(loginDropdownMenu.nativeElement).toBeDefined(); expect(loginDropdownMenu.nativeElement).toBeDefined();
@@ -291,6 +332,11 @@ describe('AuthNavMenuComponent', () => {
deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector));
})); }));
afterEach(() => {
fixture.destroy();
component = null;
});
it('should render logout link', inject([Store], (store: Store<AppState>) => { it('should render logout link', inject([Store], (store: Store<AppState>) => {
const logoutDropdownMenu = deNavMenuItem.query(By.css('a[id=logoutLink]')); const logoutDropdownMenu = deNavMenuItem.query(By.css('a[id=logoutLink]'));
expect(logoutDropdownMenu.nativeElement).toBeDefined(); expect(logoutDropdownMenu.nativeElement).toBeDefined();

View File

@@ -60,15 +60,17 @@ export class AuthNavMenuComponent implements OnInit {
this.user = this.store.pipe(select(getAuthenticatedUser)); this.user = this.store.pipe(select(getAuthenticatedUser));
this.showAuth = this.store.select(routerStateSelector) this.showAuth = this.store.pipe(
.filter((router: RouterReducerState) => isNotUndefined(router) && isNotUndefined(router.state)) select(routerStateSelector),
.map((router: RouterReducerState) => { filter((router: RouterReducerState) => isNotUndefined(router) && isNotUndefined(router.state)),
map((router: RouterReducerState) => {
const url = router.state.url; const url = router.state.url;
const show = !router.state.url.startsWith(LOGIN_ROUTE) && !router.state.url.startsWith(LOGOUT_ROUTE); const show = !router.state.url.startsWith(LOGIN_ROUTE) && !router.state.url.startsWith(LOGOUT_ROUTE);
if (show) { if (show) {
this.authService.setRedirectUrl(url); this.authService.setRedirectUrl(url);
} }
return show; return show;
}); })
);
} }
} }

View File

@@ -3,7 +3,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Observable } from 'rxjs/Observable'; import { of as observableOf } from 'rxjs';
import { SharedModule } from '../shared.module'; import { SharedModule } from '../shared.module';
describe('BrowseByComponent', () => { describe('BrowseByComponent', () => {
@@ -30,7 +30,7 @@ describe('BrowseByComponent', () => {
}); });
it('should display results when objects is not empty', () => { it('should display results when objects is not empty', () => {
(comp as any).objects = Observable.of({ (comp as any).objects = observableOf({
payload: { payload: {
page: { page: {
length: 1 length: 1

View File

@@ -1,8 +1,8 @@
<div [class.form-group]="(type !== 6 && asBootstrapFormGroup) || getClass('element', 'container').includes('form-group')" <div [class.form-group]="(model.type !== 'GROUP' && asBootstrapFormGroup) || getClass('element', 'container').includes('form-group')"
[formGroup]="group" [formGroup]="group"
[ngClass]="[getClass('element', 'container'), getClass('grid', 'container')]"> [ngClass]="[getClass('element', 'container'), getClass('grid', 'container')]">
<label *ngIf="type !== 3 && model.label" <label *ngIf="model.type !== 'CHECKBOX' && model.label"
[for]="model.id" [for]="model.id"
[innerHTML]="(model.required && model.label) ? (model.label | translate) + ' *' : (model.label | translate)" [innerHTML]="(model.required && model.label) ? (model.label | translate) + ' *' : (model.label | translate)"
[ngClass]="[getClass('element', 'label'), getClass('grid', 'label')]"></label> [ngClass]="[getClass('element', 'label'), getClass('grid', 'label')]"></label>

View File

@@ -172,7 +172,6 @@ describe('DsDynamicFormControlComponent test suite', () => {
}); });
fixture.detectChanges(); fixture.detectChanges();
console.log(fixture.componentInstance.componentViewContainerRef);
testElement = debugElement.query(By.css(`input[id='${testModel.id}']`)); testElement = debugElement.query(By.css(`input[id='${testModel.id}']`));
})); }));

View File

@@ -20,7 +20,6 @@ export class DsDatePickerComponent extends DynamicFormControlComponent implement
@Input() bindId = true; @Input() bindId = true;
@Input() group: FormGroup; @Input() group: FormGroup;
@Input() model: DynamicDsDatePickerModel; @Input() model: DynamicDsDatePickerModel;
// @Input() showErrorMessages = false;
// @Input() // @Input()
// minDate; // minDate;
// @Input() // @Input()

View File

@@ -6,16 +6,16 @@ import {
import { DYNAMIC_FORM_CONTROL_TYPE_TAG } from './tag/dynamic-tag.model'; import { DYNAMIC_FORM_CONTROL_TYPE_TAG } from './tag/dynamic-tag.model';
export interface DynamicRowArrayModelConfig extends DynamicFormArrayModelConfig { export interface DynamicRowArrayModelConfig extends DynamicFormArrayModelConfig {
notRepeteable: boolean; notRepeatable: boolean;
} }
export class DynamicRowArrayModel extends DynamicFormArrayModel { export class DynamicRowArrayModel extends DynamicFormArrayModel {
@serializable() notRepeteable = false; @serializable() notRepeatable = false;
isRowArray = true; isRowArray = true;
constructor(config: DynamicRowArrayModelConfig, layout?: DynamicFormControlLayout) { constructor(config: DynamicRowArrayModelConfig, layout?: DynamicFormControlLayout) {
super(config, layout); super(config, layout);
this.notRepeteable = config.notRepeteable; this.notRepeatable = config.notRepeatable;
} }
} }

View File

@@ -4,7 +4,6 @@ import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { DsDynamicGroupComponent } from './dynamic-group.components'; import { DsDynamicGroupComponent } from './dynamic-group.components';
@@ -23,63 +22,69 @@ import { Chips } from '../../../../../chips/models/chips.model';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { DsDynamicInputModel } from '../ds-dynamic-input.model'; import { DsDynamicInputModel } from '../ds-dynamic-input.model';
import { createTestComponent } from '../../../../../testing/utils'; import { createTestComponent } from '../../../../../testing/utils';
import { getMockFormBuilderService } from '../../../../../mocks/mock-form-builder-service';
import { getMockFormService } from '../../../../../mocks/mock-form-service';
import { MockComponent } from 'ng-mocks';
import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dynamic-forms/core';
import { MockStore } from '../../../../../testing/mock-store';
import { Store } from '@ngrx/store';
import { AppState } from '../../../../../../app.reducer';
export const FORM_GROUP_TEST_MODEL_CONFIG = { export let FORM_GROUP_TEST_MODEL_CONFIG;
disabled: false,
errorMessages: {required: 'You must specify at least one author.'},
formConfiguration: [{
fields: [{
hints: 'Enter the name of the author.',
input: {type: 'onebox'},
label: 'Author',
languageCodes: [],
mandatory: 'true',
mandatoryMessage: 'Required field!',
repeatable: false,
selectableMetadata: [{
authority: 'RPAuthority',
closed: false,
metadata: 'dc.contributor.author'
}],
} as FormFieldModel]
} as FormRowModel, {
fields: [{
hints: 'Enter the affiliation of the author.',
input: {type: 'onebox'},
label: 'Affiliation',
languageCodes: [],
mandatory: 'false',
repeatable: false,
selectableMetadata: [{
authority: 'OUAuthority',
closed: false,
metadata: 'local.contributor.affiliation'
}]
} as FormFieldModel]
} as FormRowModel],
id: 'dc_contributor_author',
label: 'Authors',
mandatoryField: 'dc.contributor.author',
name: 'dc.contributor.author',
placeholder: 'Authors',
readOnly: false,
relationFields: ['local.contributor.affiliation'],
required: true,
scopeUUID: '43fe1f8c-09a6-4fcf-9c78-5d4fed8f2c8f',
submissionScope: undefined,
validators: {required: null}
} as DynamicGroupModelConfig;
export const FORM_GROUP_TEST_GROUP = new FormGroup({ export let FORM_GROUP_TEST_GROUP;
dc_contributor_author: new FormControl(),
});
describe('DsDynamicGroupComponent test suite', () => { let config;
const config = {
function init() {
FORM_GROUP_TEST_MODEL_CONFIG = {
disabled: false,
errorMessages: { required: 'You must specify at least one author.' },
formConfiguration: [{
fields: [{
hints: 'Enter the name of the author.',
input: { type: 'onebox' },
label: 'Author',
languageCodes: [],
mandatory: 'true',
mandatoryMessage: 'Required field!',
repeatable: false,
selectableMetadata: [{
authority: 'RPAuthority',
closed: false,
metadata: 'dc.contributor.author'
}],
} as FormFieldModel]
} as FormRowModel, {
fields: [{
hints: 'Enter the affiliation of the author.',
input: { type: 'onebox' },
label: 'Affiliation',
languageCodes: [],
mandatory: 'false',
repeatable: false,
selectableMetadata: [{
authority: 'OUAuthority',
closed: false,
metadata: 'local.contributor.affiliation'
}]
} as FormFieldModel]
} as FormRowModel],
id: 'dc_contributor_author',
label: 'Authors',
mandatoryField: 'dc.contributor.author',
name: 'dc.contributor.author',
placeholder: 'Authors',
readOnly: false,
relationFields: ['local.contributor.affiliation'],
required: true,
scopeUUID: '43fe1f8c-09a6-4fcf-9c78-5d4fed8f2c8f',
submissionScope: undefined,
validators: { required: null }
} as DynamicGroupModelConfig;
FORM_GROUP_TEST_GROUP = new FormGroup({
dc_contributor_author: new FormControl(),
});
config = {
form: { form: {
validatorMap: { validatorMap: {
required: 'required', required: 'required',
@@ -87,11 +92,15 @@ describe('DsDynamicGroupComponent test suite', () => {
} }
} }
} as any; } as any;
}
describe('DsDynamicGroupComponent test suite', () => {
let testComp: TestComponent; let testComp: TestComponent;
let groupComp: DsDynamicGroupComponent; let groupComp: DsDynamicGroupComponent;
let testFixture: ComponentFixture<TestComponent>; let testFixture: ComponentFixture<TestComponent>;
let groupFixture: ComponentFixture<DsDynamicGroupComponent>; let groupFixture: ComponentFixture<DsDynamicGroupComponent>;
// let modelValue: any; let modelValue: any;
let html; let html;
let control1: FormControl; let control1: FormControl;
let model1: DsDynamicInputModel; let model1: DsDynamicInputModel;
@@ -100,7 +109,9 @@ describe('DsDynamicGroupComponent test suite', () => {
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
init();
const store = new MockStore<AppState>(Object.create(null));
/* TODO make sure these files use mocks instead of real services/components https://github.com/DSpace/dspace-angular/issues/281 */
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
BrowserAnimationsModule, BrowserAnimationsModule,
@@ -110,18 +121,20 @@ describe('DsDynamicGroupComponent test suite', () => {
TranslateModule.forRoot() TranslateModule.forRoot()
], ],
declarations: [ declarations: [
MockComponent(FormComponent), FormComponent,
DsDynamicGroupComponent, DsDynamicGroupComponent,
TestComponent, TestComponent,
], // declare the test component ], // declare the test component
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DsDynamicGroupComponent, DsDynamicGroupComponent,
{provide: FormBuilderService, useValue: getMockFormBuilderService()}, DynamicFormValidationService,
{provide: FormService, useValue: getMockFormService()}, DynamicFormLayoutService,
{provide: GLOBAL_CONFIG, useValue: config}, FormBuilderService,
{provide: DynamicFormLayoutService, useValue: {}}, FormComponent,
{provide: DynamicFormValidationService, useValue: {}} FormService,
{ provide: GLOBAL_CONFIG, useValue: config },
{provide: Store, useValue: store},
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}); });
@@ -143,6 +156,11 @@ describe('DsDynamicGroupComponent test suite', () => {
testComp = testFixture.componentInstance; testComp = testFixture.componentInstance;
}); });
afterEach(() => {
testFixture.destroy();
testComp = null;
});
it('should create DsDynamicGroupComponent', inject([DsDynamicGroupComponent], (app: DsDynamicGroupComponent) => { it('should create DsDynamicGroupComponent', inject([DsDynamicGroupComponent], (app: DsDynamicGroupComponent) => {
expect(app).toBeDefined(); expect(app).toBeDefined();
@@ -158,7 +176,6 @@ describe('DsDynamicGroupComponent test suite', () => {
groupComp.group = FORM_GROUP_TEST_GROUP; groupComp.group = FORM_GROUP_TEST_GROUP;
groupComp.model = new DynamicGroupModel(FORM_GROUP_TEST_MODEL_CONFIG); groupComp.model = new DynamicGroupModel(FORM_GROUP_TEST_MODEL_CONFIG);
groupFixture.detectChanges(); groupFixture.detectChanges();
control1 = service.getFormControlById('dc_contributor_author', (groupComp as any).formRef.formGroup, groupComp.formModel) as FormControl; control1 = service.getFormControlById('dc_contributor_author', (groupComp as any).formRef.formGroup, groupComp.formModel) as FormControl;
model1 = service.findById('dc_contributor_author', groupComp.formModel) as DsDynamicInputModel; model1 = service.findById('dc_contributor_author', groupComp.formModel) as DsDynamicInputModel;
control2 = service.getFormControlById('local_contributor_affiliation', (groupComp as any).formRef.formGroup, groupComp.formModel) as FormControl; control2 = service.getFormControlById('local_contributor_affiliation', (groupComp as any).formRef.formGroup, groupComp.formModel) as FormControl;
@@ -172,123 +189,132 @@ describe('DsDynamicGroupComponent test suite', () => {
groupComp = null; groupComp = null;
}); });
// it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => { it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => {
// const formConfig = {rows: groupComp.model.formConfiguration} as SubmissionFormsModel; const formConfig = { rows: groupComp.model.formConfiguration } as SubmissionFormsModel;
// const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly);
// const chips = new Chips([], 'value', 'dc.contributor.author'); const chips = new Chips([], 'value', 'dc.contributor.author');
// groupComp.formCollapsed.subscribe((value) => {
// expect(groupComp.formCollapsed).toEqual(observableOf(false)); expect(value).toEqual(false);
// expect(groupComp.formModel.length).toEqual(formModel.length); });
// expect(groupComp.chips.getChipsItems()).toEqual(chips.getChipsItems()); expect(groupComp.formModel.length).toEqual(formModel.length);
// })); expect(groupComp.chips.getChipsItems()).toEqual(chips.getChipsItems());
// }));
// it('should save a new chips item', () => {
// control1.setValue('test author'); it('should save a new chips item', () => {
// (model1 as any).value = new FormFieldMetadataValueObject('test author'); control1.setValue('test author');
// control2.setValue('test affiliation'); (model1 as any).value = new FormFieldMetadataValueObject('test author');
// (model2 as any).value = new FormFieldMetadataValueObject('test affiliation'); control2.setValue('test affiliation');
// modelValue = [{ (model2 as any).value = new FormFieldMetadataValueObject('test affiliation');
// 'dc.contributor.author': new FormFieldMetadataValueObject('test author'), modelValue = [{
// 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation') 'dc.contributor.author': new FormFieldMetadataValueObject('test author'),
// }]; 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation')
// groupFixture.detectChanges(); }];
// groupFixture.detectChanges();
// const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button');
// const btnEl = buttons[0]; const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button');
// btnEl.click(); const btnEl = buttons[0];
// btnEl.click();
// expect(groupComp.chips.getChipsItems()).toEqual(modelValue);
// expect(groupComp.formCollapsed).toEqual(observableOf(true)); expect(groupComp.chips.getChipsItems()).toEqual(modelValue);
// }); groupComp.formCollapsed.subscribe((value) => {
// expect(value).toEqual(true);
// it('should clear form inputs', () => { })
// control1.setValue('test author'); });
// (model1 as any).value = new FormFieldMetadataValueObject('test author');
// control2.setValue('test affiliation'); it('should clear form inputs', () => {
// (model2 as any).value = new FormFieldMetadataValueObject('test affiliation'); control1.setValue('test author');
// (model1 as any).value = new FormFieldMetadataValueObject('test author');
// groupFixture.detectChanges(); control2.setValue('test affiliation');
// (model2 as any).value = new FormFieldMetadataValueObject('test affiliation');
// const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button');
// const btnEl = buttons[2]; groupFixture.detectChanges();
// btnEl.click();
// const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button');
// expect(control1.value).toBeNull(); const btnEl = buttons[2];
// expect(control2.value).toBeNull(); btnEl.click();
// expect(groupComp.formCollapsed).toEqual(observableOf(false));
// }); expect(control1.value).toBeNull();
// }); expect(control2.value).toBeNull();
// groupComp.formCollapsed.subscribe((value) => {
// describe('when init model value is not empty', () => { expect(value).toEqual(false);
// beforeEach(() => { });
// });
// groupFixture = TestBed.createComponent(DsDynamicGroupComponent); });
// groupComp = groupFixture.componentInstance; // FormComponent test instance
// groupComp.formId = 'testForm'; describe('when init model value is not empty', () => {
// groupComp.group = FORM_GROUP_TEST_GROUP; beforeEach(() => {
// groupComp.model = new DynamicGroupModel(FORM_GROUP_TEST_MODEL_CONFIG);
// modelValue = [{ groupFixture = TestBed.createComponent(DsDynamicGroupComponent);
// 'dc.contributor.author': new FormFieldMetadataValueObject('test author'), groupComp = groupFixture.componentInstance; // FormComponent test instance
// 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation') groupComp.formId = 'testForm';
// }]; groupComp.group = FORM_GROUP_TEST_GROUP;
// groupComp.model.value = modelValue; groupComp.model = new DynamicGroupModel(FORM_GROUP_TEST_MODEL_CONFIG);
// groupComp.showErrorMessages = false; modelValue = [{
// groupFixture.detectChanges(); 'dc.contributor.author': new FormFieldMetadataValueObject('test author'),
// 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation')
// }); }];
// groupComp.model.value = modelValue;
// afterEach(() => { groupFixture.detectChanges();
// groupFixture.destroy();
// groupComp = null; });
// });
// afterEach(() => {
// it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => { groupFixture.destroy();
// const formConfig = {rows: groupComp.model.formConfiguration} as SubmissionFormsModel; groupComp = null;
// const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); });
// const chips = new Chips(modelValue, 'value', 'dc.contributor.author');
// it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => {
// expect(groupComp.formCollapsed).toEqual(observableOf(true)); const formConfig = { rows: groupComp.model.formConfiguration } as SubmissionFormsModel;
// expect(groupComp.formModel.length).toEqual(formModel.length); const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly);
// expect(groupComp.chips.getChipsItems()).toEqual(chips.getChipsItems()); const chips = new Chips(modelValue, 'value', 'dc.contributor.author');
// })); groupComp.formCollapsed.subscribe((value) => {
// expect(value).toEqual(true);
// it('should modify existing chips item', inject([FormBuilderService], (service: FormBuilderService) => { })
// groupComp.onChipSelected(0); expect(groupComp.formModel.length).toEqual(formModel.length);
// groupFixture.detectChanges(); expect(groupComp.chips.getChipsItems()).toEqual(chips.getChipsItems());
// }));
// control1 = service.getFormControlById('dc_contributor_author', (groupComp as any).formRef.formGroup, groupComp.formModel) as FormControl;
// model1 = service.findById('dc_contributor_author', groupComp.formModel) as DsDynamicInputModel; it('should modify existing chips item', inject([FormBuilderService], (service: FormBuilderService) => {
// groupComp.onChipSelected(0);
// control1.setValue('test author modify'); groupFixture.detectChanges();
// (model1 as any).value = new FormFieldMetadataValueObject('test author modify');
// control1 = service.getFormControlById('dc_contributor_author', (groupComp as any).formRef.formGroup, groupComp.formModel) as FormControl;
// modelValue = [{ model1 = service.findById('dc_contributor_author', groupComp.formModel) as DsDynamicInputModel;
// 'dc.contributor.author': new FormFieldMetadataValueObject('test author modify'),
// 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation') control1.setValue('test author modify');
// }]; (model1 as any).value = new FormFieldMetadataValueObject('test author modify');
// groupFixture.detectChanges();
// modelValue = [{
// const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button'); 'dc.contributor.author': new FormFieldMetadataValueObject('test author modify'),
// const btnEl = buttons[0]; 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation')
// btnEl.click(); }];
// groupFixture.detectChanges();
// groupFixture.detectChanges();
// const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button');
// expect(groupComp.chips.getChipsItems()).toEqual(modelValue); const btnEl = buttons[0];
// expect(groupComp.formCollapsed).toEqual(observableOf(true)); btnEl.click();
// }));
// groupFixture.detectChanges();
// it('should delete existing chips item', () => {
// groupComp.onChipSelected(0); expect(groupComp.chips.getChipsItems()).toEqual(modelValue);
// groupFixture.detectChanges(); groupComp.formCollapsed.subscribe((value) => {
// expect(value).toEqual(true);
// const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button'); })
// const btnEl = buttons[1]; }));
// btnEl.click();
// it('should delete existing chips item', () => {
// expect(groupComp.chips.getChipsItems()).toEqual([]); groupComp.onChipSelected(0);
// expect(groupComp.formCollapsed).toEqual(observableOf(false)); groupFixture.detectChanges();
// });
const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button');
const btnEl = buttons[1];
btnEl.click();
expect(groupComp.chips.getChipsItems()).toEqual([]);
groupComp.formCollapsed.subscribe((value) => {
expect(value).toEqual(false);
})
});
}); });
}); });

View File

@@ -45,7 +45,6 @@ export class DsDynamicGroupComponent extends DynamicFormControlComponent impleme
@Input() formId: string; @Input() formId: string;
@Input() group: FormGroup; @Input() group: FormGroup;
@Input() model: DynamicGroupModel; @Input() model: DynamicGroupModel;
// @Input() showErrorMessages = false;
@Output() blur: EventEmitter<any> = new EventEmitter<any>(); @Output() blur: EventEmitter<any> = new EventEmitter<any>();
@Output() change: EventEmitter<any> = new EventEmitter<any>(); @Output() change: EventEmitter<any> = new EventEmitter<any>();

View File

@@ -33,7 +33,6 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen
@Input() bindId = true; @Input() bindId = true;
@Input() group: FormGroup; @Input() group: FormGroup;
@Input() model: DynamicListCheckboxGroupModel | DynamicListRadioGroupModel; @Input() model: DynamicListCheckboxGroupModel | DynamicListRadioGroupModel;
// @Input() showErrorMessages = false;
@Output() blur: EventEmitter<any> = new EventEmitter<any>(); @Output() blur: EventEmitter<any> = new EventEmitter<any>();
@Output() change: EventEmitter<any> = new EventEmitter<any>(); @Output() change: EventEmitter<any> = new EventEmitter<any>();

View File

@@ -18,16 +18,13 @@ import { DsDynamicLookupComponent } from './dynamic-lookup.component';
import { DynamicLookupModel } from './dynamic-lookup.model'; import { DynamicLookupModel } from './dynamic-lookup.model';
import { InfiniteScrollModule } from 'ngx-infinite-scroll'; import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { FormBuilderService } from '../../../form-builder.service';
import { FormService } from '../../../../form.service';
import { FormComponent } from '../../../../form.component';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { AuthorityValueModel } from '../../../../../../core/integration/models/authority-value.model'; import { AuthorityValueModel } from '../../../../../../core/integration/models/authority-value.model';
import { DynamicLookupNameModel } from './dynamic-lookup-name.model';
import { createTestComponent } from '../../../../../testing/utils'; import { createTestComponent } from '../../../../../testing/utils';
import { DynamicLookupNameModel } from './dynamic-lookup-name.model';
export const LOOKUP_TEST_MODEL_CONFIG = { let LOOKUP_TEST_MODEL_CONFIG = {
authorityOptions: { authorityOptions: {
closed: false, closed: false,
metadata: 'lookup', metadata: 'lookup',
@@ -35,7 +32,7 @@ export const LOOKUP_TEST_MODEL_CONFIG = {
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as AuthorityOptions,
disabled: false, disabled: false,
errorMessages: {required: 'Required field.'}, errorMessages: { required: 'Required field.' },
id: 'lookup', id: 'lookup',
label: 'Author', label: 'Author',
maxOptions: 10, maxOptions: 10,
@@ -45,11 +42,11 @@ export const LOOKUP_TEST_MODEL_CONFIG = {
required: true, required: true,
repeatable: true, repeatable: true,
separator: ',', separator: ',',
validators: {required: null}, validators: { required: null },
value: undefined value: undefined
}; };
export const LOOKUP_NAME_TEST_MODEL_CONFIG = { let LOOKUP_NAME_TEST_MODEL_CONFIG = {
authorityOptions: { authorityOptions: {
closed: false, closed: false,
metadata: 'lookup-name', metadata: 'lookup-name',
@@ -57,7 +54,7 @@ export const LOOKUP_NAME_TEST_MODEL_CONFIG = {
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions, } as AuthorityOptions,
disabled: false, disabled: false,
errorMessages: {required: 'Required field.'}, errorMessages: { required: 'Required field.' },
id: 'lookupName', id: 'lookupName',
label: 'Author', label: 'Author',
maxOptions: 10, maxOptions: 10,
@@ -67,16 +64,67 @@ export const LOOKUP_NAME_TEST_MODEL_CONFIG = {
required: true, required: true,
repeatable: true, repeatable: true,
separator: ',', separator: ',',
validators: {required: null}, validators: { required: null },
value: undefined value: undefined
}; };
export const LOOKUP_TEST_GROUP = new FormGroup({ let LOOKUP_TEST_GROUP = new FormGroup({
lookup: new FormControl(), lookup: new FormControl(),
lookupName: new FormControl() lookupName: new FormControl()
}); });
describe('Dynamic Lookup component', () => { describe('Dynamic Lookup component', () => {
function init() {
LOOKUP_TEST_MODEL_CONFIG = {
authorityOptions: {
closed: false,
metadata: 'lookup',
name: 'RPAuthority',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions,
disabled: false,
errorMessages: { required: 'Required field.' },
id: 'lookup',
label: 'Author',
maxOptions: 10,
name: 'lookup',
placeholder: 'Author',
readOnly: false,
required: true,
repeatable: true,
separator: ',',
validators: { required: null },
value: undefined
};
LOOKUP_NAME_TEST_MODEL_CONFIG = {
authorityOptions: {
closed: false,
metadata: 'lookup-name',
name: 'RPAuthority',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions,
disabled: false,
errorMessages: { required: 'Required field.' },
id: 'lookupName',
label: 'Author',
maxOptions: 10,
name: 'lookupName',
placeholder: 'Author',
readOnly: false,
required: true,
repeatable: true,
separator: ',',
validators: { required: null },
value: undefined
};
LOOKUP_TEST_GROUP = new FormGroup({
lookup: new FormControl(),
lookupName: new FormControl()
});
}
let testComp: TestComponent; let testComp: TestComponent;
let lookupComp: DsDynamicLookupComponent; let lookupComp: DsDynamicLookupComponent;
@@ -84,11 +132,11 @@ describe('Dynamic Lookup component', () => {
let lookupFixture: ComponentFixture<DsDynamicLookupComponent>; let lookupFixture: ComponentFixture<DsDynamicLookupComponent>;
let html; let html;
const authorityServiceStub = new AuthorityServiceStub(); let authorityServiceStub;
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
const authorityService = new AuthorityServiceStub();
authorityServiceStub = authorityService;
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
DynamicFormsCoreModule, DynamicFormsCoreModule,
@@ -106,16 +154,19 @@ describe('Dynamic Lookup component', () => {
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DsDynamicLookupComponent, DsDynamicLookupComponent,
{provide: AuthorityService, useValue: authorityServiceStub}, { provide: AuthorityService, useValue: authorityService },
{provide: DynamicFormLayoutService, useValue: {}}, { provide: DynamicFormLayoutService, useValue: {} },
{provide: DynamicFormValidationService, useValue: {}} { provide: DynamicFormValidationService, useValue: {} }
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}); });
})); }));
describe('', () => { beforeEach(() => {
init();
});
describe('DynamicLookUpComponent', () => {
// synchronous beforeEach // synchronous beforeEach
beforeEach(() => { beforeEach(() => {
html = ` html = `
@@ -130,200 +181,236 @@ describe('Dynamic Lookup component', () => {
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>; testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
testComp = testFixture.componentInstance; testComp = testFixture.componentInstance;
}); });
afterEach(() => {
testFixture.destroy();
testComp = null;
});
it('should create DsDynamicLookupComponent', inject([DsDynamicLookupComponent], (app: DsDynamicLookupComponent) => { it('should create DsDynamicLookupComponent', inject([DsDynamicLookupComponent], (app: DsDynamicLookupComponent) => {
expect(app).toBeDefined(); expect(app).toBeDefined();
})); }));
});
describe('when model is DynamicLookupModel', () => { describe('when model is DynamicLookupModel', () => {
describe('', () => { describe('', () => {
beforeEach(() => { beforeEach(() => {
lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupModel(LOOKUP_TEST_MODEL_CONFIG);
lookupFixture.detectChanges();
});
afterEach(() => {
lookupFixture.destroy();
lookupComp = null;
});
it('should render only an input element', () => {
const de = lookupFixture.debugElement.queryAll(By.css('input.form-control'));
expect(de.length).toBe(1);
});
lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupModel(LOOKUP_TEST_MODEL_CONFIG);
lookupFixture.detectChanges();
}); });
it('should render only an input element', () => { describe('and init model value is empty', () => {
const de = lookupFixture.debugElement.queryAll(By.css('input.form-control')); beforeEach(() => {
expect(de.length).toBe(1); lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupModel(LOOKUP_TEST_MODEL_CONFIG);
lookupFixture.detectChanges();
});
afterEach(() => {
lookupFixture.destroy();
lookupComp = null;
});
it('should init component properly', () => {
expect(lookupComp.firstInputValue).toBe('');
});
it('should return search results', fakeAsync(() => {
const de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement;
const results$ = authorityServiceStub.getEntriesByName({} as any);
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
btnEl.click();
tick();
lookupFixture.detectChanges();
results$.subscribe((results) => {
expect(lookupComp.optionsList).toEqual(results.payload);
});
}));
it('should select a results entry properly', fakeAsync(() => {
let de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement;
const selectedValue = Object.assign(new AuthorityValueModel(), {
id: 1,
display: 'one',
value: 1
});
spyOn(lookupComp.change, 'emit');
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
btnEl.click();
tick();
lookupFixture.detectChanges();
de = lookupFixture.debugElement.queryAll(By.css('button.dropdown-item'));
const entryEl = de[0].nativeElement;
entryEl.click();
lookupFixture.detectChanges();
expect(lookupComp.firstInputValue).toEqual('one');
expect(lookupComp.model.value).toEqual(selectedValue);
expect(lookupComp.change.emit).toHaveBeenCalled();
}));
it('should set model.value on input type when AuthorityOptions.closed is false', fakeAsync(() => {
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
lookupComp.onInput(new Event('input'));
expect(lookupComp.model.value).toEqual(new FormFieldMetadataValueObject('test'))
}));
it('should not set model.value on input type when AuthorityOptions.closed is true', () => {
lookupComp.model.authorityOptions.closed = true;
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
lookupComp.onInput(new Event('input'));
expect(lookupComp.model.value).not.toBeDefined();
});
}); });
}); describe('and init model value is not empty', () => {
beforeEach(() => {
describe('and init model value is empty', () => { lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
beforeEach(() => { lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupComp.group = LOOKUP_TEST_GROUP;
lookupFixture = TestBed.createComponent(DsDynamicLookupComponent); lookupComp.model = new DynamicLookupModel(LOOKUP_TEST_MODEL_CONFIG);
lookupComp = lookupFixture.componentInstance; // FormComponent test instance lookupComp.model.value = new FormFieldMetadataValueObject('test', null, 'test001');
lookupComp.group = LOOKUP_TEST_GROUP; lookupFixture.detectChanges();
lookupComp.model = new DynamicLookupModel(LOOKUP_TEST_MODEL_CONFIG);
lookupFixture.detectChanges();
});
it('should init component properly', () => {
expect(lookupComp.firstInputValue).toBe('');
});
it('should return search results', fakeAsync(() => {
const de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement;
const results$ = authorityServiceStub.getEntriesByName({} as any);
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
btnEl.click();
tick();
lookupFixture.detectChanges();
results$.subscribe((results) => {
expect(lookupComp.optionsList).toEqual(results.payload);
})
}));
it('should select a results entry properly', fakeAsync(() => {
let de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement;
const selectedValue = Object.assign(new AuthorityValueModel(), {id: 1, display: 'one', value: 1});
spyOn(lookupComp.change, 'emit');
console.log("debugger");
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
btnEl.click();
tick();
lookupFixture.detectChanges();
de = lookupFixture.debugElement.queryAll(By.css('button.dropdown-item'));
const entryEl = de[0].nativeElement;
entryEl.click();
expect(lookupComp.firstInputValue).toEqual('one');
expect(lookupComp.model.value).toEqual(selectedValue);
expect(lookupComp.change.emit).toHaveBeenCalled();
}));
it('should set model.value on input type when AuthorityOptions.closed is false', fakeAsync(() => {
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
lookupComp.onInput(new Event('input'));
expect(lookupComp.model.value).toEqual(new FormFieldMetadataValueObject('test'))
}));
it('should not set model.value on input type when AuthorityOptions.closed is true', () => {
lookupComp.model.authorityOptions.closed = true;
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
lookupComp.onInput(new Event('input'));
expect(lookupComp.model.value).not.toBeDefined();
// spyOn(store, 'dispatch');
});
afterEach(() => {
lookupFixture.destroy();
lookupComp = null;
});
it('should init component properly', () => {
expect(lookupComp.firstInputValue).toBe('test');
});
}); });
}); });
describe('and init model value is not empty', () => { describe('when model is DynamicLookupNameModel', () => {
beforeEach(() => {
lookupFixture = TestBed.createComponent(DsDynamicLookupComponent); describe('', () => {
lookupComp = lookupFixture.componentInstance; // FormComponent test instance beforeEach(() => {
lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupModel(LOOKUP_TEST_MODEL_CONFIG); lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
lookupComp.model.value = new FormFieldMetadataValueObject('test', null, 'test001'); lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupFixture.detectChanges(); lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupNameModel(LOOKUP_NAME_TEST_MODEL_CONFIG);
lookupFixture.detectChanges();
// spyOn(store, 'dispatch');
});
afterEach(() => {
lookupFixture.destroy();
lookupComp = null;
});
it('should render two input element', () => {
const de = lookupFixture.debugElement.queryAll(By.css('input.form-control'));
expect(de.length).toBe(2);
});
// spyOn(store, 'dispatch');
}); });
it('should init component properly', () => { describe('and init model value is empty', () => {
expect(lookupComp.firstInputValue).toBe('test')
beforeEach(() => {
lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupNameModel(LOOKUP_NAME_TEST_MODEL_CONFIG);
lookupFixture.detectChanges();
});
afterEach(() => {
lookupFixture.destroy();
lookupComp = null;
});
it('should select a results entry properly', fakeAsync(() => {
const payload = [
Object.assign(new AuthorityValueModel(), {
id: 1,
display: 'Name, Lastname',
value: 1
}),
Object.assign(new AuthorityValueModel(), {
id: 2,
display: 'NameTwo, LastnameTwo',
value: 2
}),
];
let de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement;
const selectedValue = Object.assign(new AuthorityValueModel(), {
id: 1,
display: 'Name, Lastname',
value: 1
});
spyOn(lookupComp.change, 'emit');
authorityServiceStub.setNewPayload(payload);
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
btnEl.click();
tick();
lookupFixture.detectChanges();
de = lookupFixture.debugElement.queryAll(By.css('button.dropdown-item'));
const entryEl = de[0].nativeElement;
entryEl.click();
expect(lookupComp.firstInputValue).toEqual('Name');
expect(lookupComp.secondInputValue).toEqual('Lastname');
expect(lookupComp.model.value).toEqual(selectedValue);
expect(lookupComp.change.emit).toHaveBeenCalled();
}));
});
describe('and init model value is not empty', () => {
beforeEach(() => {
lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupNameModel(LOOKUP_NAME_TEST_MODEL_CONFIG);
lookupComp.model.value = new FormFieldMetadataValueObject('Name, Lastname', null, 'test001');
lookupFixture.detectChanges();
});
afterEach(() => {
lookupFixture.destroy();
lookupComp = null;
});
it('should init component properly', () => {
expect(lookupComp.firstInputValue).toBe('Name');
expect(lookupComp.secondInputValue).toBe('Lastname');
});
}); });
}); });
}); });
describe('when model is DynamicLookupNameModel', () => {
describe('', () => {
beforeEach(() => {
lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupNameModel(LOOKUP_NAME_TEST_MODEL_CONFIG);
lookupFixture.detectChanges();
// spyOn(store, 'dispatch');
});
it('should render two input element', () => {
const de = lookupFixture.debugElement.queryAll(By.css('input.form-control'));
expect(de.length).toBe(2);
});
});
describe('and init model value is empty', () => {
beforeEach(() => {
lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupNameModel(LOOKUP_NAME_TEST_MODEL_CONFIG);
lookupFixture.detectChanges();
});
it('should select a results entry properly', fakeAsync(() => {
const payload = [
Object.assign(new AuthorityValueModel(), {id: 1, display: 'Name, Lastname', value: 1}),
Object.assign(new AuthorityValueModel(), {id: 2, display: 'NameTwo, LastnameTwo', value: 2}),
];
let de = lookupFixture.debugElement.queryAll(By.css('button'));
const btnEl = de[0].nativeElement;
const selectedValue = Object.assign(new AuthorityValueModel(), {id: 1, display: 'Name, Lastname', value: 1});
spyOn(lookupComp.change, 'emit');
authorityServiceStub.setNewPayload(payload);
lookupComp.firstInputValue = 'test';
lookupFixture.detectChanges();
btnEl.click();
tick();
lookupFixture.detectChanges();
de = lookupFixture.debugElement.queryAll(By.css('button.dropdown-item'));
const entryEl = de[0].nativeElement;
entryEl.click();
expect(lookupComp.firstInputValue).toEqual('Name');
expect(lookupComp.secondInputValue).toEqual('Lastname');
expect(lookupComp.model.value).toEqual(selectedValue);
expect(lookupComp.change.emit).toHaveBeenCalled();
}));
});
describe('and init model value is not empty', () => {
beforeEach(() => {
lookupFixture = TestBed.createComponent(DsDynamicLookupComponent);
lookupComp = lookupFixture.componentInstance; // FormComponent test instance
lookupComp.group = LOOKUP_TEST_GROUP;
lookupComp.model = new DynamicLookupNameModel(LOOKUP_NAME_TEST_MODEL_CONFIG);
lookupComp.model.value = new FormFieldMetadataValueObject('Name, Lastname', null, 'test001');
lookupFixture.detectChanges();
});
it('should init component properly', () => {
expect(lookupComp.firstInputValue).toBe('Name');
expect(lookupComp.secondInputValue).toBe('Lastname');
});
});
});
}); });
// declare a test component // declare a test component
@@ -338,7 +425,4 @@ class TestComponent {
inputLookupModelConfig = LOOKUP_TEST_MODEL_CONFIG; inputLookupModelConfig = LOOKUP_TEST_MODEL_CONFIG;
model = new DynamicLookupModel(this.inputLookupModelConfig); model = new DynamicLookupModel(this.inputLookupModelConfig);
showErrorMessages = false;
} }

View File

@@ -28,7 +28,6 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem
@Input() bindId = true; @Input() bindId = true;
@Input() group: FormGroup; @Input() group: FormGroup;
@Input() model: DynamicLookupModel | DynamicLookupNameModel; @Input() model: DynamicLookupModel | DynamicLookupNameModel;
// @Input() showErrorMessages = false;
@Output() blur: EventEmitter<any> = new EventEmitter<any>(); @Output() blur: EventEmitter<any> = new EventEmitter<any>();
@Output() change: EventEmitter<any> = new EventEmitter<any>(); @Output() change: EventEmitter<any> = new EventEmitter<any>();

View File

@@ -26,7 +26,6 @@ export class DsDynamicScrollableDropdownComponent extends DynamicFormControlComp
@Input() bindId = true; @Input() bindId = true;
@Input() group: FormGroup; @Input() group: FormGroup;
@Input() model: DynamicScrollableDropdownModel; @Input() model: DynamicScrollableDropdownModel;
// @Input() showErrorMessages = false;
@Output() blur: EventEmitter<any> = new EventEmitter<any>(); @Output() blur: EventEmitter<any> = new EventEmitter<any>();
@Output() change: EventEmitter<any> = new EventEmitter<any>(); @Output() change: EventEmitter<any> = new EventEmitter<any>();

View File

@@ -37,27 +37,32 @@ function createKeyUpEvent(key: number) {
return event; return event;
} }
export const TAG_TEST_GROUP = new FormGroup({ let TAG_TEST_GROUP;
tag: new FormControl(), let TAG_TEST_MODEL_CONFIG;
});
export const TAG_TEST_MODEL_CONFIG = { function init() {
authorityOptions: { TAG_TEST_GROUP = new FormGroup({
closed: false, tag: new FormControl(),
metadata: 'tag', });
name: 'common_iso_languages',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' TAG_TEST_MODEL_CONFIG = {
} as AuthorityOptions, authorityOptions: {
disabled: false, closed: false,
id: 'tag', metadata: 'tag',
label: 'Keywords', name: 'common_iso_languages',
minChars: 3, scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
name: 'tag', } as AuthorityOptions,
placeholder: 'Keywords', disabled: false,
readOnly: false, id: 'tag',
required: false, label: 'Keywords',
repeatable: false minChars: 3,
}; name: 'tag',
placeholder: 'Keywords',
readOnly: false,
required: false,
repeatable: false
};
}
describe('DsDynamicTagComponent test suite', () => { describe('DsDynamicTagComponent test suite', () => {
@@ -72,7 +77,7 @@ describe('DsDynamicTagComponent test suite', () => {
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
const authorityServiceStub = new AuthorityServiceStub(); const authorityServiceStub = new AuthorityServiceStub();
init();
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
DynamicFormsCoreModule, DynamicFormsCoreModule,
@@ -88,10 +93,10 @@ describe('DsDynamicTagComponent test suite', () => {
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DsDynamicTagComponent, DsDynamicTagComponent,
{provide: AuthorityService, useValue: authorityServiceStub}, { provide: AuthorityService, useValue: authorityServiceStub },
{provide: GLOBAL_CONFIG, useValue: {} as GlobalConfig}, { provide: GLOBAL_CONFIG, useValue: {} as GlobalConfig },
{provide: DynamicFormLayoutService, useValue: {}}, { provide: DynamicFormLayoutService, useValue: {} },
{provide: DynamicFormValidationService, useValue: {}} { provide: DynamicFormValidationService, useValue: {} }
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}); });
@@ -112,7 +117,9 @@ describe('DsDynamicTagComponent test suite', () => {
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>; testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
testComp = testFixture.componentInstance; testComp = testFixture.componentInstance;
}); });
afterEach(() => {
testFixture.destroy();
});
it('should create DsDynamicTagComponent', inject([DsDynamicTagComponent], (app: DsDynamicTagComponent) => { it('should create DsDynamicTagComponent', inject([DsDynamicTagComponent], (app: DsDynamicTagComponent) => {
expect(app).toBeDefined(); expect(app).toBeDefined();
@@ -138,6 +145,7 @@ describe('DsDynamicTagComponent test suite', () => {
it('should init component properly', () => { it('should init component properly', () => {
chips = new Chips([], 'display'); chips = new Chips([], 'display');
expect(tagComp.chips.getChipsItems()).toEqual(chips.getChipsItems()); expect(tagComp.chips.getChipsItems()).toEqual(chips.getChipsItems());
expect(tagComp.searchOptions).toBeDefined(); expect(tagComp.searchOptions).toBeDefined();
}); });
@@ -151,10 +159,14 @@ describe('DsDynamicTagComponent test suite', () => {
it('should select a results entry properly', fakeAsync(() => { it('should select a results entry properly', fakeAsync(() => {
modelValue = [ modelValue = [
Object.assign(new AuthorityValueModel(), {id: 1, display: 'Name, Lastname', value: 1}) Object.assign(new AuthorityValueModel(), { id: 1, display: 'Name, Lastname', value: 1 })
]; ];
const event: NgbTypeaheadSelectItemEvent = { const event: NgbTypeaheadSelectItemEvent = {
item: Object.assign(new AuthorityValueModel(), {id: 1, display: 'Name, Lastname', value: 1}), item: Object.assign(new AuthorityValueModel(), {
id: 1,
display: 'Name, Lastname',
value: 1
}),
preventDefault: () => { preventDefault: () => {
return; return;
} }

View File

@@ -1,4 +1,3 @@
import {of as observableOf, Observable } from 'rxjs'; import {of as observableOf, Observable } from 'rxjs';
import {catchError, debounceTime, distinctUntilChanged, tap, switchMap, map, merge} from 'rxjs/operators'; import {catchError, debounceTime, distinctUntilChanged, tap, switchMap, map, merge} from 'rxjs/operators';
@@ -29,7 +28,6 @@ export class DsDynamicTagComponent extends DynamicFormControlComponent implement
@Input() bindId = true; @Input() bindId = true;
@Input() group: FormGroup; @Input() group: FormGroup;
@Input() model: DynamicTagModel; @Input() model: DynamicTagModel;
// @Input() showErrorMessages = false;
@Output() blur: EventEmitter<any> = new EventEmitter<any>(); @Output() blur: EventEmitter<any> = new EventEmitter<any>();
@Output() change: EventEmitter<any> = new EventEmitter<any>(); @Output() change: EventEmitter<any> = new EventEmitter<any>();
@@ -80,12 +78,13 @@ export class DsDynamicTagComponent extends DynamicFormControlComponent implement
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
protected layoutService: DynamicFormLayoutService, protected layoutService: DynamicFormLayoutService,
protected validationService: DynamicFormValidationService protected validationService: DynamicFormValidationService
) { ) {
super(layoutService, validationService); super(layoutService, validationService);
} }
ngOnInit() { ngOnInit() {
this.hasAuthority = this.model.authorityOptions && hasValue(this.model.authorityOptions.name); this.hasAuthority = this.model.authorityOptions && hasValue(this.model.authorityOptions.name);
if (this.hasAuthority) { if (this.hasAuthority) {
this.searchOptions = new IntegrationSearchOptions( this.searchOptions = new IntegrationSearchOptions(
this.model.authorityOptions.scope, this.model.authorityOptions.scope,

View File

@@ -22,29 +22,34 @@ import { DynamicTypeaheadModel } from './dynamic-typeahead.model';
import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model';
import { createTestComponent } from '../../../../../testing/utils'; import { createTestComponent } from '../../../../../testing/utils';
export const TYPEAHEAD_TEST_GROUP = new FormGroup({ export let TYPEAHEAD_TEST_GROUP;
typeahead: new FormControl(),
});
export const TYPEAHEAD_TEST_MODEL_CONFIG = { export let TYPEAHEAD_TEST_MODEL_CONFIG;
authorityOptions: {
closed: false,
metadata: 'typeahead',
name: 'EVENTAuthority',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions,
disabled: false,
id: 'typeahead',
label: 'Conference',
minChars: 3,
name: 'typeahead',
placeholder: 'Conference',
readOnly: false,
required: false,
repeatable: false,
value: undefined
};
function init() {
TYPEAHEAD_TEST_GROUP = new FormGroup({
typeahead: new FormControl(),
});
TYPEAHEAD_TEST_MODEL_CONFIG = {
authorityOptions: {
closed: false,
metadata: 'typeahead',
name: 'EVENTAuthority',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
} as AuthorityOptions,
disabled: false,
id: 'typeahead',
label: 'Conference',
minChars: 3,
name: 'typeahead',
placeholder: 'Conference',
readOnly: false,
required: false,
repeatable: false,
value: undefined
};
}
describe('DsDynamicTypeaheadComponent test suite', () => { describe('DsDynamicTypeaheadComponent test suite', () => {
let testComp: TestComponent; let testComp: TestComponent;
@@ -56,7 +61,7 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
const authorityServiceStub = new AuthorityServiceStub(); const authorityServiceStub = new AuthorityServiceStub();
init()
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
DynamicFormsCoreModule, DynamicFormsCoreModule,
@@ -72,9 +77,9 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DsDynamicTypeaheadComponent, DsDynamicTypeaheadComponent,
{provide: AuthorityService, useValue: authorityServiceStub}, { provide: AuthorityService, useValue: authorityServiceStub },
{provide: DynamicFormLayoutService, useValue: {}}, { provide: DynamicFormLayoutService, useValue: {} },
{provide: DynamicFormValidationService, useValue: {}} { provide: DynamicFormValidationService, useValue: {} }
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}); });
@@ -96,6 +101,9 @@ describe('DsDynamicTypeaheadComponent test suite', () => {
testComp = testFixture.componentInstance; testComp = testFixture.componentInstance;
}); });
afterEach(() => {
testFixture.destroy();
});
it('should create DsDynamicTypeaheadComponent', inject([DsDynamicTypeaheadComponent], (app: DsDynamicTypeaheadComponent) => { it('should create DsDynamicTypeaheadComponent', inject([DsDynamicTypeaheadComponent], (app: DsDynamicTypeaheadComponent) => {
expect(app).toBeDefined(); expect(app).toBeDefined();
@@ -221,6 +229,4 @@ class TestComponent {
model = new DynamicTypeaheadModel(TYPEAHEAD_TEST_MODEL_CONFIG); model = new DynamicTypeaheadModel(TYPEAHEAD_TEST_MODEL_CONFIG);
showErrorMessages = false;
} }

View File

@@ -26,7 +26,6 @@ export class DsDynamicTypeaheadComponent extends DynamicFormControlComponent imp
@Input() bindId = true; @Input() bindId = true;
@Input() group: FormGroup; @Input() group: FormGroup;
@Input() model: DynamicTypeaheadModel; @Input() model: DynamicTypeaheadModel;
@Input() showErrorMessages = false;
@Output() blur: EventEmitter<any> = new EventEmitter<any>(); @Output() blur: EventEmitter<any> = new EventEmitter<any>();
@Output() change: EventEmitter<any> = new EventEmitter<any>(); @Output() change: EventEmitter<any> = new EventEmitter<any>();

View File

@@ -254,7 +254,7 @@ describe('FormBuilderService test suite', () => {
{ {
id: 'testFormRowArray', id: 'testFormRowArray',
initialCount: 5, initialCount: 5,
notRepeteable: false, notRepeatable: false,
groupFactory: () => { groupFactory: () => {
return [ return [
new DynamicInputModel({id: 'testFormRowArrayGroupInput'}) new DynamicInputModel({id: 'testFormRowArrayGroupInput'})

View File

@@ -35,7 +35,7 @@ export abstract class FieldParser {
id: uniqueId() + '_array', id: uniqueId() + '_array',
label: this.configData.label, label: this.configData.label,
initialCount: this.getInitArrayIndex(), initialCount: this.getInitArrayIndex(),
notRepeteable: !this.configData.repeatable, notRepeatable: !this.configData.repeatable,
groupFactory: () => { groupFactory: () => {
let model; let model;
if ((arrayCounter === 0)) { if ((arrayCounter === 0)) {

View File

@@ -14,7 +14,7 @@
<ng-template modelType="ARRAY" let-group let-index="index" let-context="context"> <ng-template modelType="ARRAY" let-group let-index="index" let-context="context">
<!--Array with repeteable items--> <!--Array with repeteable items-->
<div *ngIf="!context.notRepeteable" <div *ngIf="!context.notRepeatable"
class="col-xs-2 d-flex flex-column justify-content-sm-start align-items-end"> class="col-xs-2 d-flex flex-column justify-content-sm-start align-items-end">
<div class="btn-group" role="group" aria-label="Basic example"> <div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn btn-secondary" <button type="button" class="btn btn-secondary"
@@ -31,7 +31,7 @@
</div> </div>
<!--Array with non repeteable items - Only delete button--> <!--Array with non repeteable items - Only delete button-->
<div *ngIf="context.notRepeteable && group.context.groups.length > 1" <div *ngIf="context.notRepeatable && group.context.groups.length > 1"
class="col-xs-2 d-flex flex-column justify-content-sm-start align-items-end"> class="col-xs-2 d-flex flex-column justify-content-sm-start align-items-end">
<div class="btn-group" role="group" aria-label="Basic example"> <div class="btn-group" role="group" aria-label="Basic example">
<button type="button" class="btn btn-secondary" <button type="button" class="btn btn-secondary"

View File

@@ -1,102 +1,107 @@
import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing'; import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { BrowserModule, By } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { import {
DynamicFormArrayModel, DynamicFormArrayModel,
DynamicFormControlEvent, DynamicFormControlEvent,
DynamicFormControlModel, DynamicFormControlModel,
DynamicFormValidationService,
DynamicInputModel DynamicInputModel
} from '@ng-dynamic-forms/core'; } from '@ng-dynamic-forms/core';
import { Store } from '@ngrx/store';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { FormComponent } from './form.component'; import { FormComponent } from './form.component';
import { FormService } from './form.service'; import { FormService } from './form.service';
import { FormBuilderService } from './builder/form-builder.service'; import { FormBuilderService } from './builder/form-builder.service';
import { FormAddError, FormChangeAction } from './form.actions'; import { FormState } from './form.reducer';
import { FormChangeAction, FormStatusChangeAction } from './form.actions';
import { MockStore } from '../testing/mock-store';
import { FormFieldMetadataValueObject } from './builder/models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from './builder/models/form-field-metadata-value.model';
import { GLOBAL_CONFIG } from '../../../config'; import { GLOBAL_CONFIG } from '../../../config';
import { createTestComponent } from '../testing/utils'; import { createTestComponent } from '../testing/utils';
import { getMockFormService } from '../mocks/mock-form-service'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { getMockFormBuilderService } from '../mocks/mock-form-builder-service';
export const TEST_FORM_MODEL = [ let TEST_FORM_MODEL;
new DynamicInputModel(
{ let TEST_FORM_MODEL_WITH_ARRAY;
id: 'dc_title',
label: 'Title', let config;
placeholder: 'Title', let formState: FormState;
validators: { let html;
required: null let store: MockStore<FormState>;
},
errorMessages: { function init() {
required: 'You must enter a main title for this item.' TEST_FORM_MODEL = [
new DynamicInputModel(
{
id: 'dc_title',
label: 'Title',
placeholder: 'Title',
validators: {
required: null
},
errorMessages: {
required: 'You must enter a main title for this item.'
}
} }
} ),
),
new DynamicInputModel( new DynamicInputModel(
{ {
id: 'dc_title_alternative', id: 'dc_title_alternative',
label: 'Other Titles', label: 'Other Titles',
placeholder: 'Other Titles', placeholder: 'Other Titles',
} }
), ),
new DynamicInputModel( new DynamicInputModel(
{ {
id: 'dc_publisher', id: 'dc_publisher',
label: 'Publisher', label: 'Publisher',
placeholder: 'Publisher', placeholder: 'Publisher',
} }
), ),
new DynamicInputModel( new DynamicInputModel(
{ {
id: 'dc_identifier_citation', id: 'dc_identifier_citation',
label: 'Citation', label: 'Citation',
placeholder: 'Citation', placeholder: 'Citation',
} }
), ),
new DynamicInputModel( new DynamicInputModel(
{ {
id: 'dc_identifier_issn', id: 'dc_identifier_issn',
label: 'Identifiers', label: 'Identifiers',
placeholder: 'Identifiers', placeholder: 'Identifiers',
} }
), ),
]; ];
export const TEST_FORM_MODEL_WITH_ARRAY = [ TEST_FORM_MODEL_WITH_ARRAY = [
new DynamicFormArrayModel({ new DynamicFormArrayModel({
id: 'bootstrapFormArray', id: 'bootstrapFormArray',
initialCount: 1, initialCount: 1,
label: 'Form Array', label: 'Form Array',
groupFactory: () => { groupFactory: () => {
return [ return [
new DynamicInputModel({ new DynamicInputModel({
id: 'bootstrapArrayGroupInput', id: 'bootstrapArrayGroupInput',
placeholder: 'example array group input', placeholder: 'example array group input',
readOnly: false readOnly: false
}) })
]; ];
} }
}) })
]; ];
config = {
describe('FormComponent test suite', () => {
let testComp: TestComponent;
let formComp: FormComponent;
let testFixture: ComponentFixture<TestComponent>;
let formFixture: ComponentFixture<FormComponent>;
let dynamicForm;
const config = {
form: { form: {
validatorMap: { validatorMap: {
required: 'required', required: 'required',
@@ -105,12 +110,33 @@ describe('FormComponent test suite', () => {
} }
} as any; } as any;
let html; formState = {
let formService; testForm: {
let formBuilderService; data: {
dc_title: null,
dc_title_alternative: null,
dc_publisher: null,
dc_identifier_citation: null,
dc_identifier_issn: null
},
valid: false,
errors: []
}
};
store = new MockStore<FormState>(formState);
}
describe('FormComponent test suite', () => {
let testComp: TestComponent;
let formComp: FormComponent;
let testFixture: ComponentFixture<TestComponent>;
let formFixture: ComponentFixture<FormComponent>;
// async beforeEach // async beforeEach
beforeEach(async(() => { beforeEach(async(() => {
init();
/* TODO make sure these files use mocks instead of real services/components https://github.com/DSpace/dspace-angular/issues/281 */
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
BrowserModule, BrowserModule,
@@ -126,19 +152,22 @@ describe('FormComponent test suite', () => {
], // declare the test component ], // declare the test component
providers: [ providers: [
ChangeDetectorRef, ChangeDetectorRef,
DynamicFormValidationService,
FormBuilderService,
FormComponent, FormComponent,
{ provide: FormBuilderService, useValue: getMockFormBuilderService() }, FormService,
{ provide: FormService, useValue: getMockFormService() }, { provide: GLOBAL_CONFIG, useValue: config },
{ provide: GLOBAL_CONFIG, useValue: config } {
provide: Store, useValue: store
}
], ],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]
}); });
formService = TestBed.get(FormService);
formBuilderService = TestBed.get(FormBuilderService);
})); }));
describe('', () => { describe('', () => {
// // synchronous beforeEach // synchronous beforeEach
beforeEach(() => { beforeEach(() => {
html = ` html = `
<ds-form *ngIf="formModel" #formRef="formComponent" <ds-form *ngIf="formModel" #formRef="formComponent"
@@ -149,13 +178,19 @@ describe('FormComponent test suite', () => {
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>; testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
testComp = testFixture.componentInstance; testComp = testFixture.componentInstance;
}); });
afterEach(() => {
testFixture.destroy();
testComp = null;
html = undefined;
});
it('should create FormComponent', inject([FormComponent], (app: FormComponent) => { it('should create FormComponent', inject([FormComponent], (app: FormComponent) => {
expect(app).toBeDefined(); expect(app).toBeDefined();
})); }));
}); });
describe('', () => { describe('', () => {
let form;
let valid;
beforeEach(() => { beforeEach(() => {
formFixture = TestBed.createComponent(FormComponent); formFixture = TestBed.createComponent(FormComponent);
@@ -163,247 +198,238 @@ describe('FormComponent test suite', () => {
formComp.formId = 'testForm'; formComp.formId = 'testForm';
formComp.formModel = TEST_FORM_MODEL; formComp.formModel = TEST_FORM_MODEL;
formComp.displaySubmit = false; formComp.displaySubmit = false;
form = new BehaviorSubject(formState);
valid = new BehaviorSubject(false);
spyOn((formComp as any).formService, 'getForm').and.returnValue(form);
spyOn((formComp as any).formService, 'isValid').and.returnValue(valid);
formFixture.detectChanges(); formFixture.detectChanges();
dynamicForm = formFixture.debugElement.query(By.css('ds-dynamic-form')); spyOn(store, 'dispatch');
formBuilderService.findById.and.returnValue(TEST_FORM_MODEL);
}); });
afterEach(() => { afterEach(() => {
formFixture.destroy(); formFixture.destroy();
formComp = null; formComp = null;
}); });
//
// it('should dispatch a FormStatusChangeAction when Form group status changes', () => { it('should dispatch a FormStatusChangeAction when Form group status changes', () => {
// // spyOn(formComp, 'onChange'); const control = formComp.formGroup.get(['dc_title']);
// const control = new FormControl('', Validators.required); control.setValue('Test Title');
// const event = { expect(store.dispatch).toHaveBeenCalledWith(new FormStatusChangeAction('testForm', formComp.formGroup.valid));
// $event: new FormFieldMetadataValueObject('Test Title'), });
// context: null,
// control: control, it('should display form errors when errors are added to the state', () => {
// group: formComp.formGroup, const errors = [{
// model: formComp.formModel[0], fieldId: 'dc_title',
// type: 'change' fieldIndex: 0,
// } as DynamicFormControlEvent; message: 'error.validation.required'
// dynamicForm.componentInstance.change.emit(event); }];
// formState.testForm.errors = errors;
// // expect(formComp.onChange).toHaveBeenCalledWith('testForm', formComp.formGroup.valid); form.next(formState.testForm);
// formComp.onChange(event); formFixture.detectChanges();
// // const control = new FormControl('', Validators.required);
// formComp.formGroup.addControl('dc_title', control); expect((formComp as any).formErrors).toEqual(errors);
// control.setValue('Test Title');
// });
// expect(formService.changeForm).toHaveBeenCalledWith('testForm', formComp.formGroup.valid);
// }); it('should remove form errors when errors are empty in the state', () => {
// (formComp as any).formErrors = [{
// it('should display form errors when errors are added to the state', () => { fieldId: 'dc_title',
// message: 'error.validation.required'
// const error = {formComp.formId, 'dc_title', 0, 'error.validation.required'; }];
// formService.getFormErrors().next([error]); const errors = [];
// formFixture.detectChanges();
// formState.testForm.errors = errors;
// expect((formComp as any).formErrors).toEqual([error]); form.next(formState.testForm);
// formFixture.detectChanges();
// });
// expect((formComp as any).formErrors).toEqual(errors);
// fit('should remove form errors when errors are empty in the state', () => {
// (formComp as any).formErrors = [{ });
// fieldId: 'dc_title',
// message: 'error.validation.required' it('should dispatch FormChangeAction on form change', inject([FormBuilderService], (service: FormBuilderService) => {
// }]; const event = {
// const errors = []; $event: new FormFieldMetadataValueObject('Test Title'),
// context: null,
// formService.getFormErrors().next([]); control: formComp.formGroup.get('dc_title'),
// formFixture.detectChanges(); group: formComp.formGroup,
// model: formComp.formModel[0],
// expect((formComp as any).formErrors).toEqual(errors); type: 'change'
// } as DynamicFormControlEvent;
// });
// spyOn(formComp.change, 'emit');
// it('should dispatch FormChangeAction on form change', inject([FormBuilderService], (service: FormBuilderService) => {
// const event = { formComp.onChange(event);
// $event: new FormFieldMetadataValueObject('Test Title'),
// context: null, expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testForm', service.getValueFromModel(formComp.formModel)));
// control: formComp.formGroup.get('dc_title'), expect(formComp.change.emit).toHaveBeenCalled();
// group: formComp.formGroup, }));
// model: formComp.formModel[0],
// type: 'change' it('should emit change on form change', inject([FormBuilderService], (service: FormBuilderService) => {
// } as DynamicFormControlEvent; const event = {
// $event: new FormFieldMetadataValueObject('Test Title'),
// spyOn(formComp.change, 'emit'); context: null,
// control: formComp.formGroup.get('dc_title'),
// formComp.onChange(event); group: formComp.formGroup,
// model: formComp.formModel[0],
// expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testForm', service.getValueFromModel(formComp.formModel))); type: 'change'
// expect(formComp.change.emit).toHaveBeenCalled(); } as DynamicFormControlEvent;
// }));
// spyOn(formComp.change, 'emit');
// it('should emit change on form change', inject([FormBuilderService], (service: FormBuilderService) => {
// const event = { formComp.onChange(event);
// $event: new FormFieldMetadataValueObject('Test Title'),
// context: null, expect(formComp.change.emit).toHaveBeenCalled();
// control: formComp.formGroup.get('dc_title'), }));
// group: formComp.formGroup,
// model: formComp.formModel[0], it('should not emit change Event on form change when emitChange is false', inject([FormBuilderService], (service: FormBuilderService) => {
// type: 'change' const event = {
// } as DynamicFormControlEvent; $event: new FormFieldMetadataValueObject('Test Title'),
// context: null,
// spyOn(formComp.change, 'emit'); control: formComp.formGroup.get('dc_title'),
// group: formComp.formGroup,
// formComp.onChange(event); model: formComp.formModel[0],
// type: 'change'
// expect(formComp.change.emit).toHaveBeenCalled(); } as DynamicFormControlEvent;
// }));
// formComp.emitChange = false;
// it('should not emit change Event on form change when emitChange is false', inject([FormBuilderService], (service: FormBuilderService) => { spyOn(formComp.change, 'emit');
// const event = {
// $event: new FormFieldMetadataValueObject('Test Title'), formComp.onChange(event);
// context: null,
// control: formComp.formGroup.get('dc_title'), expect(formComp.change.emit).not.toHaveBeenCalled();
// group: formComp.formGroup, }));
// model: formComp.formModel[0],
// type: 'change' it('should emit blur Event on blur', () => {
// } as DynamicFormControlEvent; const event = {
// $event: new FocusEvent('blur'),
// formComp.emitChange = false; context: null,
// spyOn(formComp.change, 'emit'); control: formComp.formGroup.get('dc_title'),
// group: formComp.formGroup,
// formComp.onChange(event); model: formComp.formModel[0],
// type: 'blur'
// expect(formComp.change.emit).not.toHaveBeenCalled(); } as DynamicFormControlEvent;
// }));
// spyOn(formComp.blur, 'emit');
// it('should emit blur Event on blur', () => {
// const event = { formComp.onBlur(event);
// $event: new FocusEvent('blur'),
// context: null, expect(formComp.blur.emit).toHaveBeenCalled();
// control: formComp.formGroup.get('dc_title'), });
// group: formComp.formGroup,
// model: formComp.formModel[0], it('should emit focus Event on focus', () => {
// type: 'blur' const event = {
// } as DynamicFormControlEvent; $event: new FocusEvent('focus'),
// context: null,
// spyOn(formComp.blur, 'emit'); control: formComp.formGroup.get('dc_title'),
// group: formComp.formGroup,
// formComp.onBlur(event); model: formComp.formModel[0],
// type: 'focus'
// expect(formComp.blur.emit).toHaveBeenCalled(); } as DynamicFormControlEvent;
// });
// spyOn(formComp.focus, 'emit');
// it('should emit focus Event on focus', () => {
// const event = { formComp.onFocus(event);
// $event: new FocusEvent('focus'),
// context: null, expect(formComp.focus.emit).toHaveBeenCalled();
// control: formComp.formGroup.get('dc_title'), });
// group: formComp.formGroup,
// model: formComp.formModel[0], it('should return Observable of form status', () => {
// type: 'focus'
// } as DynamicFormControlEvent; const control = formComp.formGroup.get(['dc_title']);
// control.setValue('Test Title');
// spyOn(formComp.focus, 'emit'); valid.next(true);
// formFixture.detectChanges();
// formComp.onFocus(event);
// formComp.isValid().subscribe((v) => {
// expect(formComp.focus.emit).toHaveBeenCalled(); expect(v).toBe(true);
// }); });
// });
// it('should return Observable of form status', () => {
// it('should emit submit Event on form submit whether the form is valid', () => {
// const control = formComp.formGroup.get(['dc_title']);
// control.setValue('Test Title'); const control = formComp.formGroup.get(['dc_title']);
// formState.testForm.valid = true; control.setValue('Test Title');
// store.nextState(formState); formState.testForm.valid = true;
// formFixture.detectChanges(); spyOn(formComp.submit, 'emit');
//
// formComp.isValid().subscribe((valid) => { form.next(formState.testForm);
// expect(valid).toBe(true); formFixture.detectChanges();
// });
// }); formComp.onSubmit();
// expect(formComp.submit.emit).toHaveBeenCalled();
// it('should emit submit Event on form submit whether the form is valid', () => { });
//
// const control = formComp.formGroup.get(['dc_title']); it('should not emit submit Event on form submit whether the form is not valid', () => {
// control.setValue('Test Title');
// formState.testForm.valid = true; spyOn((formComp as any).formService, 'validateAllFormFields');
// spyOn(formComp.submit, 'emit');
// form.next(formState.testForm)
// store.nextState(formState); formFixture.detectChanges();
// formFixture.detectChanges();
// formComp.onSubmit();
// formComp.onSubmit(); expect((formComp as any).formService.validateAllFormFields).toHaveBeenCalled();
// expect(formComp.submit.emit).toHaveBeenCalled(); });
// });
// it('should reset form group', () => {
// it('should not emit submit Event on form submit whether the form is not valid', () => {
// spyOn(formComp.formGroup, 'reset');
// spyOn((formComp as any).formService, 'validateAllFormFields');
// formComp.reset();
// store.nextState(formState);
// formFixture.detectChanges(); expect(formComp.formGroup.reset).toHaveBeenCalled();
// });
// formComp.onSubmit(); });
// expect((formComp as any).formService.validateAllFormFields).toHaveBeenCalled();
// }); describe('', () => {
// beforeEach(() => {
// it('should reset form group', () => {
// formFixture = TestBed.createComponent(FormComponent);
// spyOn(formComp.formGroup, 'reset'); formComp = formFixture.componentInstance; // FormComponent test instance
// formComp.formId = 'testFormArray';
// formComp.reset(); formComp.formModel = TEST_FORM_MODEL_WITH_ARRAY;
// formComp.displaySubmit = false;
// expect(formComp.formGroup.reset).toHaveBeenCalled(); formFixture.detectChanges();
// }); spyOn(store, 'dispatch');
// }); });
//
// describe('', () => { afterEach(() => {
// beforeEach(() => { formFixture.destroy();
// formComp = null;
// formFixture = TestBed.createComponent(FormComponent); });
// formComp = formFixture.componentInstance; // FormComponent test instance
// formComp.formId = 'testFormArray'; it('should return ReadOnly property from array item', inject([FormBuilderService], (service: FormBuilderService) => {
// formComp.formModel = TEST_FORM_MODEL_WITH_ARRAY; const readOnly = formComp.isItemReadOnly(formComp.formModel[0] as DynamicFormArrayModel, 0);
// formComp.displaySubmit = false;
// formFixture.detectChanges(); expect(readOnly).toBe(false);
// spyOn(store, 'dispatch'); }));
// });
// it('should dispatch FormChangeAction when an item has been added to an array', inject([FormBuilderService], (service: FormBuilderService) => {
// afterEach(() => { formComp.insertItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 0);
// formFixture.destroy();
// formComp = null; expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testFormArray', service.getValueFromModel(formComp.formModel)));
// }); }));
//
// it('should return ReadOnly property from array item', inject([FormBuilderService], (service: FormBuilderService) => { it('should emit addArrayItem Event when an item has been added to an array', inject([FormBuilderService], (service: FormBuilderService) => {
// const readOnly = formComp.isItemReadOnly(formComp.formModel[0] as DynamicFormArrayModel, 0); spyOn(formComp.addArrayItem, 'emit');
//
// expect(readOnly).toBe(false); formComp.insertItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 0);
// }));
// expect(formComp.addArrayItem.emit).toHaveBeenCalled();
// it('should dispatch FormChangeAction when an item has been added to an array', inject([FormBuilderService], (service: FormBuilderService) => { }));
// formComp.insertItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
// it('should dispatch FormChangeAction when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => {
// expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testFormArray', service.getValueFromModel(formComp.formModel))); formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 0);
// }));
// expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testFormArray', service.getValueFromModel(formComp.formModel)));
// it('should emit addArrayItem Event when an item has been added to an array', inject([FormBuilderService], (service: FormBuilderService) => { }));
// spyOn(formComp.addArrayItem, 'emit');
// it('should emit removeArrayItem Event when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => {
// formComp.insertItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1); spyOn(formComp.removeArrayItem, 'emit');
//
// expect(formComp.addArrayItem.emit).toHaveBeenCalled(); formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 0);
// }));
// expect(formComp.removeArrayItem.emit).toHaveBeenCalled();
// it('should dispatch FormChangeAction when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => { }));
// formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
//
// expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testFormArray', service.getValueFromModel(formComp.formModel)));
// }));
//
// it('should emit removeArrayItem Event when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => {
// spyOn(formComp.removeArrayItem, 'emit');
//
// formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
//
// expect(formComp.removeArrayItem.emit).toHaveBeenCalled();
// }));
}) })
}); });

View File

@@ -156,7 +156,6 @@ export class FormComponent implements OnDestroy, OnInit {
// .delay(100) // this terrible delay is here to prevent the detection change error // .delay(100) // this terrible delay is here to prevent the detection change error
.subscribe((errors: FormError[]) => { .subscribe((errors: FormError[]) => {
const { formGroup, formModel } = this; const { formGroup, formModel } = this;
errors errors
.filter((error: FormError) => findIndex(this.formErrors, { .filter((error: FormError) => findIndex(this.formErrors, {
fieldId: error.fieldId, fieldId: error.fieldId,
@@ -171,25 +170,15 @@ export class FormComponent implements OnDestroy, OnInit {
} else { } else {
field = this.formBuilderService.getFormControlById(fieldId, formGroup, formModel, fieldIndex); field = this.formBuilderService.getFormControlById(fieldId, formGroup, formModel, fieldIndex);
} }
console.log('1', error);
if (field) { if (field) {
console.log('2',error);
const model: DynamicFormControlModel = this.formBuilderService.findById(fieldId, formModel); const model: DynamicFormControlModel = this.formBuilderService.findById(fieldId, formModel);
console.log('4',error);
this.formService.addErrorToField(field, model, error.message); this.formService.addErrorToField(field, model, error.message);
// this.formService.validateAllFormFields(formGroup); // this.formService.validateAllFormFields(formGroup);
console.log('5',error);
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
} }
console.log('4',error);
}); });
console.log(errors);
this.formErrors this.formErrors
.filter((error: FormError) => findIndex(errors, { .filter((error: FormError) => findIndex(errors, {
@@ -211,7 +200,6 @@ export class FormComponent implements OnDestroy, OnInit {
this.formService.removeErrorFromField(field, model, error.message); this.formService.removeErrorFromField(field, model, error.message);
} }
}); });
console.log(this.formErrors);
this.formErrors = errors; this.formErrors = errors;
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
}) })
@@ -256,7 +244,6 @@ export class FormComponent implements OnDestroy, OnInit {
} }
onChange(event: DynamicFormControlEvent): void { onChange(event: DynamicFormControlEvent): void {
this.formService.changeForm(this.formId, this.formModel); this.formService.changeForm(this.formId, this.formModel);
this.formGroup.markAsPristine(); this.formGroup.markAsPristine();

View File

@@ -30,7 +30,6 @@ export interface FormState {
const initialState: FormState = Object.create(null); const initialState: FormState = Object.create(null);
export function formReducer(state = initialState, action: FormAction): FormState { export function formReducer(state = initialState, action: FormAction): FormState {
console.log('TEST');
switch (action.type) { switch (action.type) {
case FormActionTypes.FORM_INIT: { case FormActionTypes.FORM_INIT: {
@@ -68,7 +67,6 @@ export function formReducer(state = initialState, action: FormAction): FormState
} }
function addFormErrors(state: FormState, action: FormAddError) { function addFormErrors(state: FormState, action: FormAddError) {
console.log(state);
const formId = action.payload.formId; const formId = action.payload.formId;
if (hasValue(state[formId])) { if (hasValue(state[formId])) {
const error: FormError = { const error: FormError = {

View File

@@ -1,14 +1,8 @@
import { Store, StoreModule } from '@ngrx/store'; import { Store, StoreModule } from '@ngrx/store';
import { async, inject, TestBed } from '@angular/core/testing'; import { async, inject, TestBed } from '@angular/core/testing';
import { FormGroup } from '@angular/forms'; import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';
import { import { DynamicFormControlModel, DynamicInputModel } from '@ng-dynamic-forms/core';
DynamicFormControlModel,
DynamicFormGroupModel,
DynamicFormService,
DynamicFormValidationService,
DynamicInputModel
} from '@ng-dynamic-forms/core';
import { FormService } from './form.service'; import { FormService } from './form.service';
import { FormBuilderService } from './builder/form-builder.service'; import { FormBuilderService } from './builder/form-builder.service';
@@ -21,7 +15,7 @@ describe('FormService test suite', () => {
form: { form: {
validatorMap: { validatorMap: {
required: 'required', required: 'required',
regex: 'pattern' regex: 'pattern'
} }
} }
} as any; } as any;
@@ -31,7 +25,7 @@ describe('FormService test suite', () => {
let formGroup: FormGroup; let formGroup: FormGroup;
const formModel: DynamicFormControlModel[] = [ const formModel: DynamicFormControlModel[] = [
new DynamicInputModel({id: 'author', value: 'test'}), new DynamicInputModel({ id: 'author', value: 'test' }),
new DynamicInputModel({ new DynamicInputModel({
id: 'title', id: 'title',
validators: { validators: {
@@ -41,34 +35,36 @@ describe('FormService test suite', () => {
required: 'Title is required' required: 'Title is required'
} }
}), }),
new DynamicInputModel({id: 'date'}), new DynamicInputModel({ id: 'date' }),
new DynamicInputModel({id: 'description'}), new DynamicInputModel({ id: 'description' }),
new DynamicFormGroupModel({ // new DynamicFormGroupModel({
//
id: 'addressLocation', // id: 'addressLocation',
group: [ // group: [
new DynamicInputModel({ // new DynamicInputModel({
//
id: 'zipCode', // id: 'zipCode',
label: 'Zip Code', // label: 'Zip Code',
placeholder: 'ZIP' // placeholder: 'ZIP'
}), // }),
new DynamicInputModel({ // new DynamicInputModel({
//
id: 'state', // id: 'state',
label: 'State', // label: 'State',
placeholder: 'State' // placeholder: 'State'
}), // }),
new DynamicInputModel({ // new DynamicInputModel({
//
id: 'city', // id: 'city',
label: 'City', // label: 'City',
placeholder: 'City' // placeholder: 'City'
}) // })
] // ]
}), // }),
]; ];
let controls;
const formData = { const formData = {
author: ['test'], author: ['test'],
title: null, title: null,
@@ -91,23 +87,27 @@ describe('FormService test suite', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
StoreModule.forRoot({formReducer}) StoreModule.forRoot({ formReducer })
],
providers: [
{provide: FormBuilderService, useValue: getMockFormBuilderService()},
] ]
}).compileComponents(); }).compileComponents();
})); }));
beforeEach(inject([Store, FormBuilderService], (store: Store<AppState>, formBuilderService: FormBuilderService) => { beforeEach(inject([Store], (store: Store<AppState>) => {
store builderService = getMockFormBuilderService();
.subscribe((state) => { store
state.forms = formState; .subscribe((state) => {
}); state.forms = formState;
builderService = formBuilderService; });
formGroup = builderService.createFormGroup(formModel); const author: AbstractControl = new FormControl('test');
service = new FormService(config, formBuilderService, store); const title: AbstractControl = new FormControl(undefined, Validators.required);
})); const date: AbstractControl = new FormControl(undefined);
const description: AbstractControl = new FormControl(undefined);
formGroup = new FormGroup({ author, title, date, description });
controls = { author, title, date, description };
service = new FormService(config, builderService, store);
})
)
;
it('should check whether form state is init', () => { it('should check whether form state is init', () => {
service.isFormInitialized(formId).subscribe((init) => { service.isFormInitialized(formId).subscribe((init) => {
@@ -136,7 +136,6 @@ describe('FormService test suite', () => {
it('should validate all form fields', () => { it('should validate all form fields', () => {
service.validateAllFormFields(formGroup); service.validateAllFormFields(formGroup);
expect(formGroup.controls.author.touched).toBe(true); expect(formGroup.controls.author.touched).toBe(true);
expect(formGroup.controls.author.status).toBe('VALID'); expect(formGroup.controls.author.status).toBe('VALID');
@@ -149,8 +148,8 @@ describe('FormService test suite', () => {
}); });
it('should add error to field', () => { it('should add error to field', () => {
let control = builderService.getFormControlById('description', formGroup, formModel); let control = controls.description;
let model = builderService.findById('description', formModel); let model = formModel.find((mdl: DynamicFormControlModel) => mdl.id === 'description');
let errorKeys: string[]; let errorKeys: string[];
service.addErrorToField(control, model, 'Test error message'); service.addErrorToField(control, model, 'Test error message');
@@ -162,8 +161,8 @@ describe('FormService test suite', () => {
expect(formGroup.controls.description.touched).toBe(true); expect(formGroup.controls.description.touched).toBe(true);
control = builderService.getFormControlById('title', formGroup, formModel); control = controls.title;
model = builderService.findById('title', formModel); model = formModel.find((mdl: DynamicFormControlModel) => mdl.id === 'title');
service.addErrorToField(control, model, 'error.required'); service.addErrorToField(control, model, 'error.required');
errorKeys = Object.keys(control.errors); errorKeys = Object.keys(control.errors);
@@ -175,8 +174,8 @@ describe('FormService test suite', () => {
}); });
it('should remove error from field', () => { it('should remove error from field', () => {
let control = builderService.getFormControlById('description', formGroup, formModel); let control = controls.description;
let model = builderService.findById('description', formModel); let model = formModel.find((mdl: DynamicFormControlModel) => mdl.id === 'description');
let errorKeys: string[]; let errorKeys: string[];
service.addErrorToField(control, model, 'Test error message'); service.addErrorToField(control, model, 'Test error message');
@@ -190,8 +189,8 @@ describe('FormService test suite', () => {
expect(formGroup.controls.description.touched).toBe(false); expect(formGroup.controls.description.touched).toBe(false);
control = builderService.getFormControlById('title', formGroup, formModel); control = controls.title;
model = builderService.findById('title', formModel); model = formModel.find((mdl: DynamicFormControlModel) => mdl.id === 'title');
service.addErrorToField(control, model, 'error.required'); service.addErrorToField(control, model, 'error.required');
@@ -205,10 +204,11 @@ describe('FormService test suite', () => {
}); });
it('should reset form group', () => { it('should reset form group', () => {
const control = builderService.getFormControlById('author', formGroup, formModel); const control = controls.author;
service.resetForm(formGroup, formModel, formId); service.resetForm(formGroup, formModel, formId);
expect(control.value).toBeNull(); expect(control.value).toBeNull();
}); });
}); })
;

View File

@@ -1,11 +1,9 @@
import { filter, takeWhile, map } from 'rxjs/operators'; import { filter, map, takeWhile } from 'rxjs/operators';
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { select, Store } from '@ngrx/store'; import { select, Store } from '@ngrx/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { import {
AuthenticateAction, AuthenticateAction,
ResetAuthenticationMessagesAction ResetAuthenticationMessagesAction
@@ -135,7 +133,7 @@ export class LogInComponent implements OnDestroy, OnInit {
this.store.pipe( this.store.pipe(
select(isAuthenticated), select(isAuthenticated),
takeWhile(() => this.alive), takeWhile(() => this.alive),
filter((authenticated) => authenticated),) filter((authenticated) => authenticated))
.subscribe(() => { .subscribe(() => {
this.authService.redirectToPreviousUrl(); this.authService.redirectToPreviousUrl();
} }

View File

@@ -2,7 +2,7 @@ import { FormBuilderService } from '../form/builder/form-builder.service';
import { FormControl, FormGroup } from '@angular/forms'; import { FormControl, FormGroup } from '@angular/forms';
export function getMockFormBuilderService(): FormBuilderService { export function getMockFormBuilderService(): FormBuilderService {
return jasmine.createSpyObj('FormService', { return jasmine.createSpyObj('FormBuilderService', {
modelFromConfiguration: [], modelFromConfiguration: [],
createFormGroup: new FormGroup({}), createFormGroup: new FormGroup({}),
getValueFromModel: {}, getValueFromModel: {},

View File

@@ -1,23 +1,12 @@
import { FormService } from '../form/form.service'; import { FormService } from '../form/form.service';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { map } from 'rxjs/operators';
export function getMockFormService( export function getMockFormService(
id$: string = 'random_id', id$: string = 'random_id'
errors = new BehaviorSubject([])
): FormService { ): FormService {
return jasmine.createSpyObj('FormService', { return jasmine.createSpyObj('FormService', {
getUniqueId: id$, getUniqueId: id$,
resetForm: {}, resetForm: {},
validateAllFormFields: {}, validateAllFormFields: {}
getForm: errors.pipe(map((err) => { return {data: {}, valid: true, errors: err} })),
removeForm: undefined,
removeError: undefined,
changeForm: undefined,
setStatusChanged: undefined,
initForm: undefined,
getFormErrors: errors,
addErrorToField: undefined
}); });
} }

View File

@@ -1,4 +1,5 @@
import { Observable } from 'rxjs';
import {of as observableOf, Observable } from 'rxjs';
import { map, take } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service';
import { ResponseCacheEntry } from '../../core/cache/response-cache.reducer'; import { ResponseCacheEntry } from '../../core/cache/response-cache.reducer';
@@ -19,7 +20,7 @@ export function getMockRemoteDataBuildService(toRemoteDataObservable$?: Observab
} as RemoteData<any>))) } as RemoteData<any>)))
} }
}, },
buildSingle: (href$: string | Observable<string>) => Observable.of(new RemoteData(false, false, true, undefined, {})) buildSingle: (href$: string | Observable<string>) => observableOf(new RemoteData(false, false, true, undefined, {}))
} as RemoteDataBuildService; } as RemoteDataBuildService;
} }

View File

@@ -1,4 +0,0 @@
import { Store } from '@ngrx/store';
import { of as observableOf } from 'rxjs';

View File

@@ -99,7 +99,7 @@ export class NumberPickerComponent implements OnInit, ControlValueAccessor {
update(event) { update(event) {
try { try {
const i = Number.parseInt(event.target.value); const i = Number.parseInt(event.target.value, 10);
if (i >= this.min && i <= this.max) { if (i >= this.min && i <= this.max) {
this.value = i; this.value = i;

View File

@@ -1,4 +1,4 @@
import {of as observableOf, Observable } from 'rxjs'; import { Observable, of as observableOf } from 'rxjs';
import { HttpOptions } from '../../core/dspace-rest-v2/dspace-rest-v2.service'; import { HttpOptions } from '../../core/dspace-rest-v2/dspace-rest-v2.service';
import { AuthStatus } from '../../core/auth/models/auth-status.model'; import { AuthStatus } from '../../core/auth/models/auth-status.model';
import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model'; import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model';
@@ -27,7 +27,7 @@ export class AuthRequestServiceStub {
if (this.validateToken(token)) { if (this.validateToken(token)) {
authStatusStub.authenticated = true; authStatusStub.authenticated = true;
authStatusStub.token = this.mockTokenInfo; authStatusStub.token = this.mockTokenInfo;
authStatusStub.eperson = Observable.of(new RemoteData<EPerson>(false, false, true, undefined, this.mockUser)); authStatusStub.eperson = observableOf(new RemoteData<EPerson>(false, false, true, undefined, this.mockUser));
} else { } else {
authStatusStub.authenticated = false; authStatusStub.authenticated = false;
} }
@@ -46,7 +46,7 @@ export class AuthRequestServiceStub {
if (this.validateToken(token)) { if (this.validateToken(token)) {
authStatusStub.authenticated = true; authStatusStub.authenticated = true;
authStatusStub.token = this.mockTokenInfo; authStatusStub.token = this.mockTokenInfo;
authStatusStub.eperson = Observable.of(new RemoteData<EPerson>(false, false, true, undefined, this.mockUser)); authStatusStub.eperson = observableOf(new RemoteData<EPerson>(false, false, true, undefined, this.mockUser));
} else { } else {
authStatusStub.authenticated = false; authStatusStub.authenticated = false;
} }

View File

@@ -1,5 +1,4 @@
import { Observable, of as observableOf } from 'rxjs';
import {of as observableOf, Observable } from 'rxjs';
import { AuthStatus } from '../../core/auth/models/auth-status.model'; import { AuthStatus } from '../../core/auth/models/auth-status.model';
import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model'; import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model';
import { EPersonMock } from './eperson-mock'; import { EPersonMock } from './eperson-mock';
@@ -21,7 +20,7 @@ export class AuthServiceStub {
authStatus.okay = true; authStatus.okay = true;
authStatus.authenticated = true; authStatus.authenticated = true;
authStatus.token = this.token; authStatus.token = this.token;
authStatus.eperson = Observable.of(new RemoteData<EPerson>(false, false, true, undefined, EPersonMock)); authStatus.eperson = observableOf(new RemoteData<EPerson>(false, false, true, undefined, EPersonMock));
return observableOf(authStatus); return observableOf(authStatus);
} else { } else {
console.log('error'); console.log('error');
@@ -31,7 +30,7 @@ export class AuthServiceStub {
public authenticatedUser(token: AuthTokenInfo): Observable<EPerson> { public authenticatedUser(token: AuthTokenInfo): Observable<EPerson> {
if (token.accessToken === 'token_test') { if (token.accessToken === 'token_test') {
return Observable.of(EPersonMock); return observableOf(EPersonMock);
} else { } else {
throw(new Error('Message Error test')); throw(new Error('Message Error test'));
} }

View File

@@ -1,10 +1,7 @@
import {distinctUntilChanged, debounceTime, takeUntil} from 'rxjs/operators'; import {distinctUntilChanged, debounceTime, takeUntil} from 'rxjs/operators';
import { Directive, Input, Output, EventEmitter, OnDestroy, OnInit } from '@angular/core'; import { Directive, Input, Output, EventEmitter, OnDestroy, OnInit } from '@angular/core';
import { NgControl } from '@angular/forms'; import { NgControl } from '@angular/forms';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
@Directive({ @Directive({

View File

@@ -1,8 +1,5 @@
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Action, Store } from '@ngrx/store'; import { Action, Store } from '@ngrx/store';
import { Actions, Effect, ofType } from '@ngrx/effects'; import { Actions, Effect, ofType } from '@ngrx/effects';

View File

@@ -6,8 +6,6 @@ import { RouterModule } from '@angular/router';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { AppComponent } from '../../app/app.component'; import { AppComponent } from '../../app/app.component';
import { AppModule } from '../../app/app.module'; import { AppModule } from '../../app/app.module';

View File

@@ -151,10 +151,10 @@
"use-input-property-decorator": true, "use-input-property-decorator": true,
"use-life-cycle-interface": false, "use-life-cycle-interface": false,
"use-output-property-decorator": true, "use-output-property-decorator": true,
"use-pipe-transform-interface": true, "use-pipe-transform-interface": true
"rxjs-collapse-imports": true, // "rxjs-collapse-imports": true,
"rxjs-pipeable-operators-only": true, // "rxjs-pipeable-operators-only": true,
"rxjs-no-static-observable-methods": true, // "rxjs-no-static-observable-methods": true,
"rxjs-proper-imports": true // "rxjs-proper-imports": true
} }
} }