diff --git a/package.json b/package.json index cc4de4de64..f4ab6e2ff4 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,8 @@ "server:watch": "nodemon dist/server.js", "server:watch:debug": "nodemon --debug dist/server.js", "webpack:watch": "webpack -w --mode development", - "watch": "yarn run build && npm-run-all -p webpack:watch server:watch --mode development", - "watch:debug": "yarn run build && npm-run-all -p webpack:watch server:watch:debug --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", "predebug": "yarn run build", "predebug:server": "yarn run build", "debug": "node --debug-brk dist/server.js", diff --git a/src/app/+admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts b/src/app/+admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts index dc118a1dea..8b72afa083 100644 --- a/src/app/+admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts +++ b/src/app/+admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts @@ -14,7 +14,6 @@ import { PaginationComponent } from '../../../shared/pagination/pagination.compo import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub'; import { HostWindowService } from '../../../shared/host-window.service'; - describe('MetadataRegistryComponent', () => { let comp: MetadataRegistryComponent; let fixture: ComponentFixture; @@ -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; expect(mockName.textContent).toBe('mock'); }); - }); diff --git a/src/app/+browse-by/+browse-by-author-page/browse-by-author-page.component.ts b/src/app/+browse-by/+browse-by-author-page/browse-by-author-page.component.ts index aa5df99610..813ee8a32f 100644 --- a/src/app/+browse-by/+browse-by-author-page/browse-by-author-page.component.ts +++ b/src/app/+browse-by/+browse-by-author-page/browse-by-author-page.component.ts @@ -1,8 +1,9 @@ + +import {combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs'; import { Component, OnInit } from '@angular/core'; import { RemoteData } from '../../core/data/remote-data'; import { PaginatedList } from '../../core/data/paginated-list'; import { ItemDataService } from '../../core/data/item-data.service'; -import { Observable, Subscription } from 'rxjs'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { ActivatedRoute } from '@angular/router'; @@ -45,7 +46,7 @@ export class BrowseByAuthorPageComponent implements OnInit { sort: this.sortConfig }); this.subs.push( - Observable.combineLatest( + observableCombineLatest( this.route.params, this.route.queryParams, (params, queryParams, ) => { diff --git a/src/app/+browse-by/+browse-by-title-page/browse-by-title-page.component.ts b/src/app/+browse-by/+browse-by-title-page/browse-by-title-page.component.ts index c144ae5b61..e9127dbbab 100644 --- a/src/app/+browse-by/+browse-by-title-page/browse-by-title-page.component.ts +++ b/src/app/+browse-by/+browse-by-title-page/browse-by-title-page.component.ts @@ -1,9 +1,10 @@ + +import {combineLatest as observableCombineLatest, Observable , Subscription } from 'rxjs'; import { Component, OnInit } from '@angular/core'; import { RemoteData } from '../../core/data/remote-data'; import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { PaginatedList } from '../../core/data/paginated-list'; import { ItemDataService } from '../../core/data/item-data.service'; -import { Observable , Subscription } from 'rxjs'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { Item } from '../../core/shared/item.model'; @@ -44,7 +45,7 @@ export class BrowseByTitlePageComponent implements OnInit { sort: this.sortConfig }); this.subs.push( - Observable.combineLatest( + observableCombineLatest( this.route.params, this.route.queryParams, (params, queryParams, ) => { diff --git a/src/app/+search-page/search-service/search-configuration.service.ts b/src/app/+search-page/search-service/search-configuration.service.ts index ab62cc0915..292f26724d 100644 --- a/src/app/+search-page/search-service/search-configuration.service.ts +++ b/src/app/+search-page/search-service/search-configuration.service.ts @@ -159,7 +159,7 @@ export class SearchConfigurationService implements OnDestroy { Object.keys(filterParams).forEach((key) => { if (key.endsWith('.min') || key.endsWith('.max')) { 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 max = filterParams[realKey + '.max'] ? filterParams[realKey + '.max'][0] : '*'; filters.push(new SearchFilter(realKey, ['[' + min + ' TO ' + max + ']'])); diff --git a/src/app/core/auth/auth-request.service.ts b/src/app/core/auth/auth-request.service.ts index 92af4644c6..7cb5fae7e4 100644 --- a/src/app/core/auth/auth-request.service.ts +++ b/src/app/core/auth/auth-request.service.ts @@ -1,5 +1,4 @@ import { Observable, of as observableOf, throwError as observableThrowError } from 'rxjs'; - import { distinctUntilChanged, filter, map, mergeMap, tap } from 'rxjs/operators'; import { Inject, Injectable } from '@angular/core'; import { HALEndpointService } from '../shared/hal-endpoint.service'; diff --git a/src/app/core/auth/auth-response-parsing.service.spec.ts b/src/app/core/auth/auth-response-parsing.service.spec.ts index f6dd87e99a..138d0f1be3 100644 --- a/src/app/core/auth/auth-response-parsing.service.spec.ts +++ b/src/app/core/auth/auth-response-parsing.service.spec.ts @@ -2,20 +2,18 @@ import { AuthStatusResponse } from '../cache/response-cache.models'; import { ObjectCacheService } from '../cache/object-cache.service'; 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 { AuthResponseParsingService } from './auth-response-parsing.service'; 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', () => { let service: AuthResponseParsingService; - const EnvConfig = {cache: {msToLive: 1000}} as GlobalConfig; - const store = getMockStore() as Store; - const objectCacheService = new ObjectCacheService(store); + const EnvConfig = { cache: { msToLive: 1000 } } as GlobalConfig; + const store = new MockStore({}); + const objectCacheService = new ObjectCacheService(store as any); beforeEach(() => { service = new AuthResponseParsingService(EnvConfig, objectCacheService); diff --git a/src/app/core/auth/auth.effects.spec.ts b/src/app/core/auth/auth.effects.spec.ts index 2820f2d210..0dc8abf860 100644 --- a/src/app/core/auth/auth.effects.spec.ts +++ b/src/app/core/auth/auth.effects.spec.ts @@ -4,8 +4,7 @@ import { provideMockActions } from '@ngrx/effects/testing'; import { Store } from '@ngrx/store'; import { cold, hot } from 'jasmine-marbles'; -import { Observable } from 'rxjs'; -import { of as observableOf, throwError as observableThrow } from 'rxjs'; +import { Observable, of as observableOf, throwError as observableThrow } from 'rxjs'; import { AuthEffects } from './auth.effects'; import { @@ -30,16 +29,21 @@ import { EPersonMock } from '../../shared/testing/eperson-mock'; describe('AuthEffects', () => { let authEffects: AuthEffects; let actions: Observable; - const authServiceStub = new AuthServiceStub(); + let authServiceStub; const store: Store = jasmine.createSpyObj('store', { /* tslint:disable:no-empty */ dispatch: {}, /* tslint:enable:no-empty */ select: observableOf(true) }); - const token = authServiceStub.getToken(); + let token; + function init() { + authServiceStub = new AuthServiceStub(); + token = authServiceStub.getToken(); + } beforeEach(() => { + init(); TestBed.configureTestingModule({ providers: [ AuthEffects, @@ -138,7 +142,7 @@ describe('AuthEffects', () => { describe('when check token failed', () => { 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}}); diff --git a/src/app/core/auth/auth.interceptor.ts b/src/app/core/auth/auth.interceptor.ts index 44c8ec088d..dd9e3fb5e7 100644 --- a/src/app/core/auth/auth.interceptor.ts +++ b/src/app/core/auth/auth.interceptor.ts @@ -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 { Injectable, Injector } from '@angular/core'; @@ -11,8 +11,6 @@ import { HttpResponse, HttpResponseBase } from '@angular/common/http'; - - import { find } from 'lodash'; import { AppState } from '../../app.reducer'; diff --git a/src/app/core/auth/auth.service.spec.ts b/src/app/core/auth/auth.service.spec.ts index bfc21359fb..187db93f3c 100644 --- a/src/app/core/auth/auth.service.spec.ts +++ b/src/app/core/auth/auth.service.spec.ts @@ -31,38 +31,50 @@ describe('AuthService test', () => { pipe: observableOf(true) }); let authService: AuthService; - const authRequest = new AuthRequestServiceStub(); + let authRequest; const window = new NativeWindowRef(); const routerStub = new RouterStub(); - const routeStub = new ActivatedRouteStub(); + let routeStub; let storage: CookieService; - const token: AuthTokenInfo = new AuthTokenInfo('test_token'); - token.expires = Date.now() + (1000 * 60 * 60); - let authenticatedState = { - authenticated: true, - loaded: true, - loading: false, - authToken: token, - user: EPersonMock - }; + let token: AuthTokenInfo; + let authenticatedState; 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(() => { + TestBed.configureTestingModule({ imports: [ CommonModule, - StoreModule.forRoot({authReducer}), + StoreModule.forRoot({ authReducer }), ], declarations: [], providers: [ - {provide: AuthRequestService, useValue: authRequest}, - {provide: NativeWindowService, useValue: window}, - {provide: REQUEST, useValue: {}}, - {provide: Router, useValue: routerStub}, - {provide: ActivatedRoute, useValue: routeStub}, + { provide: AuthRequestService, useValue: authRequest }, + { provide: NativeWindowService, useValue: window }, + { provide: REQUEST, useValue: {} }, + { provide: Router, useValue: routerStub }, + { provide: ActivatedRoute, useValue: routeStub }, {provide: Store, useValue: mockStore}, - {provide: RemoteDataBuildService, useValue: rdbService}, + { provide: RemoteDataBuildService, useValue: rdbService }, CookieService, AuthService ], @@ -115,15 +127,16 @@ describe('AuthService test', () => { describe('', () => { beforeEach(async(() => { + init(); TestBed.configureTestingModule({ imports: [ - StoreModule.forRoot({authReducer}) + StoreModule.forRoot({ authReducer }) ], providers: [ - {provide: AuthRequestService, useValue: authRequest}, - {provide: REQUEST, useValue: {}}, - {provide: Router, useValue: routerStub}, - {provide: RemoteDataBuildService, useValue: rdbService}, + { provide: AuthRequestService, useValue: authRequest }, + { provide: REQUEST, useValue: {} }, + { provide: Router, useValue: routerStub }, + { provide: RemoteDataBuildService, useValue: rdbService }, CookieService ] }).compileComponents(); @@ -167,12 +180,12 @@ describe('AuthService test', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ - StoreModule.forRoot({authReducer}) + StoreModule.forRoot({ authReducer }) ], providers: [ - {provide: AuthRequestService, useValue: authRequest}, - {provide: REQUEST, useValue: {}}, - {provide: Router, useValue: routerStub}, + { provide: AuthRequestService, useValue: authRequest }, + { provide: REQUEST, useValue: {} }, + { provide: Router, useValue: routerStub }, ClientCookieService, CookieService ] diff --git a/src/app/core/auth/auth.service.ts b/src/app/core/auth/auth.service.ts index dc2d1ca379..229c44bcfa 100644 --- a/src/app/core/auth/auth.service.ts +++ b/src/app/core/auth/auth.service.ts @@ -1,13 +1,14 @@ -import { of as observableOf, Observable , Observable } from 'rxjs'; +import { Observable, of as observableOf } from 'rxjs'; import { - take, - filter, - startWith, - first, distinctUntilChanged, + filter, + first, map, + startWith, + switchMap, + take, withLatestFrom -, map, switchMap, withLatestFrom } from 'rxjs/operators'; +} from 'rxjs/operators'; import { Inject, Injectable } from '@angular/core'; import { PRIMARY_OUTLET, Router, UrlSegmentGroup, UrlTree } from '@angular/router'; import { HttpHeaders } from '@angular/common/http'; diff --git a/src/app/core/cache/response-cache.models.ts b/src/app/core/cache/response-cache.models.ts index 9b1b5b89eb..9566dcdc3c 100644 --- a/src/app/core/cache/response-cache.models.ts +++ b/src/app/core/cache/response-cache.models.ts @@ -140,7 +140,7 @@ export class ErrorResponse extends RestResponse { constructor(error: RequestError) { super(false, error.statusText); - console.error(error); + // console.error(error); this.errorMessage = error.message; } } diff --git a/src/app/core/data/browse-response-parsing.service.spec.ts b/src/app/core/data/browse-response-parsing.service.spec.ts index b0fbb1f977..2b1703e38f 100644 --- a/src/app/core/data/browse-response-parsing.service.spec.ts +++ b/src/app/core/data/browse-response-parsing.service.spec.ts @@ -10,134 +10,148 @@ describe('BrowseResponseParsingService', () => { beforeEach(() => { service = new BrowseResponseParsingService(); }); + let validRequest; + let validResponse; + let invalidResponse1; + let invalidResponse2; + let invalidResponse3; + let definitions; 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 = { - payload: { - _embedded: { - browses: [{ - metadataBrowse: false, - sortOptions: [{ name: 'title', metadata: 'dc.title' }, { + validResponse = { + payload: { + _embedded: { + browses: [{ + 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' } + } + }, { + 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', 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' } + }, + { + name: 'dateaccessioned', + metadata: 'dc.date.accessioned' } - }, { - metadataBrowse: true, - sortOptions: [{ name: 'title', metadata: 'dc.title' }, { + ], + defaultSortOrder: 'ASC', + 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', 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; - - 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' } + }, + { + name: 'dateaccessioned', + metadata: 'dc.date.accessioned' } + ], + 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', () => { const response = service.parse(validRequest, validResponse); expect(response.constructor).toBe(GenericSuccessResponse); diff --git a/src/app/core/data/comcol-data.service.ts b/src/app/core/data/comcol-data.service.ts index 12be32a4f4..c589c5bdc8 100644 --- a/src/app/core/data/comcol-data.service.ts +++ b/src/app/core/data/comcol-data.service.ts @@ -1,5 +1,5 @@ -import { Observable, throwError as observableThrowError, merge as observableMerge } from 'rxjs'; -import { distinctUntilChanged, filter, first, map, mergeMap, tap } from 'rxjs/operators'; +import { distinctUntilChanged, filter, map, mergeMap, take, tap } from 'rxjs/operators'; +import { merge as observableMerge, Observable, throwError as observableThrowError } from 'rxjs'; import { isEmpty, isNotEmpty } from '../../shared/empty.util'; import { NormalizedCommunity } from '../cache/models/normalized-community.model'; import { ObjectCacheService } from '../cache/object-cache.service'; @@ -10,7 +10,6 @@ import { DataService } from './data.service'; import { FindAllOptions, FindByIDRequest } from './request.models'; import { NormalizedObject } from '../cache/models/normalized-object.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { DSOSuccessResponse } from '../cache/response-cache.models'; export abstract class ComColDataService extends DataService { protected abstract cds: CommunityDataService; @@ -31,14 +30,14 @@ export abstract class ComColDataService this.cds.getFindByIDHref(endpoint, options.scopeID)) - .filter((href: string) => isNotEmpty(href)) - .take(1) - .do((href: string) => { + const scopeCommunityHrefObs = this.cds.getEndpoint().pipe( + mergeMap((endpoint: string) => this.cds.getFindByIDHref(endpoint, options.scopeID)), + filter((href: string) => isNotEmpty(href)), + take(1), + tap((href: string) => { const request = new FindByIDRequest(this.requestService.generateRequestId(), href, options.scopeID); this.requestService.configure(request); - }); + }),); // return scopeCommunityHrefObs.pipe( // mergeMap((href: string) => this.responseCache.get(href)), diff --git a/src/app/core/data/community-data.service.ts b/src/app/core/data/community-data.service.ts index b8e8bd5ce0..6edd7fc23d 100644 --- a/src/app/core/data/community-data.service.ts +++ b/src/app/core/data/community-data.service.ts @@ -41,7 +41,7 @@ export class CommunityDataService extends ComColDataService>> { 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( filter((href: string) => hasValue(href)), diff --git a/src/app/core/data/data.service.spec.ts b/src/app/core/data/data.service.spec.ts index 1adf108687..d65bad9bbf 100644 --- a/src/app/core/data/data.service.spec.ts +++ b/src/app/core/data/data.service.spec.ts @@ -9,6 +9,7 @@ import { HALEndpointService } from '../shared/hal-endpoint.service'; import { Observable } from 'rxjs'; import { FindAllOptions } from './request.models'; import { SortOptions, SortDirection } from '../cache/models/sort-options.model'; +import { of as observableOf } from 'rxjs'; const endpoint = 'https://rest.api/core'; @@ -17,107 +18,107 @@ class NormalizedTestObject extends NormalizedObject { } class TestService extends DataService { - constructor( - protected responseCache: ResponseCacheService, - protected requestService: RequestService, - protected rdbService: RemoteDataBuildService, - protected store: Store, - protected linkPath: string, - protected halService: HALEndpointService - ) { - super(); - } + constructor( + protected responseCache: ResponseCacheService, + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected store: Store, + protected linkPath: string, + protected halService: HALEndpointService + ) { + super(); + } - public getBrowseEndpoint(options: FindAllOptions): Observable { - return Observable.of(endpoint); - } + public getBrowseEndpoint(options: FindAllOptions): Observable { + return observableOf(endpoint); + } } describe('DataService', () => { - let service: TestService; - let options: FindAllOptions; - const responseCache = {} as ResponseCacheService; - const requestService = {} as RequestService; - const halService = {} as HALEndpointService; - const rdbService = {} as RemoteDataBuildService; - const store = {} as Store; + let service: TestService; + let options: FindAllOptions; + const responseCache = {} as ResponseCacheService; + const requestService = {} as RequestService; + const halService = {} as HALEndpointService; + const rdbService = {} as RemoteDataBuildService; + const store = {} as Store; - function initTestService(): TestService { - return new TestService( - responseCache, - requestService, - rdbService, - store, - endpoint, - halService - ); - } + function initTestService(): TestService { + return new TestService( + responseCache, + requestService, + rdbService, + store, + endpoint, + halService + ); + } - service = initTestService(); + service = initTestService(); - describe('getFindAllHref', () => { + describe('getFindAllHref', () => { - it('should return an observable with the endpoint', () => { - options = {}; + it('should return an observable with the endpoint', () => { + options = {}; - (service as any).getFindAllHref(options).subscribe((value) => { - 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); - }); - }) + (service as any).getFindAllHref(options).subscribe((value) => { + 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); + }); + }) + }); + }); diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts index a42990f780..f52f61cea1 100644 --- a/src/app/core/data/data.service.ts +++ b/src/app/core/data/data.service.ts @@ -1,5 +1,5 @@ -import { filter, take, first } from 'rxjs/operators'; -import {of as observableOf, Observable } from 'rxjs'; +import { distinctUntilChanged, filter, take, first, map } from 'rxjs/operators'; +import { of as observableOf, Observable } from 'rxjs'; import { Store } from '@ngrx/store'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; 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 { RequestService } from './request.service'; import { NormalizedObject } from '../cache/models/normalized-object.model'; -import { promise } from 'selenium-webdriver'; -import map = promise.map; export abstract class DataService { protected abstract responseCache: ResponseCacheService; @@ -29,7 +27,7 @@ export abstract class DataService let result: Observable; const args = []; - result = this.getBrowseEndpoint(options).distinctUntilChanged(); + result = this.getBrowseEndpoint(options).pipe(distinctUntilChanged()); 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 */ diff --git a/src/app/core/data/item-data.service.ts b/src/app/core/data/item-data.service.ts index 9a6a83952d..89b2eef568 100644 --- a/src/app/core/data/item-data.service.ts +++ b/src/app/core/data/item-data.service.ts @@ -1,3 +1,5 @@ + +import {distinctUntilChanged, map, filter} from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; @@ -40,10 +42,10 @@ export class ItemDataService extends DataService { if (options.sort && options.sort.field) { field = options.sort.field; } - return this.bs.getBrowseURLFor(field, this.linkPath) - .filter((href: string) => isNotEmpty(href)) - .map((href: string) => new URLCombiner(href, `?scope=${options.scopeID}`).toString()) - .distinctUntilChanged(); + return this.bs.getBrowseURLFor(field, this.linkPath).pipe( + filter((href: string) => isNotEmpty(href)), + map((href: string) => new URLCombiner(href, `?scope=${options.scopeID}`).toString()), + distinctUntilChanged(),); } } diff --git a/src/app/core/data/test.spec.ts b/src/app/core/data/test.spec.ts deleted file mode 100644 index 3659c66e11..0000000000 --- a/src/app/core/data/test.spec.ts +++ /dev/null @@ -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) { - 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$) - }); -}) \ No newline at end of file diff --git a/src/app/core/metadata/metadata.service.ts b/src/app/core/metadata/metadata.service.ts index 860dd71ce6..ede66f6952 100644 --- a/src/app/core/metadata/metadata.service.ts +++ b/src/app/core/metadata/metadata.service.ts @@ -1,29 +1,18 @@ - -import {distinctUntilKeyChanged, map, filter, first, take} from 'rxjs/operators'; - - - +import { distinctUntilKeyChanged, filter, first, map, take } from 'rxjs/operators'; import { Inject, Injectable } from '@angular/core'; -import { - ActivatedRoute, - Event, - NavigationEnd, - Params, - Router -} from '@angular/router'; +import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { Meta, MetaDefinition, Title } from '@angular/platform-browser'; import { TranslateService } from '@ngx-translate/core'; -import { BehaviorSubject , Observable } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; import { RemoteData } from '../data/remote-data'; import { Bitstream } from '../shared/bitstream.model'; import { CacheableObject } from '../cache/object-cache.reducer'; import { DSpaceObject } from '../shared/dspace-object.model'; import { Item } from '../shared/item.model'; -import { Metadatum } from '../shared/metadatum.model'; import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; import { BitstreamFormat } from '../shared/bitstream-format.model'; diff --git a/src/app/shared/auth-nav-menu/auth-nav-menu.component.spec.ts b/src/app/shared/auth-nav-menu/auth-nav-menu.component.spec.ts index e1a82f4a33..5c5dd11d75 100644 --- a/src/app/shared/auth-nav-menu/auth-nav-menu.component.spec.ts +++ b/src/app/shared/auth-nav-menu/auth-nav-menu.component.spec.ts @@ -22,23 +22,28 @@ describe('AuthNavMenuComponent', () => { let deNavMenuItem: DebugElement; let fixture: ComponentFixture; - const notAuthState: AuthState = { - authenticated: false, - loaded: false, - loading: false - }; - const authState: AuthState = { - authenticated: true, - loaded: true, - loading: false, - authToken: new AuthTokenInfo('test_token'), - user: EPersonMock - }; + let notAuthState: AuthState; + let authState: AuthState; + let routerState = { 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', () => { + beforeEach(async(() => { const window = new HostWindowServiceStub(800); @@ -53,8 +58,13 @@ describe('AuthNavMenuComponent', () => { AuthNavMenuComponent ], providers: [ - {provide: HostWindowService, useValue: window}, - {provide: AuthService, useValue: {setRedirectUrl: () => { /*empty*/ }}} + { provide: HostWindowService, useValue: window }, + { + provide: AuthService, useValue: { + setRedirectUrl: () => { /*empty*/ + } + } + } ], schemas: [ CUSTOM_ELEMENTS_SCHEMA @@ -64,11 +74,14 @@ describe('AuthNavMenuComponent', () => { })); + beforeEach(() => { + init(); + }); describe('when route is /login and user is not authenticated', () => { - routerState = { - url: '/login' - }; beforeEach(inject([Store], (store: Store) => { + routerState = { + url: '/login' + }; store .subscribe((state) => { (state as any).router = Object.create({}); @@ -91,7 +104,9 @@ describe('AuthNavMenuComponent', () => { const navMenuItemSelector = 'li'; deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); - + afterEach(() => { + fixture.destroy(); + }); it('should not render', () => { expect(component).toBeTruthy(); expect(deNavMenu.nativeElement).toBeDefined(); @@ -101,10 +116,10 @@ describe('AuthNavMenuComponent', () => { }); describe('when route is /logout and user is authenticated', () => { - routerState = { - url: '/logout' - }; beforeEach(inject([Store], (store: Store) => { + routerState = { + url: '/logout' + }; store .subscribe((state) => { (state as any).router = Object.create({}); @@ -128,6 +143,10 @@ describe('AuthNavMenuComponent', () => { deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); + afterEach(() => { + fixture.destroy(); + }); + it('should not render', () => { expect(component).toBeTruthy(); expect(deNavMenu.nativeElement).toBeDefined(); @@ -166,6 +185,11 @@ describe('AuthNavMenuComponent', () => { deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); + afterEach(() => { + fixture.destroy(); + component = null; + }); + it('should render login dropdown menu', () => { const loginDropdownMenu = deNavMenuItem.query(By.css('div[id=loginDropdownMenu]')); expect(loginDropdownMenu.nativeElement).toBeDefined(); @@ -200,6 +224,10 @@ describe('AuthNavMenuComponent', () => { deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); + afterEach(() => { + fixture.destroy(); + component = null; + }); it('should render logout dropdown menu', () => { const logoutDropdownMenu = deNavMenuItem.query(By.css('div[id=logoutDropdownMenu]')); expect(logoutDropdownMenu.nativeElement).toBeDefined(); @@ -223,8 +251,13 @@ describe('AuthNavMenuComponent', () => { AuthNavMenuComponent ], providers: [ - {provide: HostWindowService, useValue: window}, - {provide: AuthService, useValue: {setRedirectUrl: () => { /*empty*/ }}} + { provide: HostWindowService, useValue: window }, + { + provide: AuthService, useValue: { + setRedirectUrl: () => { /*empty*/ + } + } + } ], schemas: [ CUSTOM_ELEMENTS_SCHEMA @@ -234,6 +267,9 @@ describe('AuthNavMenuComponent', () => { })); + beforeEach(() => { + init(); + }); describe('when user is not authenticated', () => { beforeEach(inject([Store], (store: Store) => { @@ -260,6 +296,11 @@ describe('AuthNavMenuComponent', () => { deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); + afterEach(() => { + fixture.destroy(); + component = null; + }); + it('should render login link', () => { const loginDropdownMenu = deNavMenuItem.query(By.css('a[id=loginLink]')); expect(loginDropdownMenu.nativeElement).toBeDefined(); @@ -291,6 +332,11 @@ describe('AuthNavMenuComponent', () => { deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); + afterEach(() => { + fixture.destroy(); + component = null; + }); + it('should render logout link', inject([Store], (store: Store) => { const logoutDropdownMenu = deNavMenuItem.query(By.css('a[id=logoutLink]')); expect(logoutDropdownMenu.nativeElement).toBeDefined(); diff --git a/src/app/shared/auth-nav-menu/auth-nav-menu.component.ts b/src/app/shared/auth-nav-menu/auth-nav-menu.component.ts index 5fb6aaaabf..4361163538 100644 --- a/src/app/shared/auth-nav-menu/auth-nav-menu.component.ts +++ b/src/app/shared/auth-nav-menu/auth-nav-menu.component.ts @@ -60,15 +60,17 @@ export class AuthNavMenuComponent implements OnInit { this.user = this.store.pipe(select(getAuthenticatedUser)); - this.showAuth = this.store.select(routerStateSelector) - .filter((router: RouterReducerState) => isNotUndefined(router) && isNotUndefined(router.state)) - .map((router: RouterReducerState) => { + this.showAuth = this.store.pipe( + select(routerStateSelector), + filter((router: RouterReducerState) => isNotUndefined(router) && isNotUndefined(router.state)), + map((router: RouterReducerState) => { const url = router.state.url; const show = !router.state.url.startsWith(LOGIN_ROUTE) && !router.state.url.startsWith(LOGOUT_ROUTE); if (show) { this.authService.setRedirectUrl(url); } return show; - }); + }) + ); } } diff --git a/src/app/shared/browse-by/browse-by.component.spec.ts b/src/app/shared/browse-by/browse-by.component.spec.ts index 883d61a221..2417dde7ca 100644 --- a/src/app/shared/browse-by/browse-by.component.spec.ts +++ b/src/app/shared/browse-by/browse-by.component.spec.ts @@ -3,7 +3,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { TranslateModule } from '@ngx-translate/core'; import { By } from '@angular/platform-browser'; import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { Observable } from 'rxjs/Observable'; +import { of as observableOf } from 'rxjs'; import { SharedModule } from '../shared.module'; describe('BrowseByComponent', () => { @@ -30,7 +30,7 @@ describe('BrowseByComponent', () => { }); it('should display results when objects is not empty', () => { - (comp as any).objects = Observable.of({ + (comp as any).objects = observableOf({ payload: { page: { length: 1 diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html index d838a90f20..750ef721c2 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.html @@ -1,8 +1,8 @@ -
- diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.spec.ts index ab98476cc3..ca12a7a4b4 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control.component.spec.ts @@ -172,7 +172,6 @@ describe('DsDynamicFormControlComponent test suite', () => { }); fixture.detectChanges(); - console.log(fixture.componentInstance.componentViewContainerRef); testElement = debugElement.query(By.css(`input[id='${testModel.id}']`)); })); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component.ts index 6cac65ff65..2e22f314ed 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component.ts @@ -20,7 +20,6 @@ export class DsDatePickerComponent extends DynamicFormControlComponent implement @Input() bindId = true; @Input() group: FormGroup; @Input() model: DynamicDsDatePickerModel; - // @Input() showErrorMessages = false; // @Input() // minDate; // @Input() diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model.ts index b38ea142f0..b91af8f0c9 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-array-model.ts @@ -6,16 +6,16 @@ import { import { DYNAMIC_FORM_CONTROL_TYPE_TAG } from './tag/dynamic-tag.model'; export interface DynamicRowArrayModelConfig extends DynamicFormArrayModelConfig { - notRepeteable: boolean; + notRepeatable: boolean; } export class DynamicRowArrayModel extends DynamicFormArrayModel { - @serializable() notRepeteable = false; + @serializable() notRepeatable = false; isRowArray = true; constructor(config: DynamicRowArrayModelConfig, layout?: DynamicFormControlLayout) { super(config, layout); - this.notRepeteable = config.notRepeteable; + this.notRepeatable = config.notRepeatable; } } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts index a3205e69c6..42d8f4b6de 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.component.spec.ts @@ -4,7 +4,6 @@ import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { TranslateModule } from '@ngx-translate/core'; -import { of as observableOf } from 'rxjs'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 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 { DsDynamicInputModel } from '../ds-dynamic-input.model'; 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 { MockStore } from '../../../../../testing/mock-store'; +import { Store } from '@ngrx/store'; +import { AppState } from '../../../../../../app.reducer'; -export const 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 let FORM_GROUP_TEST_MODEL_CONFIG; -export const FORM_GROUP_TEST_GROUP = new FormGroup({ - dc_contributor_author: new FormControl(), -}); +export let FORM_GROUP_TEST_GROUP; -describe('DsDynamicGroupComponent test suite', () => { - const config = { +let 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: { validatorMap: { required: 'required', @@ -87,11 +92,15 @@ describe('DsDynamicGroupComponent test suite', () => { } } } as any; + +} + +describe('DsDynamicGroupComponent test suite', () => { let testComp: TestComponent; let groupComp: DsDynamicGroupComponent; let testFixture: ComponentFixture; let groupFixture: ComponentFixture; - // let modelValue: any; + let modelValue: any; let html; let control1: FormControl; let model1: DsDynamicInputModel; @@ -100,7 +109,9 @@ describe('DsDynamicGroupComponent test suite', () => { // async beforeEach beforeEach(async(() => { - + init(); + const store = new MockStore(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({ imports: [ BrowserAnimationsModule, @@ -110,18 +121,20 @@ describe('DsDynamicGroupComponent test suite', () => { TranslateModule.forRoot() ], declarations: [ - MockComponent(FormComponent), + FormComponent, DsDynamicGroupComponent, TestComponent, ], // declare the test component providers: [ ChangeDetectorRef, DsDynamicGroupComponent, - {provide: FormBuilderService, useValue: getMockFormBuilderService()}, - {provide: FormService, useValue: getMockFormService()}, - {provide: GLOBAL_CONFIG, useValue: config}, - {provide: DynamicFormLayoutService, useValue: {}}, - {provide: DynamicFormValidationService, useValue: {}} + DynamicFormValidationService, + DynamicFormLayoutService, + FormBuilderService, + FormComponent, + FormService, + { provide: GLOBAL_CONFIG, useValue: config }, + {provide: Store, useValue: store}, ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }); @@ -143,6 +156,11 @@ describe('DsDynamicGroupComponent test suite', () => { testComp = testFixture.componentInstance; }); + afterEach(() => { + testFixture.destroy(); + testComp = null; + }); + it('should create DsDynamicGroupComponent', inject([DsDynamicGroupComponent], (app: DsDynamicGroupComponent) => { expect(app).toBeDefined(); @@ -158,7 +176,6 @@ describe('DsDynamicGroupComponent test suite', () => { groupComp.group = FORM_GROUP_TEST_GROUP; groupComp.model = new DynamicGroupModel(FORM_GROUP_TEST_MODEL_CONFIG); groupFixture.detectChanges(); - 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; 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; }); - // it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => { - // const formConfig = {rows: groupComp.model.formConfiguration} as SubmissionFormsModel; - // const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); - // const chips = new Chips([], 'value', 'dc.contributor.author'); - // - // expect(groupComp.formCollapsed).toEqual(observableOf(false)); - // 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'); - // (model1 as any).value = new FormFieldMetadataValueObject('test author'); - // control2.setValue('test affiliation'); - // (model2 as any).value = new FormFieldMetadataValueObject('test affiliation'); - // modelValue = [{ - // 'dc.contributor.author': new FormFieldMetadataValueObject('test author'), - // 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation') - // }]; - // groupFixture.detectChanges(); - // - // const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button'); - // const btnEl = buttons[0]; - // btnEl.click(); - // - // expect(groupComp.chips.getChipsItems()).toEqual(modelValue); - // expect(groupComp.formCollapsed).toEqual(observableOf(true)); - // }); - // - // it('should clear form inputs', () => { - // control1.setValue('test author'); - // (model1 as any).value = new FormFieldMetadataValueObject('test author'); - // control2.setValue('test affiliation'); - // (model2 as any).value = new FormFieldMetadataValueObject('test affiliation'); - // - // groupFixture.detectChanges(); - // - // const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button'); - // const btnEl = buttons[2]; - // btnEl.click(); - // - // expect(control1.value).toBeNull(); - // expect(control2.value).toBeNull(); - // expect(groupComp.formCollapsed).toEqual(observableOf(false)); - // }); - // }); - // - // describe('when init model value is not empty', () => { - // beforeEach(() => { - // - // groupFixture = TestBed.createComponent(DsDynamicGroupComponent); - // groupComp = groupFixture.componentInstance; // FormComponent test instance - // groupComp.formId = 'testForm'; - // groupComp.group = FORM_GROUP_TEST_GROUP; - // groupComp.model = new DynamicGroupModel(FORM_GROUP_TEST_MODEL_CONFIG); - // modelValue = [{ - // 'dc.contributor.author': new FormFieldMetadataValueObject('test author'), - // 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation') - // }]; - // groupComp.model.value = modelValue; - // groupComp.showErrorMessages = false; - // groupFixture.detectChanges(); - // - // }); - // - // afterEach(() => { - // groupFixture.destroy(); - // groupComp = null; - // }); - // - // it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => { - // const formConfig = {rows: groupComp.model.formConfiguration} as SubmissionFormsModel; - // const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); - // const chips = new Chips(modelValue, 'value', 'dc.contributor.author'); - // - // expect(groupComp.formCollapsed).toEqual(observableOf(true)); - // expect(groupComp.formModel.length).toEqual(formModel.length); - // expect(groupComp.chips.getChipsItems()).toEqual(chips.getChipsItems()); - // })); - // - // it('should modify existing chips item', inject([FormBuilderService], (service: FormBuilderService) => { - // groupComp.onChipSelected(0); - // groupFixture.detectChanges(); - // - // 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; - // - // control1.setValue('test author modify'); - // (model1 as any).value = new FormFieldMetadataValueObject('test author modify'); - // - // modelValue = [{ - // 'dc.contributor.author': new FormFieldMetadataValueObject('test author modify'), - // 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation') - // }]; - // groupFixture.detectChanges(); - // - // const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button'); - // const btnEl = buttons[0]; - // btnEl.click(); - // - // groupFixture.detectChanges(); - // - // expect(groupComp.chips.getChipsItems()).toEqual(modelValue); - // expect(groupComp.formCollapsed).toEqual(observableOf(true)); - // })); - // - // it('should delete existing chips item', () => { - // groupComp.onChipSelected(0); - // groupFixture.detectChanges(); - // - // const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button'); - // const btnEl = buttons[1]; - // btnEl.click(); - // - // expect(groupComp.chips.getChipsItems()).toEqual([]); - // expect(groupComp.formCollapsed).toEqual(observableOf(false)); - // }); + it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => { + const formConfig = { rows: groupComp.model.formConfiguration } as SubmissionFormsModel; + const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); + const chips = new Chips([], 'value', 'dc.contributor.author'); + groupComp.formCollapsed.subscribe((value) => { + expect(value).toEqual(false); + }); + 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'); + (model1 as any).value = new FormFieldMetadataValueObject('test author'); + control2.setValue('test affiliation'); + (model2 as any).value = new FormFieldMetadataValueObject('test affiliation'); + modelValue = [{ + 'dc.contributor.author': new FormFieldMetadataValueObject('test author'), + 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation') + }]; + groupFixture.detectChanges(); + + const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button'); + const btnEl = buttons[0]; + btnEl.click(); + + 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'); + (model2 as any).value = new FormFieldMetadataValueObject('test affiliation'); + + groupFixture.detectChanges(); + + const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button'); + const btnEl = buttons[2]; + btnEl.click(); + + expect(control1.value).toBeNull(); + expect(control2.value).toBeNull(); + groupComp.formCollapsed.subscribe((value) => { + expect(value).toEqual(false); + }); + }); + }); + + describe('when init model value is not empty', () => { + beforeEach(() => { + + groupFixture = TestBed.createComponent(DsDynamicGroupComponent); + groupComp = groupFixture.componentInstance; // FormComponent test instance + groupComp.formId = 'testForm'; + groupComp.group = FORM_GROUP_TEST_GROUP; + groupComp.model = new DynamicGroupModel(FORM_GROUP_TEST_MODEL_CONFIG); + modelValue = [{ + 'dc.contributor.author': new FormFieldMetadataValueObject('test author'), + 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation') + }]; + groupComp.model.value = modelValue; + groupFixture.detectChanges(); + + }); + + afterEach(() => { + groupFixture.destroy(); + groupComp = null; + }); + + it('should init component properly', inject([FormBuilderService], (service: FormBuilderService) => { + const formConfig = { rows: groupComp.model.formConfiguration } as SubmissionFormsModel; + const formModel = service.modelFromConfiguration(formConfig, groupComp.model.scopeUUID, {}, groupComp.model.submissionScope, groupComp.model.readOnly); + const chips = new Chips(modelValue, 'value', 'dc.contributor.author'); + groupComp.formCollapsed.subscribe((value) => { + expect(value).toEqual(true); + }) + expect(groupComp.formModel.length).toEqual(formModel.length); + expect(groupComp.chips.getChipsItems()).toEqual(chips.getChipsItems()); + })); + + it('should modify existing chips item', inject([FormBuilderService], (service: FormBuilderService) => { + groupComp.onChipSelected(0); + groupFixture.detectChanges(); + + 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; + + control1.setValue('test author modify'); + (model1 as any).value = new FormFieldMetadataValueObject('test author modify'); + + modelValue = [{ + 'dc.contributor.author': new FormFieldMetadataValueObject('test author modify'), + 'local.contributor.affiliation': new FormFieldMetadataValueObject('test affiliation') + }]; + groupFixture.detectChanges(); + + const buttons = groupFixture.debugElement.nativeElement.querySelectorAll('button'); + const btnEl = buttons[0]; + btnEl.click(); + + groupFixture.detectChanges(); + + expect(groupComp.chips.getChipsItems()).toEqual(modelValue); + groupComp.formCollapsed.subscribe((value) => { + expect(value).toEqual(true); + }) + })); + + it('should delete existing chips item', () => { + groupComp.onChipSelected(0); + 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); + }) + }); }); }); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts index fa3350e43c..40e337588a 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/dynamic-group/dynamic-group.components.ts @@ -45,7 +45,6 @@ export class DsDynamicGroupComponent extends DynamicFormControlComponent impleme @Input() formId: string; @Input() group: FormGroup; @Input() model: DynamicGroupModel; - // @Input() showErrorMessages = false; @Output() blur: EventEmitter = new EventEmitter(); @Output() change: EventEmitter = new EventEmitter(); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts index f5285ffa87..dc808f4759 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.ts @@ -33,7 +33,6 @@ export class DsDynamicListComponent extends DynamicFormControlComponent implemen @Input() bindId = true; @Input() group: FormGroup; @Input() model: DynamicListCheckboxGroupModel | DynamicListRadioGroupModel; - // @Input() showErrorMessages = false; @Output() blur: EventEmitter = new EventEmitter(); @Output() change: EventEmitter = new EventEmitter(); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts index a1ab4dfacd..62e9191893 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.spec.ts @@ -18,16 +18,13 @@ import { DsDynamicLookupComponent } from './dynamic-lookup.component'; import { DynamicLookupModel } from './dynamic-lookup.model'; import { InfiniteScrollModule } from 'ngx-infinite-scroll'; 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 { By } from '@angular/platform-browser'; import { AuthorityValueModel } from '../../../../../../core/integration/models/authority-value.model'; -import { DynamicLookupNameModel } from './dynamic-lookup-name.model'; import { createTestComponent } from '../../../../../testing/utils'; +import { DynamicLookupNameModel } from './dynamic-lookup-name.model'; -export const LOOKUP_TEST_MODEL_CONFIG = { +let LOOKUP_TEST_MODEL_CONFIG = { authorityOptions: { closed: false, metadata: 'lookup', @@ -35,7 +32,7 @@ export const LOOKUP_TEST_MODEL_CONFIG = { scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' } as AuthorityOptions, disabled: false, - errorMessages: {required: 'Required field.'}, + errorMessages: { required: 'Required field.' }, id: 'lookup', label: 'Author', maxOptions: 10, @@ -45,11 +42,11 @@ export const LOOKUP_TEST_MODEL_CONFIG = { required: true, repeatable: true, separator: ',', - validators: {required: null}, + validators: { required: null }, value: undefined }; -export const LOOKUP_NAME_TEST_MODEL_CONFIG = { +let LOOKUP_NAME_TEST_MODEL_CONFIG = { authorityOptions: { closed: false, metadata: 'lookup-name', @@ -57,7 +54,7 @@ export const LOOKUP_NAME_TEST_MODEL_CONFIG = { scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' } as AuthorityOptions, disabled: false, - errorMessages: {required: 'Required field.'}, + errorMessages: { required: 'Required field.' }, id: 'lookupName', label: 'Author', maxOptions: 10, @@ -67,16 +64,67 @@ export const LOOKUP_NAME_TEST_MODEL_CONFIG = { required: true, repeatable: true, separator: ',', - validators: {required: null}, + validators: { required: null }, value: undefined }; -export const LOOKUP_TEST_GROUP = new FormGroup({ +let LOOKUP_TEST_GROUP = new FormGroup({ lookup: new FormControl(), lookupName: new FormControl() }); 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 lookupComp: DsDynamicLookupComponent; @@ -84,11 +132,11 @@ describe('Dynamic Lookup component', () => { let lookupFixture: ComponentFixture; let html; - const authorityServiceStub = new AuthorityServiceStub(); - + let authorityServiceStub; // async beforeEach beforeEach(async(() => { - + const authorityService = new AuthorityServiceStub(); + authorityServiceStub = authorityService; TestBed.configureTestingModule({ imports: [ DynamicFormsCoreModule, @@ -106,16 +154,19 @@ describe('Dynamic Lookup component', () => { providers: [ ChangeDetectorRef, DsDynamicLookupComponent, - {provide: AuthorityService, useValue: authorityServiceStub}, - {provide: DynamicFormLayoutService, useValue: {}}, - {provide: DynamicFormValidationService, useValue: {}} + { provide: AuthorityService, useValue: authorityService }, + { provide: DynamicFormLayoutService, useValue: {} }, + { provide: DynamicFormValidationService, useValue: {} } ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }); - })); - describe('', () => { + beforeEach(() => { + init(); + }); + + describe('DynamicLookUpComponent', () => { // synchronous beforeEach beforeEach(() => { html = ` @@ -130,200 +181,236 @@ describe('Dynamic Lookup component', () => { testFixture = createTestComponent(html, TestComponent) as ComponentFixture; testComp = testFixture.componentInstance; }); - + afterEach(() => { + testFixture.destroy(); + testComp = null; + }); it('should create DsDynamicLookupComponent', inject([DsDynamicLookupComponent], (app: DsDynamicLookupComponent) => { expect(app).toBeDefined(); })); - }); - describe('when model is DynamicLookupModel', () => { + describe('when model is DynamicLookupModel', () => { - describe('', () => { - beforeEach(() => { + describe('', () => { + 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', () => { - const de = lookupFixture.debugElement.queryAll(By.css('input.form-control')); - expect(de.length).toBe(1); + 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 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', () => { - 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(); - }); - - 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(); + lookupFixture = TestBed.createComponent(DsDynamicLookupComponent); + lookupComp = lookupFixture.componentInstance; // FormComponent test instance + lookupComp.group = LOOKUP_TEST_GROUP; + lookupComp.model = new DynamicLookupModel(LOOKUP_TEST_MODEL_CONFIG); + lookupComp.model.value = new FormFieldMetadataValueObject('test', null, 'test001'); + lookupFixture.detectChanges(); + // 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', () => { - beforeEach(() => { + describe('when model is DynamicLookupNameModel', () => { - lookupFixture = TestBed.createComponent(DsDynamicLookupComponent); - lookupComp = lookupFixture.componentInstance; // FormComponent test instance - lookupComp.group = LOOKUP_TEST_GROUP; - lookupComp.model = new DynamicLookupModel(LOOKUP_TEST_MODEL_CONFIG); - lookupComp.model.value = new FormFieldMetadataValueObject('test', null, 'test001'); - lookupFixture.detectChanges(); + 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'); + }); + 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', () => { - expect(lookupComp.firstInputValue).toBe('test') + 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(); + }); + + 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 @@ -338,7 +425,4 @@ class TestComponent { inputLookupModelConfig = LOOKUP_TEST_MODEL_CONFIG; model = new DynamicLookupModel(this.inputLookupModelConfig); - - showErrorMessages = false; - } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts index abe14dfb49..2a2ee64e9e 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.ts @@ -28,7 +28,6 @@ export class DsDynamicLookupComponent extends DynamicFormControlComponent implem @Input() bindId = true; @Input() group: FormGroup; @Input() model: DynamicLookupModel | DynamicLookupNameModel; - // @Input() showErrorMessages = false; @Output() blur: EventEmitter = new EventEmitter(); @Output() change: EventEmitter = new EventEmitter(); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts index 4b259b6cce..02468f9fbf 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.ts @@ -26,7 +26,6 @@ export class DsDynamicScrollableDropdownComponent extends DynamicFormControlComp @Input() bindId = true; @Input() group: FormGroup; @Input() model: DynamicScrollableDropdownModel; - // @Input() showErrorMessages = false; @Output() blur: EventEmitter = new EventEmitter(); @Output() change: EventEmitter = new EventEmitter(); diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts index 656d43bb68..9eaa23c004 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.spec.ts @@ -37,27 +37,32 @@ function createKeyUpEvent(key: number) { return event; } -export const TAG_TEST_GROUP = new FormGroup({ - tag: new FormControl(), -}); +let TAG_TEST_GROUP; +let TAG_TEST_MODEL_CONFIG; -export const TAG_TEST_MODEL_CONFIG = { - authorityOptions: { - closed: false, - metadata: 'tag', - name: 'common_iso_languages', - scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' - } as AuthorityOptions, - disabled: false, - id: 'tag', - label: 'Keywords', - minChars: 3, - name: 'tag', - placeholder: 'Keywords', - readOnly: false, - required: false, - repeatable: false -}; +function init() { + TAG_TEST_GROUP = new FormGroup({ + tag: new FormControl(), + }); + + TAG_TEST_MODEL_CONFIG = { + authorityOptions: { + closed: false, + metadata: 'tag', + name: 'common_iso_languages', + scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23' + } as AuthorityOptions, + disabled: false, + id: 'tag', + label: 'Keywords', + minChars: 3, + name: 'tag', + placeholder: 'Keywords', + readOnly: false, + required: false, + repeatable: false + }; +} describe('DsDynamicTagComponent test suite', () => { @@ -72,7 +77,7 @@ describe('DsDynamicTagComponent test suite', () => { // async beforeEach beforeEach(async(() => { const authorityServiceStub = new AuthorityServiceStub(); - + init(); TestBed.configureTestingModule({ imports: [ DynamicFormsCoreModule, @@ -88,10 +93,10 @@ describe('DsDynamicTagComponent test suite', () => { providers: [ ChangeDetectorRef, DsDynamicTagComponent, - {provide: AuthorityService, useValue: authorityServiceStub}, - {provide: GLOBAL_CONFIG, useValue: {} as GlobalConfig}, - {provide: DynamicFormLayoutService, useValue: {}}, - {provide: DynamicFormValidationService, useValue: {}} + { provide: AuthorityService, useValue: authorityServiceStub }, + { provide: GLOBAL_CONFIG, useValue: {} as GlobalConfig }, + { provide: DynamicFormLayoutService, useValue: {} }, + { provide: DynamicFormValidationService, useValue: {} } ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }); @@ -112,7 +117,9 @@ describe('DsDynamicTagComponent test suite', () => { testFixture = createTestComponent(html, TestComponent) as ComponentFixture; testComp = testFixture.componentInstance; }); - + afterEach(() => { + testFixture.destroy(); + }); it('should create DsDynamicTagComponent', inject([DsDynamicTagComponent], (app: DsDynamicTagComponent) => { expect(app).toBeDefined(); @@ -138,6 +145,7 @@ describe('DsDynamicTagComponent test suite', () => { it('should init component properly', () => { chips = new Chips([], 'display'); expect(tagComp.chips.getChipsItems()).toEqual(chips.getChipsItems()); + expect(tagComp.searchOptions).toBeDefined(); }); @@ -151,10 +159,14 @@ describe('DsDynamicTagComponent test suite', () => { it('should select a results entry properly', fakeAsync(() => { 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 = { - 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: () => { return; } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts index ce8d85b5e4..b8ef84d48d 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts @@ -1,4 +1,3 @@ - import {of as observableOf, Observable } from 'rxjs'; 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() group: FormGroup; @Input() model: DynamicTagModel; - // @Input() showErrorMessages = false; @Output() blur: EventEmitter = new EventEmitter(); @Output() change: EventEmitter = new EventEmitter(); @@ -80,12 +78,13 @@ export class DsDynamicTagComponent extends DynamicFormControlComponent implement private cdr: ChangeDetectorRef, protected layoutService: DynamicFormLayoutService, protected validationService: DynamicFormValidationService - ) { + ) { super(layoutService, validationService); } ngOnInit() { this.hasAuthority = this.model.authorityOptions && hasValue(this.model.authorityOptions.name); + if (this.hasAuthority) { this.searchOptions = new IntegrationSearchOptions( this.model.authorityOptions.scope, diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.spec.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.spec.ts index eb50ae732f..c950f8f4ef 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.spec.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.spec.ts @@ -22,29 +22,34 @@ import { DynamicTypeaheadModel } from './dynamic-typeahead.model'; import { FormFieldMetadataValueObject } from '../../../models/form-field-metadata-value.model'; import { createTestComponent } from '../../../../../testing/utils'; -export const TYPEAHEAD_TEST_GROUP = new FormGroup({ - typeahead: new FormControl(), -}); +export let TYPEAHEAD_TEST_GROUP; -export const 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 -}; +export let TYPEAHEAD_TEST_MODEL_CONFIG; +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', () => { let testComp: TestComponent; @@ -56,7 +61,7 @@ describe('DsDynamicTypeaheadComponent test suite', () => { // async beforeEach beforeEach(async(() => { const authorityServiceStub = new AuthorityServiceStub(); - + init() TestBed.configureTestingModule({ imports: [ DynamicFormsCoreModule, @@ -72,9 +77,9 @@ describe('DsDynamicTypeaheadComponent test suite', () => { providers: [ ChangeDetectorRef, DsDynamicTypeaheadComponent, - {provide: AuthorityService, useValue: authorityServiceStub}, - {provide: DynamicFormLayoutService, useValue: {}}, - {provide: DynamicFormValidationService, useValue: {}} + { provide: AuthorityService, useValue: authorityServiceStub }, + { provide: DynamicFormLayoutService, useValue: {} }, + { provide: DynamicFormValidationService, useValue: {} } ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }); @@ -96,6 +101,9 @@ describe('DsDynamicTypeaheadComponent test suite', () => { testComp = testFixture.componentInstance; }); + afterEach(() => { + testFixture.destroy(); + }); it('should create DsDynamicTypeaheadComponent', inject([DsDynamicTypeaheadComponent], (app: DsDynamicTypeaheadComponent) => { expect(app).toBeDefined(); @@ -221,6 +229,4 @@ class TestComponent { model = new DynamicTypeaheadModel(TYPEAHEAD_TEST_MODEL_CONFIG); - showErrorMessages = false; - } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts index 482820931f..58f8030bcc 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.component.ts @@ -26,7 +26,6 @@ export class DsDynamicTypeaheadComponent extends DynamicFormControlComponent imp @Input() bindId = true; @Input() group: FormGroup; @Input() model: DynamicTypeaheadModel; - @Input() showErrorMessages = false; @Output() blur: EventEmitter = new EventEmitter(); @Output() change: EventEmitter = new EventEmitter(); diff --git a/src/app/shared/form/builder/form-builder.service.spec.ts b/src/app/shared/form/builder/form-builder.service.spec.ts index 4e9f720e4e..5266afabfd 100644 --- a/src/app/shared/form/builder/form-builder.service.spec.ts +++ b/src/app/shared/form/builder/form-builder.service.spec.ts @@ -254,7 +254,7 @@ describe('FormBuilderService test suite', () => { { id: 'testFormRowArray', initialCount: 5, - notRepeteable: false, + notRepeatable: false, groupFactory: () => { return [ new DynamicInputModel({id: 'testFormRowArrayGroupInput'}) diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index f37b3868f3..3286b3fdbb 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -35,7 +35,7 @@ export abstract class FieldParser { id: uniqueId() + '_array', label: this.configData.label, initialCount: this.getInitArrayIndex(), - notRepeteable: !this.configData.repeatable, + notRepeatable: !this.configData.repeatable, groupFactory: () => { let model; if ((arrayCounter === 0)) { diff --git a/src/app/shared/form/form.component.html b/src/app/shared/form/form.component.html index 1b5f2ef72f..958c9a6c73 100644 --- a/src/app/shared/form/form.component.html +++ b/src/app/shared/form/form.component.html @@ -14,7 +14,7 @@ -