diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index 6906cbca2..0131b06df 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -24,10 +24,7 @@ import { SharedModule } from './shared/shared.module'; import { WizardModule } from './wizard/wizard.module'; import { FormModule } from './schema-form/schema-form.module'; import { environment } from '../environments/environment.prod'; -import { getCurrentLocale } from './shared/util'; import { I18nModule } from './i18n/i18n.module'; -import { WidgetRegistry } from 'ngx-schema-form'; -import { CustomWidgetRegistry } from './schema-form/registry'; @NgModule({ declarations: [ diff --git a/ui/src/app/metadata/domain/component/editor-nav.component.spec.ts b/ui/src/app/metadata/domain/component/editor-nav.component.spec.ts index a43fe52d3..755e61205 100644 --- a/ui/src/app/metadata/domain/component/editor-nav.component.spec.ts +++ b/ui/src/app/metadata/domain/component/editor-nav.component.spec.ts @@ -5,32 +5,31 @@ import { StoreModule, Store, combineReducers } from '@ngrx/store'; import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; -import * as fromRoot from '../reducer'; import { SchemaFormModule, WidgetRegistry, DefaultWidgetRegistry } from 'ngx-schema-form'; import * as fromWizard from '../../../wizard/reducer'; -import { ProviderEditorNavComponent, NAV_FORMATS } from './provider-editor-nav.component'; +import { EditorNavComponent, NAV_FORMATS } from './editor-nav.component'; import { ValidFormIconComponent } from '../../../shared/component/valid-form-icon.component'; import { WizardStep } from '../../../wizard/model'; import { MockI18nModule } from '../../../../testing/i18n.stub'; @Component({ template: ` - + ` }) class TestHostComponent { - @ViewChild(ProviderEditorNavComponent) - public componentUnderTest: ProviderEditorNavComponent; + @ViewChild(EditorNavComponent) + public componentUnderTest: EditorNavComponent; public format = NAV_FORMATS; } -describe('Provider Editor Nav Component', () => { +describe('Editor Nav Component', () => { let fixture: ComponentFixture; let instance: TestHostComponent; - let app: ProviderEditorNavComponent; - let store: Store; + let app: EditorNavComponent; + let store: Store; let step: WizardStep = { id: 'common', @@ -47,13 +46,12 @@ describe('Provider Editor Nav Component', () => { RouterTestingModule, SchemaFormModule.forRoot(), StoreModule.forRoot({ - provider: combineReducers(fromRoot.reducers), wizard: combineReducers(fromWizard.reducers) }), MockI18nModule ], declarations: [ - ProviderEditorNavComponent, + EditorNavComponent, ValidFormIconComponent, TestHostComponent ], diff --git a/ui/src/app/metadata/domain/component/forms/advanced-info-form.component.html b/ui/src/app/metadata/domain/component/forms/advanced-info-form.component.html deleted file mode 100644 index e7e9399bb..000000000 --- a/ui/src/app/metadata/domain/component/forms/advanced-info-form.component.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - Service Provider Name (Dashboard Display Only) - - - - - - - - - - - - - - Service Provider Entity ID - - - - - - - - - - - - - - Enable this service? - - - - - - - - - Organization Name - - - - - - - - - - - - - - Organization Display Name - - - - - - - - - - - - - - Organization URL - - - - - - - - - - - - * These three fields must all be entered if any single field has a value. - - - - - Contact Information: - - Add Contact - - - - - - - - - - - {{ contact.get('name').value || 'New Contact' }} - ({{ contact.get('type').value }}) - - - - - - - - - - - - - - - - - Name - - - - - - - - - - - - - Type - - - - - - - - {{ opt }} - - - - - - - - - - - Email Address - - - - - - - - Must be a valid Email Address - - - - - - - - - - - diff --git a/ui/src/app/metadata/domain/component/forms/advanced-info-form.component.spec.ts b/ui/src/app/metadata/domain/component/forms/advanced-info-form.component.spec.ts deleted file mode 100644 index 424b4d2d2..000000000 --- a/ui/src/app/metadata/domain/component/forms/advanced-info-form.component.spec.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ViewChild, Component } from '@angular/core'; -import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { Observable, of } from 'rxjs'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { AdvancedInfoFormComponent } from './advanced-info-form.component'; -import * as stubs from '../../../../../testing/resolver.stub'; -import { FileBackedHttpMetadataResolver } from '../../entity'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; - -@Component({ - template: `` -}) -class TestHostComponent { - - ids$: Observable = of(['foo']); - resolver = new FileBackedHttpMetadataResolver({ - ...stubs.resolver, - serviceProviderSsoDescriptor: { - protocolSupportEnum: 'foo', - nameIdFormats: [] - } - }); - - @ViewChild(AdvancedInfoFormComponent) - public formUnderTest: AdvancedInfoFormComponent; - - changeProvider(opts: any): void { - this.resolver = Object.assign({}, this.resolver, opts); - } - - addFormat(value: string): void { - this.resolver.serviceProviderSsoDescriptor.nameIdFormats.push(value); - } -} - - -describe('Advanced Info Form Component', () => { - let fixture: ComponentFixture; - let instance: TestHostComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - ProviderValueEmitter, - ProviderStatusEmitter, - NgbPopoverConfig - ], - imports: [ - NoopAnimationsModule, - ReactiveFormsModule, - MockI18nModule, - MockSharedModule - ], - declarations: [ - AdvancedInfoFormComponent, - TestHostComponent - ], - }); - - fixture = TestBed.createComponent(TestHostComponent); - instance = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('ngOnChanges method', () => { - it('should set properties on the resolver', () => { - instance.changeProvider(stubs.resolver); - fixture.detectChanges(); - expect(instance.formUnderTest.resolver.organization).toEqual({}); - expect(instance.formUnderTest.resolver.contacts).toEqual([]); - }); - }); - - describe('removeContact method', () => { - it('should remove the contact at the given index', () => { - instance.changeProvider({ - ...stubs.resolver, - contacts: [stubs.contact] - }); - fixture.detectChanges(); - instance.formUnderTest.removeContact(0); - expect(instance.formUnderTest.contacts.length).toBe(0); - }); - }); - - describe('addContact method', () => { - it('should remove the contact at the given index', () => { - instance.changeProvider({ - ...stubs.resolver, - contacts: [stubs.contact] - }); - fixture.detectChanges(); - instance.formUnderTest.addContact(); - expect(instance.formUnderTest.contacts.length).toBe(2); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/advanced-info-form.component.ts b/ui/src/app/metadata/domain/component/forms/advanced-info-form.component.ts deleted file mode 100644 index d0ce28c2c..000000000 --- a/ui/src/app/metadata/domain/component/forms/advanced-info-form.component.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy, EventEmitter } from '@angular/core'; -import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms'; -import { Observable, Subscription, of } from 'rxjs'; -import { takeUntil, switchMap, map, startWith } from 'rxjs/operators'; - -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { MetadataResolver, Contact } from '../../../domain/model'; -import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; -import { EntityValidators } from '../../../domain/service/entity-validators.service'; - -@Component({ - selector: 'adv-info-form', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './advanced-info-form.component.html' -}) -export class AdvancedInfoFormComponent extends ProviderFormFragmentComponent implements OnInit, OnChanges, OnDestroy { - @Input() resolver: MetadataResolver; - @Input() ids: Observable; - - contactTypes: string[] = [ - 'support', - 'technical', - 'administrative', - 'other' - ]; - - form: FormGroup; - - hasValue$: Observable; - totalValue$: Observable; - - private validationSubscription: Subscription; - - constructor( - protected fb: FormBuilder, - protected statusEmitter: ProviderStatusEmitter, - protected valueEmitter: ProviderValueEmitter - ) { - super(fb, statusEmitter, valueEmitter); - } - - createForm(): void { - let orgEmitter$ = this.valueEmitter.changeEmitted$.pipe( - takeUntil(this.ngUnsubscribe), - switchMap(changes => of(changes.organization)) - ); - this.form = this.fb.group({ - entityId: ['', Validators.required], - serviceProviderName: ['', Validators.required], - serviceEnabled: [false], - organization: this.fb.group({ - name: [''], - displayName: [''], - url: [''] - }, { asyncValidator: EntityValidators.createOrgValidator() }), - contacts: this.fb.array([]) - }); - } - - ngOnInit(): void { - super.ngOnInit(); - - this.hasValue$ = this.form - .get('organization') - .valueChanges.pipe( - startWith(this.form.get('organization').value), - map(values => Object.keys(values).reduce((coll, key) => coll + (values[key] || ''), '')), - map(value => !!value) - ); - - this.form - .get('entityId') - .setAsyncValidators( - EntityValidators.createUniqueIdValidator(this.ids) - ); - } - - ngOnChanges(): void { - this.resolver.organization = this.resolver.organization || {}; - this.resolver.contacts = this.resolver.contacts || []; - this.form.reset({ - serviceProviderName: this.resolver.serviceProviderName, - serviceEnabled: this.resolver.serviceEnabled, - entityId: this.resolver.entityId, - organization: this.resolver.organization - }); - this.setContacts(this.resolver.contacts); - } - - get contacts(): FormArray { - return this.form.get('contacts') as FormArray; - } - - setContacts(contacts: Contact[] = []): void { - let fgs = contacts.map(contact => this.getContact(contact)), - list = this.fb.array(fgs); - this.form.setControl('contacts', list); - } - - addContact(): void { - this.contacts.push(this.getContact()); - } - - getContact(contact: Contact = {} as Contact): FormGroup { - return this.fb.group({ - type: [contact.type || null, Validators.required], - name: [contact.name || null, Validators.required], - emailAddress: [contact.emailAddress || null, [Validators.required, Validators.email]] - }); - } - - removeContact(index: number): void { - this.contacts.removeAt(index); - } -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/component/forms/assertion-form.component.html b/ui/src/app/metadata/domain/component/forms/assertion-form.component.html deleted file mode 100644 index 8cf76147a..000000000 --- a/ui/src/app/metadata/domain/component/forms/assertion-form.component.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - Assertion Consumer Service Endpoints: - - Add Endpoint - - - - - - - - - - - {{ endpoint.get('locationUrl').value }} - New Endpoint - {{ i }} - - - (default) - - - - - - - - - - - - - - Assertion Consumer Service Location - - - - - - - - Must be a valid URL - - - - - - - - Assertion Consumer Service Location Binding - - - - - - - Select Binding Type - - {{ opt }} - - - - - - - - - Mark as Default - - - - - Yes - - - - - - - - - - - - diff --git a/ui/src/app/metadata/domain/component/forms/assertion-form.component.spec.ts b/ui/src/app/metadata/domain/component/forms/assertion-form.component.spec.ts deleted file mode 100644 index fafa644c2..000000000 --- a/ui/src/app/metadata/domain/component/forms/assertion-form.component.spec.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { AssertionFormComponent } from './assertion-form.component'; -import * as stubs from '../../../../../testing/resolver.stub'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; - -describe('Assertion Form Component', () => { - let fixture: ComponentFixture; - let instance: AssertionFormComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - ProviderValueEmitter, - ProviderStatusEmitter, - NgbPopoverConfig - ], - imports: [ - NoopAnimationsModule, - ReactiveFormsModule, - MockSharedModule, - MockI18nModule - ], - declarations: [ - AssertionFormComponent - ], - }); - - fixture = TestBed.createComponent(AssertionFormComponent); - instance = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('ngOnChanges method', () => { - it('should set properties on the provider', () => { - instance.resolver = stubs.resolver; - fixture.detectChanges(); - instance.ngOnChanges(); - expect(instance.resolver.assertionConsumerServices).toEqual([]); - }); - }); - - describe('removeEndpoint method', () => { - it('should remove the endpoint at the given index', () => { - instance.resolver = { - ...stubs.resolver, - assertionConsumerServices: [stubs.endpoint] - }; - fixture.detectChanges(); - instance.ngOnChanges(); - instance.removeEndpoint(0); - expect(instance.assertionConsumerServices.length).toBe(0); - }); - }); - - describe('addEndpoint method', () => { - it('should remove the endpoint at the given index', () => { - instance.resolver = { - ...stubs.resolver, - assertionConsumerServices: [stubs.endpoint] - }; - fixture.detectChanges(); - instance.ngOnChanges(); - instance.addEndpoint(); - expect(instance.assertionConsumerServices.length).toBe(2); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/assertion-form.component.ts b/ui/src/app/metadata/domain/component/forms/assertion-form.component.ts deleted file mode 100644 index a3ce408b8..000000000 --- a/ui/src/app/metadata/domain/component/forms/assertion-form.component.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; -import { FormBuilder, FormGroup, FormArray, AbstractControl } from '@angular/forms'; - -import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; - -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { SsoService, MetadataResolver } from '../../../domain/model/'; - -@Component({ - selector: 'assertion-form', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './assertion-form.component.html' -}) -export class AssertionFormComponent extends ProviderFormFragmentComponent implements OnInit, OnChanges, OnDestroy { - @Input() resolver: MetadataResolver; - - form: FormGroup; - - bindingTypes: string[] = [ - 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', - 'urn:oasis:names:tc:SAML:1.0:profiles:browser-post' - ]; - - constructor( - protected fb: FormBuilder, - protected statusEmitter: ProviderStatusEmitter, - protected valueEmitter: ProviderValueEmitter - ) { - super(fb, statusEmitter, valueEmitter); - } - - createForm(): void { - this.form = this.fb.group({ - assertionConsumerServices: this.fb.array([]) - }); - } - - get assertionConsumerServices(): FormArray { - return this.form.get('assertionConsumerServices') as FormArray; - } - - setEndpoints(endpoints: SsoService[] = []): void { - let fgs = endpoints.map(ep => this.fb.group(ep)), - list = this.fb.array(fgs); - this.form.setControl('assertionConsumerServices', list); - } - - addEndpoint(): void { - this.assertionConsumerServices.push(this.fb.group({ - binding: null, - locationUrl: [''], - makeDefault: false - })); - } - - removeEndpoint(index: number): void { - this.assertionConsumerServices.removeAt(index); - } - - markAsDefault(endpoint: AbstractControl): void { - this.assertionConsumerServices.controls.forEach(element => { - element.patchValue({ - makeDefault: (endpoint === element) ? !endpoint.get('makeDefault').value : false - }); - }); - this.assertionConsumerServices.updateValueAndValidity(); - } - - ngOnChanges(): void { - this.resolver.assertionConsumerServices = this.resolver.assertionConsumerServices || []; - this.setEndpoints(this.resolver.assertionConsumerServices); - } -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/component/forms/attribute-release-form.component.html b/ui/src/app/metadata/domain/component/forms/attribute-release-form.component.html deleted file mode 100644 index 9ee740517..000000000 --- a/ui/src/app/metadata/domain/component/forms/attribute-release-form.component.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - Attribute Name - Yes - - - - - {{ attr.label }} - - - - - - - - - - - Check All Attributes - - - - Check All Attributes - - - - - Clear All Attributes - - - - Clear All Attributes - - - - - - - - \ No newline at end of file diff --git a/ui/src/app/metadata/domain/component/forms/attribute-release-form.component.spec.ts b/ui/src/app/metadata/domain/component/forms/attribute-release-form.component.spec.ts deleted file mode 100644 index 9f9e3f04a..000000000 --- a/ui/src/app/metadata/domain/component/forms/attribute-release-form.component.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { StoreModule, Store, combineReducers } from '@ngrx/store'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { AttributeReleaseFormComponent } from './attribute-release-form.component'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import * as stubs from '../../../../../testing/resolver.stub'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockListValueService } from '../../../../../testing/list-values.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; - -describe('Attribute Release Form Component', () => { - let fixture: ComponentFixture; - let instance: AttributeReleaseFormComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - ProviderValueEmitter, - ProviderStatusEmitter, - NgbPopoverConfig, - { provide: ListValuesService, useClass: MockListValueService } - ], - imports: [ - NoopAnimationsModule, - ReactiveFormsModule, - MockSharedModule, - MockI18nModule - ], - declarations: [ - AttributeReleaseFormComponent - ], - }); - - fixture = TestBed.createComponent(AttributeReleaseFormComponent); - instance = fixture.componentInstance; - instance.resolver = { - ...stubs.resolver, - attributeRelease: [] - }; - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('ngOnChanges method', () => { - it('should set properties on the provider', () => { - spyOn(instance, 'setAttributes'); - instance.ngOnChanges(); - expect(instance.resolver.attributeRelease).toEqual([]); - expect(instance.setAttributes).toHaveBeenCalled(); - }); - }); - - describe('onCheck method', () => { - it('should add the attribute to the list if checked', () => { - instance.onCheck({ target: { checked: true } }, 'foo'); - expect(instance.attributeRelease.length).toBe(1); - }); - it('should remove the attribute if not checked', () => { - spyOn(instance.attributeRelease, 'removeAt').and.callThrough(); - instance.onCheck({ target: { checked: false } }, 'foo'); - expect(instance.attributeRelease.removeAt).toHaveBeenCalled(); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/attribute-release-form.component.ts b/ui/src/app/metadata/domain/component/forms/attribute-release-form.component.ts deleted file mode 100644 index 8a7d3a258..000000000 --- a/ui/src/app/metadata/domain/component/forms/attribute-release-form.component.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { Component, Output, Input, EventEmitter, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; -import { FormBuilder, FormGroup } from '@angular/forms'; -import { Observable } from 'rxjs'; -import { last } from 'rxjs/operators'; - -import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { MetadataResolver } from '../../../domain/model'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import { FormArray } from '@angular/forms/src/model'; - - -@Component({ - selector: 'attribute-release-form', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './attribute-release-form.component.html' -}) -export class AttributeReleaseFormComponent extends ProviderFormFragmentComponent implements OnInit, OnChanges, OnDestroy { - @Input() resolver: MetadataResolver; - - form: FormGroup; - attributesToRelease: any[]; - listOfAttributes$: Observable<{ key: string, label: string }[]>; - - constructor( - protected fb: FormBuilder, - protected statusEmitter: ProviderStatusEmitter, - protected valueEmitter: ProviderValueEmitter, - protected listService: ListValuesService - ) { - super(fb, statusEmitter, valueEmitter); - } - - createForm(): void { - this.form = this.fb.group({ - attributeRelease: this.fb.array([]) - }); - } - - ngOnInit(): void { - super.ngOnInit(); - this.listOfAttributes$ = this.listService.attributesToRelease; - } - - ngOnChanges(): void { - this.resolver.attributeRelease = this.resolver.attributeRelease || []; - this.setAttributes(this.resolver.attributeRelease); - } - - get attributeRelease(): FormArray { - return this.form.get('attributeRelease') as FormArray; - } - - isChecked(attr): boolean { - return this.attributeRelease.controls.findIndex(control => control.value === attr) > -1; - } - - setAttributes(list: string[] = []): void { - let attrs = list.map(attr => this.fb.control(attr)); - const fbarray = this.fb.array(attrs); - this.form.setControl('attributeRelease', fbarray); - } - - onCheck($event, attr: string): void { - const checked = $event ? $event.target.checked : true; - if (checked) { - this.attributeRelease.push(this.fb.control(attr)); - } else { - const index = this.attributeRelease.controls.findIndex(control => control.value === attr); - this.attributeRelease.removeAt(index); - } - } - - onCheckAll(): void { - this.onCheckNone(); - this.listOfAttributes$.pipe(last()).subscribe(attrs => { - attrs.forEach(attr => this.onCheck(null, attr.key)); - }); - } - onCheckNone(event: Event | null = null): void { - if (event) { - event.preventDefault(); - } - while (this.attributeRelease.controls.length !== 0) { - this.attributeRelease.removeAt(0); - } - } -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/component/forms/descriptor-info-form.component.html b/ui/src/app/metadata/domain/component/forms/descriptor-info-form.component.html deleted file mode 100644 index 6aac2a7b4..000000000 --- a/ui/src/app/metadata/domain/component/forms/descriptor-info-form.component.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - Protocol Support Enumeration - - - - - - - Select Protocol - {{ opt }} - - - - - - NameID Format - Add NameID Format - - - - - - - - - - - NameID Format {{ i + 1 }}. - - - - - - - - - - - - - - diff --git a/ui/src/app/metadata/domain/component/forms/descriptor-info-form.component.spec.ts b/ui/src/app/metadata/domain/component/forms/descriptor-info-form.component.spec.ts deleted file mode 100644 index 1481a0638..000000000 --- a/ui/src/app/metadata/domain/component/forms/descriptor-info-form.component.spec.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Component, ViewChild } from '@angular/core'; -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import { FileBackedHttpMetadataResolver } from '../../../domain/entity'; -import { DescriptorInfoFormComponent } from './descriptor-info-form.component'; - -import * as stubs from '../../../../../testing/resolver.stub'; -import { SharedModule } from '../../../../shared/shared.module'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockListValueService } from '../../../../../testing/list-values.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; - -@Component({ - template: `` -}) -class TestHostComponent { - resolver = new FileBackedHttpMetadataResolver({ - ...stubs.resolver, - serviceProviderSsoDescriptor: { - protocolSupportEnum: 'foo', - nameIdFormats: [] - } - }); - - @ViewChild(DescriptorInfoFormComponent) - public formUnderTest: DescriptorInfoFormComponent; - - changeProvider(opts: any): void { - this.resolver = Object.assign({}, this.resolver, opts); - } - - addFormat(value: string): void { - this.resolver.serviceProviderSsoDescriptor.nameIdFormats.push(value); - } -} - -describe('Descriptor Info Form Component', () => { - let fixture: ComponentFixture; - let instance: TestHostComponent; - let form: DescriptorInfoFormComponent; - let fb: FormBuilder; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - ProviderValueEmitter, - ProviderStatusEmitter, - NgbPopoverConfig, - { provide: ListValuesService, useClass: MockListValueService } - ], - imports: [ - NoopAnimationsModule, - ReactiveFormsModule, - MockSharedModule, - MockI18nModule - ], - declarations: [ - DescriptorInfoFormComponent, - TestHostComponent - ], - }); - - fixture = TestBed.createComponent(TestHostComponent); - instance = fixture.componentInstance; - form = instance.formUnderTest; - fb = TestBed.get(FormBuilder); - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('removeFormat method', () => { - it('should remove the nameid format at the given index', () => { - instance.addFormat('foo'); - fixture.detectChanges(); - form.removeFormat(0); - fixture.detectChanges(); - expect(form.nameIdFormats.length).toBe(0); - }); - }); - - describe('addFormat method', () => { - it('should add a new nameid format', () => { - form.addFormat(); - fixture.detectChanges(); - expect(form.nameIdFormats.length).toBe(1); - }); - }); - - describe('getRequiredControl method', () => { - it('should create a form control with the required validator attached', () => { - spyOn(fb, 'control').and.callThrough(); - form.getRequiredControl('foo'); - expect(fb.control).toHaveBeenCalledWith('foo', Validators.required); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/descriptor-info-form.component.ts b/ui/src/app/metadata/domain/component/forms/descriptor-info-form.component.ts deleted file mode 100644 index 89a824bc5..000000000 --- a/ui/src/app/metadata/domain/component/forms/descriptor-info-form.component.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; -import { FormBuilder, FormGroup, FormControl, FormArray, Validators } from '@angular/forms'; -import { Observable, of } from 'rxjs'; - -import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; - -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { MetadataResolver } from '../../../domain/model'; -import { ListValuesService } from '../../../domain/service/list-values.service'; - -@Component({ - selector: 'descriptor-info-form', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './descriptor-info-form.component.html' -}) -export class DescriptorInfoFormComponent extends ProviderFormFragmentComponent implements OnInit, OnChanges, OnDestroy { - @Input() resolver: MetadataResolver; - - form: FormGroup; - - nameIdFormatOptions: Observable = this.listValues.nameIdFormats; - - enumOptions: string[] = [ - 'SAML 2', - 'SAML 1.1' - ]; - - nameIds$: Observable = of([]); - - constructor( - protected fb: FormBuilder, - protected statusEmitter: ProviderStatusEmitter, - protected valueEmitter: ProviderValueEmitter, - private listValues: ListValuesService - ) { - super(fb, statusEmitter, valueEmitter); - } - - createForm(): void { - this.form = this.fb.group({ - serviceProviderSsoDescriptor: this.fb.group({ - protocolSupportEnum: null, - nameIdFormats: this.fb.array([]) - }) - }); - } - - ngOnChanges(): void { - let descriptor = this.resolver.serviceProviderSsoDescriptor; - this.form.reset({ - serviceProviderSsoDescriptor: descriptor || {} - }); - this.setNameIdFormats(descriptor ? descriptor.nameIdFormats : []); - } - - get nameIdFormats(): FormArray { - return this.form.get('serviceProviderSsoDescriptor.nameIdFormats') as FormArray; - } - - getRequiredControl = (name: string): FormControl => this.fb.control(name, Validators.required); - - setNameIdFormats(nameIdFormats: string[]): void { - let fcs = nameIdFormats.map(this.getRequiredControl), - list = this.fb.array(fcs), - group = this.form.get('serviceProviderSsoDescriptor') as FormGroup; - group.setControl('nameIdFormats', list); - } - - addFormat(text: string = ''): void { - this.nameIdFormats.push(this.fb.control(text, Validators.required)); - } - - removeFormat(index: number): void { - this.nameIdFormats.removeAt(index); - } - - updateOptions(query: string): void { - this.nameIds$ = this.listValues.searchFormats(of(query)); - } - -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/component/forms/key-info-form.component.html b/ui/src/app/metadata/domain/component/forms/key-info-form.component.html deleted file mode 100644 index 6222434db..000000000 --- a/ui/src/app/metadata/domain/component/forms/key-info-form.component.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - - - Is there a X509 Certificate? - - - - - - - - - Yes - - - - No - - - - - - - - - Authentication Requests Signed? - - - - - - - - - Yes - - - - No - - - - - - - - - Want Assertions Signed? - - - - - - - - - Yes - - - - No - - - - - - - - X509 Certificates: - Add Certificate - - - - - - - - - - {{ cert.get('name').value }} - New Certificate - - () - - - - - - - - - - - - - - - - - Certificate Name (Display Only) - - - - - - - - - - - - - - - Type - - - - - - - - - - - - - - - - - - - - - - Certificate - - - - - - - - - - - - - - - - diff --git a/ui/src/app/metadata/domain/component/forms/key-info-form.component.spec.ts b/ui/src/app/metadata/domain/component/forms/key-info-form.component.spec.ts deleted file mode 100644 index bdb50a4ed..000000000 --- a/ui/src/app/metadata/domain/component/forms/key-info-form.component.spec.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { Component, ViewChild } from '@angular/core'; -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import { KeyInfoFormComponent } from './key-info-form.component'; - -import * as stubs from '../../../../../testing/resolver.stub'; -import { FileBackedHttpMetadataResolver } from '../../entity'; -import { InputDefaultsDirective } from '../../../../shared/directive/input-defaults.directive'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockListValueService } from '../../../../../testing/list-values.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; - -@Component({ - template: `` -}) -class TestHostComponent { - resolver = new FileBackedHttpMetadataResolver({ - ...stubs.resolver, - securityInfo: { - ...stubs.secInfo, - x509Certificates: [] - } - }); - - @ViewChild(KeyInfoFormComponent) - public formUnderTest: KeyInfoFormComponent; - - changeProvider(opts: any): void { - this.resolver = Object.assign({}, this.resolver, opts); - } -} - -describe('Security (Key) Info Form Component', () => { - let fixture: ComponentFixture; - let instance: TestHostComponent; - let form: KeyInfoFormComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - ProviderValueEmitter, - ProviderStatusEmitter, - NgbPopoverConfig, - { provide: ListValuesService, useClass: MockListValueService } - ], - imports: [ - NoopAnimationsModule, - ReactiveFormsModule, - MockSharedModule, - MockI18nModule - ], - declarations: [ - KeyInfoFormComponent, - TestHostComponent, - InputDefaultsDirective - ], - }).compileComponents(); - - fixture = TestBed.createComponent(TestHostComponent); - instance = fixture.componentInstance; - form = instance.formUnderTest; - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('removeCert method', () => { - it('should remove the certificate at the given index', () => { - instance.changeProvider({ - securityInfo: { - ...stubs.secInfo, - x509CertificateAvailable: true, - x509Certificates: [stubs.certificate] - } - }); - fixture.detectChanges(); - form.removeCert(0); - fixture.detectChanges(); - expect(form.x509Certificates.length).toBe(0); - }); - }); - - describe('addCert method', () => { - it('should remove the certificate at the given index', () => { - instance.changeProvider({ - securityInfo: { - ...stubs.secInfo, - x509CertificateAvailable: true - } - }); - fixture.detectChanges(); - form.addCert(); - fixture.detectChanges(); - expect(form.x509Certificates.length).toBe(1); - }); - }); - - describe('ngOnInit method', () => { - it('should remove certificates if there are none available', () => { - instance.changeProvider({ - securityInfo: { - ...stubs.secInfo, - x509Certificates: [stubs.certificate] - } - }); - fixture.detectChanges(); - expect(form.x509Certificates.length).toBe(0); - }); - }); - - describe('createGroup method', () => { - it('should return a FormGroup with the correct attributes', () => { - let group = form.createGroup(); - expect(Object.keys(group.controls)).toEqual(['name', 'type', 'value']); - }); - - it('should return a FormGroup with the provided attributes', () => { - let group = form.createGroup({ - name: 'foo', - type: 'signing', - value: 'bar' - }); - let controls = group.controls; - expect(controls.name.value).toEqual('foo'); - expect(controls.type.value).toEqual('signing'); - expect(controls.value.value).toEqual('bar'); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/key-info-form.component.ts b/ui/src/app/metadata/domain/component/forms/key-info-form.component.ts deleted file mode 100644 index 882b7c330..000000000 --- a/ui/src/app/metadata/domain/component/forms/key-info-form.component.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; -import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms'; -import { Observable } from 'rxjs'; -import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators'; - -import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { MetadataResolver, Certificate } from '../../../domain/model'; - -@Component({ - selector: 'key-info-form', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './key-info-form.component.html' -}) -export class KeyInfoFormComponent extends ProviderFormFragmentComponent implements OnInit, OnChanges, OnDestroy { - @Input() resolver: MetadataResolver; - - hasCert$: Observable; - - form: FormGroup; - - types: string[] = [ - 'signing', - 'encryption', - 'both' - ]; - - constructor( - protected fb: FormBuilder, - protected statusEmitter: ProviderStatusEmitter, - protected valueEmitter: ProviderValueEmitter - ) { - super(fb, statusEmitter, valueEmitter); - } - - createForm(): void { - this.form = this.fb.group({ - securityInfo: this.fb.group({ - x509CertificateAvailable: [false], - authenticationRequestsSigned: [false], - wantAssertionsSigned: [false], - x509Certificates: this.fb.array([]) - }) - }); - } - - get x509Certificates(): FormArray { - return this.form.get('securityInfo.x509Certificates') as FormArray; - } - - createGroup(values: Certificate = {name: '', type: 'both', value: ''}): FormGroup { - return this.fb.group({ - name: [values.name || '', Validators.required], - type: [values.type || 'both', Validators.required], - value: [values.value || '', Validators.required] - }); - } - - setCertificates(certs: Certificate[] = []): void { - let fgs = certs.map(ep => this.createGroup(ep)), - list = this.fb.array(fgs, Validators.minLength(1)), - group = this.form.get('securityInfo') as FormGroup; - group.setControl('x509Certificates', list); - } - - addCert(): void { - this.x509Certificates.push(this.createGroup()); - } - - removeCert(index: number): void { - this.x509Certificates.removeAt(index); - } - - ngOnInit(): void { - super.ngOnInit(); - this.hasCert$ = this.form.valueChanges.pipe( - distinctUntilChanged(), - map(values => values.securityInfo.x509CertificateAvailable) - ); - - this.hasCert$.pipe( - takeUntil(this.ngUnsubscribe), - distinctUntilChanged() - ).subscribe(hasCert => { - if (hasCert && !this.x509Certificates.length) { - this.addCert(); - this.x509Certificates.setValidators(Validators.minLength(1)); - this.x509Certificates.updateValueAndValidity(); - } - if (!hasCert) { - while (this.x509Certificates.controls.length !== 0) { - this.removeCert(0); - } - } - }); - } - - ngOnChanges(): void { - this.form.reset({ - securityInfo: this.resolver.securityInfo || { - x509CertificateAvailable: false, - authenticationRequestsSigned: false, - wantAssertionsSigned: false - } - }); - if (this.resolver.securityInfo && this.resolver.securityInfo.x509CertificateAvailable) { - this.setCertificates(this.resolver.securityInfo.x509Certificates); - } - } -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/component/forms/logout-form.component.html b/ui/src/app/metadata/domain/component/forms/logout-form.component.html deleted file mode 100644 index cf1f091ba..000000000 --- a/ui/src/app/metadata/domain/component/forms/logout-form.component.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - Logout Endpoints: - Add Endpoint - - - - - - - - - - {{ endpoint.get('url').value }} - New Endpoint - - - - - - - - - - - - - - - URL - - - - - - - Must be a valid URL - - - - - Binding Type - - - - - - - Select Binding Type - {{ opt }} - - - - - - - - - diff --git a/ui/src/app/metadata/domain/component/forms/logout-form.component.spec.ts b/ui/src/app/metadata/domain/component/forms/logout-form.component.spec.ts deleted file mode 100644 index dc13075a8..000000000 --- a/ui/src/app/metadata/domain/component/forms/logout-form.component.spec.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { ViewChild, Component } from '@angular/core'; -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import { LogoutFormComponent } from './logout-form.component'; - -import * as stubs from '../../../../../testing/resolver.stub'; -import { FileBackedHttpMetadataResolver } from '../../entity'; -import { InputDefaultsDirective } from '../../../../shared/directive/input-defaults.directive'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockListValueService } from '../../../../../testing/list-values.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; - -@Component({ - template: `` -}) -class TestHostComponent { - resolver = new FileBackedHttpMetadataResolver({ - ...stubs.resolver, - logoutEndpoints: [stubs.logoutEndpoint] - }); - - @ViewChild(LogoutFormComponent) - public formUnderTest: LogoutFormComponent; - - changeProvider(opts: any): void { - this.resolver = Object.assign({}, this.resolver, opts); - } -} - -describe('Logout Endpoints Form Component', () => { - let fixture: ComponentFixture; - let instance: TestHostComponent; - let form: LogoutFormComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - ProviderValueEmitter, - ProviderStatusEmitter, - NgbPopoverConfig, - { provide: ListValuesService, useClass: MockListValueService } - ], - imports: [ - NoopAnimationsModule, - ReactiveFormsModule, - MockSharedModule, - MockI18nModule - ], - declarations: [ - LogoutFormComponent, - TestHostComponent, - InputDefaultsDirective - ], - }); - - fixture = TestBed.createComponent(TestHostComponent); - instance = fixture.componentInstance; - form = instance.formUnderTest; - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('ngOnInit method', () => { - it('should remove endpoints if there are none available', () => { - instance.changeProvider({ - logoutEndpoints: [] - }); - fixture.detectChanges(); - expect(form.logoutEndpoints.length).toBe(0); - }); - }); - - describe('ngOnChanges method', () => { - it('should add endpoints if provided', () => { - instance.resolver = new FileBackedHttpMetadataResolver({ - ...stubs.resolver - }); - fixture.detectChanges(); - expect(form.logoutEndpoints.length).toBe(0); - }); - }); - - describe('setEndpoints method', () => { - it('should add endpoints if provided', () => { - form.setEndpoints(); - fixture.detectChanges(); - expect(form.form.get('logoutEndpoints')).toBeDefined(); - }); - }); - - describe('removeCert method', () => { - it('should remove the endpoint at the given index', () => { - instance.changeProvider({ - logoutEndpoints: [stubs.endpoint] - }); - fixture.detectChanges(); - form.removeEndpoint(0); - fixture.detectChanges(); - expect(form.logoutEndpoints.length).toBe(0); - }); - }); - - describe('addCert method', () => { - it('should remove the endpoint at the given index', () => { - instance.changeProvider({ - logoutEndpoints: [] - }); - fixture.detectChanges(); - form.addEndpoint(); - fixture.detectChanges(); - expect(form.logoutEndpoints.length).toBe(1); - }); - }); - - describe('createGroup method', () => { - it('should return a FormGroup with the correct attributes', () => { - let group = form.createGroup(); - expect(Object.keys(group.controls)).toEqual(['url', 'bindingType']); - }); - - it('should return a FormGroup with the provided attributes', () => { - let group = form.createGroup({ - url: 'foo', - bindingType: 'bar' - }); - let controls = group.controls; - expect(controls.url.value).toEqual('foo'); - expect(controls.bindingType.value).toEqual('bar'); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/logout-form.component.ts b/ui/src/app/metadata/domain/component/forms/logout-form.component.ts deleted file mode 100644 index 60b3b5f80..000000000 --- a/ui/src/app/metadata/domain/component/forms/logout-form.component.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; -import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms'; - -import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { MetadataResolver, LogoutEndpoint } from '../../../domain/model'; - -@Component({ - selector: 'logout-form', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './logout-form.component.html' -}) -export class LogoutFormComponent extends ProviderFormFragmentComponent implements OnInit, OnChanges, OnDestroy { - @Input() resolver: MetadataResolver; - - form: FormGroup; - - bindingTypes: string[] = [ - 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', - 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect' - ]; - - constructor( - protected fb: FormBuilder, - protected statusEmitter: ProviderStatusEmitter, - protected valueEmitter: ProviderValueEmitter - ) { - super(fb, statusEmitter, valueEmitter); - } - - createForm(): void { - this.form = this.fb.group({ - logoutEndpoints: this.fb.array([]) - }); - } - - createGroup(ep: LogoutEndpoint = { url: '', bindingType: null }): FormGroup { - return this.fb.group({ - url: [ep.url || '', Validators.required], - bindingType: [ep.bindingType || null, Validators.required] - }); - } - - get logoutEndpoints(): FormArray { - return this.form.get('logoutEndpoints') as FormArray; - } - - setEndpoints(endpoints: LogoutEndpoint[] = []): void { - let fgs = endpoints.map(ep => this.createGroup(ep)), - list = this.fb.array(fgs); - this.form.setControl('logoutEndpoints', list); - } - - addEndpoint(): void { - this.logoutEndpoints.push(this.createGroup()); - } - - removeEndpoint(index: number): void { - this.logoutEndpoints.removeAt(index); - } - - ngOnChanges(): void { - this.resolver.logoutEndpoints = this.resolver.logoutEndpoints || []; - this.setEndpoints(this.resolver.logoutEndpoints); - } -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/component/forms/metadata-ui-form.component.html b/ui/src/app/metadata/domain/component/forms/metadata-ui-form.component.html deleted file mode 100644 index 44954aa1d..000000000 --- a/ui/src/app/metadata/domain/component/forms/metadata-ui-form.component.html +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - Display Name - - - - - - - - - - - Information URL - - - - - - - Must be a valid URL - - - - - Description - - - - - - - - - {{ form.get('mdui.description').value ? form.get('mdui.description').value.length : '0' }} - - / - {{ descriptionMaxLength }} - - - - - - - - Privacy Statement URL - - - - - - - Must be a valid URL - - - - - Logo URL - - - - - - - Must be a valid URL - - - - - - - Logo Width - - - - - - - Must be an integer equal to or greater than 0 - - - - - - - Logo Height - - - - - - - Must be an integer equal to or greater than 0 - - - - - - diff --git a/ui/src/app/metadata/domain/component/forms/metadata-ui-form.component.spec.ts b/ui/src/app/metadata/domain/component/forms/metadata-ui-form.component.spec.ts deleted file mode 100644 index a09b3bd66..000000000 --- a/ui/src/app/metadata/domain/component/forms/metadata-ui-form.component.spec.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { ViewChild, Component, Input } from '@angular/core'; -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import { MetadataUiFormComponent } from './metadata-ui-form.component'; - -import * as stubs from '../../../../../testing/resolver.stub'; -import { FileBackedHttpMetadataResolver } from '../../entity'; -import { InputDefaultsDirective } from '../../../../shared/directive/input-defaults.directive'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockListValueService } from '../../../../../testing/list-values.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; - -@Component({ - template: `` -}) -class TestHostComponent { - resolver = new FileBackedHttpMetadataResolver({ - ...stubs.resolver - }); - - @ViewChild(MetadataUiFormComponent) - public formUnderTest: MetadataUiFormComponent; - - changeProvider(opts: any): void { - this.resolver = Object.assign({}, this.resolver, opts); - } -} - -describe('Metadata UI Form Component', () => { - let fixture: ComponentFixture; - let instance: TestHostComponent; - let form: MetadataUiFormComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - ProviderValueEmitter, - ProviderStatusEmitter, - NgbPopoverConfig, - { provide: ListValuesService, useClass: MockListValueService } - ], - imports: [ - NoopAnimationsModule, - ReactiveFormsModule, - MockSharedModule, - MockI18nModule - ], - declarations: [ - MetadataUiFormComponent, - TestHostComponent, - InputDefaultsDirective - ], - }); - - fixture = TestBed.createComponent(TestHostComponent); - instance = fixture.componentInstance; - form = instance.formUnderTest; - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('ngOnChanges lifecycle event', () => { - it('should set the mdui data with a default object when one is not provided', () => { - spyOn(form.form, 'reset'); - instance.changeProvider({}); - fixture.detectChanges(); - expect(form.form.reset).toHaveBeenCalledWith({mdui: {}}); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/metadata-ui-form.component.ts b/ui/src/app/metadata/domain/component/forms/metadata-ui-form.component.ts deleted file mode 100644 index bde640cfc..000000000 --- a/ui/src/app/metadata/domain/component/forms/metadata-ui-form.component.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; -import { FormBuilder, Validators } from '@angular/forms'; -import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { MetadataResolver } from '../../../domain/model'; -import * as patterns from '../../../../shared/regex'; - -@Component({ - selector: 'metadata-ui-form', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './metadata-ui-form.component.html' -}) -export class MetadataUiFormComponent extends ProviderFormFragmentComponent implements OnInit, OnChanges, OnDestroy { - @Input() resolver: MetadataResolver; - - descriptionMaxLength = this.defaultMaxLength; - - constructor( - protected fb: FormBuilder, - protected statusEmitter: ProviderStatusEmitter, - protected valueEmitter: ProviderValueEmitter - ) { - super(fb, statusEmitter, valueEmitter); - } - - createForm(): void { - this.form = this.fb.group({ - mdui: this.fb.group({ - displayName: '', - informationUrl: [''], - privacyStatementUrl: [''], - description: '', - logoUrl: [''], - logoHeight: [0, [Validators.min(0), Validators.pattern(patterns.INTEGER_REGEX)]], - logoWidth: [0, [Validators.min(0), Validators.pattern(patterns.INTEGER_REGEX)]] - }) - }); - } - - ngOnChanges(): void { - this.form.reset({ - mdui: this.resolver.mdui || {} - }); - } -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/component/forms/organization-info-form.component.html b/ui/src/app/metadata/domain/component/forms/organization-info-form.component.html deleted file mode 100644 index eab15cabf..000000000 --- a/ui/src/app/metadata/domain/component/forms/organization-info-form.component.html +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - Organization Name - - - - - - - - - - - - - - Organization Display Name - - - - - - - - - - - - - - Organization URL - - - - - - - - - Must be a valid URL - - - * These three fields must all be entered if any single field has a value. - - - - - Contact Information: - Add Contact - - - - - - - - - {{ contact.get('name').value || 'New Contact' }} - - ({{ contact.get('type').value }}) - - - - - - - - - - - - - - - - - Contact Name - - - - - - - - - - - - - Contact Type - - - - - - - Select Contact Type - - {{ opt }} - - - - - - - - - - - Contact Email Address - - - - - - - - Must be a valid Email Address - - - - - - - - - - - diff --git a/ui/src/app/metadata/domain/component/forms/organization-info-form.component.spec.ts b/ui/src/app/metadata/domain/component/forms/organization-info-form.component.spec.ts deleted file mode 100644 index c30c63f56..000000000 --- a/ui/src/app/metadata/domain/component/forms/organization-info-form.component.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import { OrganizationInfoFormComponent } from './organization-info-form.component'; -import * as stubs from '../../../../../testing/resolver.stub'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockListValueService } from '../../../../../testing/list-values.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; - -describe('Organization Info Form Component', () => { - let fixture: ComponentFixture; - let instance: OrganizationInfoFormComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - ProviderValueEmitter, - ProviderStatusEmitter, - NgbPopoverConfig, - { provide: ListValuesService, useClass: MockListValueService } - ], - imports: [ - NoopAnimationsModule, - ReactiveFormsModule, - MockSharedModule, - MockI18nModule - ], - declarations: [ - OrganizationInfoFormComponent - ], - }); - - fixture = TestBed.createComponent(OrganizationInfoFormComponent); - instance = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('ngOnChanges method', () => { - it('should set properties on the provider', () => { - instance.resolver = stubs.resolver; - fixture.detectChanges(); - instance.ngOnChanges(); - expect(instance.resolver.organization).toEqual({}); - expect(instance.resolver.contacts).toEqual([]); - }); - }); - - describe('removeContact method', () => { - it('should remove the contact at the given index', () => { - instance.resolver = { - ...stubs.resolver, - contacts: [stubs.contact] - }; - fixture.detectChanges(); - instance.ngOnChanges(); - instance.removeContact(0); - expect(instance.contacts.length).toBe(0); - }); - }); - - describe('addContact method', () => { - it('should remove the contact at the given index', () => { - instance.resolver = { - ...stubs.resolver, - contacts: [stubs.contact] - }; - fixture.detectChanges(); - instance.ngOnChanges(); - instance.addContact(); - expect(instance.contacts.length).toBe(2); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/organization-info-form.component.ts b/ui/src/app/metadata/domain/component/forms/organization-info-form.component.ts deleted file mode 100644 index 6051e4bbb..000000000 --- a/ui/src/app/metadata/domain/component/forms/organization-info-form.component.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy, EventEmitter } from '@angular/core'; -import { FormBuilder, FormGroup, FormControl, FormArray, Validators } from '@angular/forms'; -import { Observable, Subscription } from 'rxjs'; -import { startWith, map } from 'rxjs/operators'; - -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { MetadataResolver, Contact } from '../../../domain/model'; -import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; -import { EntityValidators } from '../../../domain/service/entity-validators.service'; - -@Component({ - selector: 'org-info-form', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './organization-info-form.component.html' -}) -export class OrganizationInfoFormComponent extends ProviderFormFragmentComponent implements OnInit, OnChanges, OnDestroy { - @Input() resolver: MetadataResolver; - - contactTypes: string[] = [ - 'support', - 'technical', - 'administrative', - 'other' - ]; - - form: FormGroup; - - hasValue$: Observable; - totalValue$: Observable; - - private validationSubscription: Subscription; - - constructor( - protected fb: FormBuilder, - protected statusEmitter: ProviderStatusEmitter, - protected valueEmitter: ProviderValueEmitter - ) { - super(fb, statusEmitter, valueEmitter); - } - - createForm(): void { - this.form = this.fb.group({ - organization: this.fb.group({ - name: [''], - displayName: [''], - url: [''] - }, { asyncValidator: EntityValidators.createOrgValidator() }), - contacts: this.fb.array([]) - }); - } - - ngOnInit(): void { - super.ngOnInit(); - this.hasValue$ = this.form.get('organization').valueChanges.pipe( - startWith(this.form.get('organization').value), - map(values => Object.keys(values).reduce((coll, key) => coll + (values[key] || ''), '')), - map(value => !!value) - ); - } - - ngOnChanges(): void { - this.resolver.organization = this.resolver.organization || {}; - this.resolver.contacts = this.resolver.contacts || []; - this.form.reset({ - organization: this.resolver.organization - }); - this.setContacts(this.resolver.contacts); - } - - get contacts(): FormArray { - return this.form.get('contacts') as FormArray; - } - - setContacts(contacts: Contact[] = []): void { - let fgs = contacts.map(contact => this.getContact(contact)), - list = this.fb.array(fgs); - this.form.setControl('contacts', list); - } - - addContact(): void { - this.contacts.push(this.getContact()); - } - - getContact(contact: Contact = {} as Contact): FormGroup { - return this.fb.group({ - type: [contact.type || '', Validators.required], - name: [contact.name || '', Validators.required], - emailAddress: [contact.emailAddress || null, [Validators.required, Validators.email]] - }); - } - - removeContact(index: number): void { - this.contacts.removeAt(index); - } -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/component/forms/relying-party-form.component.html b/ui/src/app/metadata/domain/component/forms/relying-party-form.component.html deleted file mode 100644 index 40387d505..000000000 --- a/ui/src/app/metadata/domain/component/forms/relying-party-form.component.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - Sign the Assertion - - - - - - - - - Don't Sign the Response - - - - - - - - - Turn Off Encryption of Response - - - - - - - - - Use SHA1 Signing Algorithm - - - - - - - - NameID Format to Send - - Add NameID Format - - - - - - - - - - NameID Format - {{ i + 1 }}. - - - - - - - - - - - - - - - - Authentication Methods to Use - - Add Authentication Method - - - - - - - - - - Authentication Method {{ i + 1 }}. - - - - - - - - - - - - - - - - - Ignore any SP-Requested Authentication Method - - - - - - - - - - Force AuthN - - - - - - - - - - Omit Not Before Condition - - - - - - - - ResponderID - - - - - - - - - diff --git a/ui/src/app/metadata/domain/component/forms/relying-party-form.component.spec.ts b/ui/src/app/metadata/domain/component/forms/relying-party-form.component.spec.ts deleted file mode 100644 index c12feca92..000000000 --- a/ui/src/app/metadata/domain/component/forms/relying-party-form.component.spec.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { Component, ViewChild } from '@angular/core'; -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import { RelyingPartyFormComponent } from './relying-party-form.component'; -import * as stubs from '../../../../../testing/resolver.stub'; -import { SharedModule } from '../../../../shared/shared.module'; -import { FileBackedHttpMetadataResolver } from '../../entity'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockListValueService } from '../../../../../testing/list-values.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; - - -@Component({ - template: `` -}) -class TestHostComponent { - resolver = new FileBackedHttpMetadataResolver({ - ...stubs.resolver, - relyingPartyOverrides: { - nameIdFormats: [], - authenticationMethods: [] - } - }); - - @ViewChild(RelyingPartyFormComponent) - public formUnderTest: RelyingPartyFormComponent; - - changeProvider(opts: any): void { - this.resolver = Object.assign({}, this.resolver, opts); - } - - addString(collection: 'nameIdFormats' | 'authenticationMethods', value: string): void { - this.resolver.relyingPartyOverrides[collection].push(value); - } -} - -describe('Relying Party Form Component', () => { - let fixture: ComponentFixture; - let instance: TestHostComponent; - let form: RelyingPartyFormComponent; - let fb: FormBuilder; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - ProviderValueEmitter, - ProviderStatusEmitter, - NgbPopoverConfig, - { provide: ListValuesService, useClass: MockListValueService } - ], - imports: [ - NoopAnimationsModule, - ReactiveFormsModule, - MockSharedModule, - MockI18nModule - ], - declarations: [ - RelyingPartyFormComponent, - TestHostComponent - ], - }); - - fixture = TestBed.createComponent(TestHostComponent); - fb = TestBed.get(FormBuilder); - instance = fixture.componentInstance; - form = instance.formUnderTest; - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('removeFormat method', () => { - it('should remove the nameid format at the given index', () => { - instance.addString('nameIdFormats', 'foo'); - fixture.detectChanges(); - form.removeFormat(0); - fixture.detectChanges(); - expect(form.nameIdFormatList.length).toBe(0); - }); - }); - - describe('addFormat method', () => { - it('should add a new nameid format', () => { - form.addFormat(); - fixture.detectChanges(); - expect(form.nameIdFormatList.length).toBe(1); - }); - - it('should add a new nameid format with a value supplied', () => { - form.addFormat('foo'); - fixture.detectChanges(); - expect(form.nameIdFormatList.length).toBe(1); - }); - }); - - describe('removeAuthenticationMethod method', () => { - it('should remove the auth method at the given index', () => { - instance.addString('authenticationMethods', 'foo'); - fixture.detectChanges(); - form.removeAuthenticationMethod(0); - fixture.detectChanges(); - expect(form.authenticationMethodList.length).toBe(0); - }); - }); - - describe('addAuthenticationMethod method', () => { - it('should add a new auth method', () => { - form.addAuthenticationMethod(); - fixture.detectChanges(); - expect(form.authenticationMethodList.length).toBe(1); - }); - - it('should add a new auth method with provided value', () => { - form.addAuthenticationMethod('foo'); - fixture.detectChanges(); - expect(form.authenticationMethodList.length).toBe(1); - }); - }); - - describe('getRequiredControl method', () => { - it('should create a form control with the required validator attached', () => { - spyOn(fb, 'control').and.callThrough(); - form.getRequiredControl('foo'); - expect(fb.control).toHaveBeenCalledWith('foo', Validators.required); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/relying-party-form.component.ts b/ui/src/app/metadata/domain/component/forms/relying-party-form.component.ts deleted file mode 100644 index fe4c15038..000000000 --- a/ui/src/app/metadata/domain/component/forms/relying-party-form.component.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; -import { FormBuilder, FormGroup, FormControl, FormArray, Validators } from '@angular/forms'; -import { Observable, of } from 'rxjs'; - -import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import { MetadataResolver } from '../../../domain/model'; - - -@Component({ - selector: 'relying-party-form', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './relying-party-form.component.html' -}) -export class RelyingPartyFormComponent extends ProviderFormFragmentComponent implements OnInit, OnChanges, OnDestroy { - @Input() resolver: MetadataResolver; - - form: FormGroup; - nameIds$: Observable = of([]); - authenticationMethods$: Observable = of([]); - - nameIdFormatList: FormArray; - authenticationMethodList: FormArray; - - constructor( - protected fb: FormBuilder, - protected statusEmitter: ProviderStatusEmitter, - protected valueEmitter: ProviderValueEmitter, - private listValues: ListValuesService - ) { - super(fb, statusEmitter, valueEmitter); - } - - ngOnInit(): void { - super.ngOnInit(); - } - - createForm(): void { - this.nameIdFormatList = this.fb.array([]); - this.authenticationMethodList = this.fb.array([]); - this.form = this.fb.group({ - relyingPartyOverrides: this.fb.group({ - signAssertion: false, - dontSignResponse: false, - turnOffEncryption: false, - useSha: false, - ignoreAuthenticationMethod: false, - forceAuthn: false, - omitNotBefore: false, - responderId: '', - nameIdFormats: this.nameIdFormatList, - authenticationMethods: this.authenticationMethodList - }) - }); - } - - getRequiredControl = (value: string): FormControl => this.fb.control(value, Validators.required); - - setNameIdFormats(nameIdFormats: string[] = []): void { - let fcs = nameIdFormats.map(this.getRequiredControl); - fcs.forEach(ctrl => this.nameIdFormatList.push(ctrl)); - } - - setAuthenticationMethods(methods: string[] = []): void { - let fcs = methods.map(this.getRequiredControl); - fcs.forEach(ctrl => this.authenticationMethodList.push(ctrl)); - } - - addFormat(text: string = ''): void { - this.nameIdFormatList.push(this.getRequiredControl(text)); - } - - addAuthenticationMethod(text: string = ''): void { - this.authenticationMethodList.push(this.getRequiredControl(text)); - } - - removeFormat(index: number): void { - this.nameIdFormatList.removeAt(index); - } - - removeAuthenticationMethod(index: number): void { - this.authenticationMethodList.removeAt(index); - } - - ngOnChanges(): void { - let overrides = this.resolver.relyingPartyOverrides || {nameIdFormats: [], authenticationMethods: []}; - this.form.reset({ - relyingPartyOverrides: overrides - }); - this.setNameIdFormats(overrides.nameIdFormats); - this.setAuthenticationMethods(overrides.authenticationMethods); - } - - searchNameIds(query: string): void { - this.nameIds$ = this.listValues.searchFormats(of(query)); - } - - searchAuthMethods(query: string): void { - this.authenticationMethods$ = this.listValues.searchAuthenticationMethods(of(query)); - } -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/domain/component/index.ts b/ui/src/app/metadata/domain/component/index.ts deleted file mode 100644 index e95549109..000000000 --- a/ui/src/app/metadata/domain/component/index.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { ReactiveFormsModule } from '@angular/forms'; -import { RouterModule } from '@angular/router'; -import { NgbPopoverModule, NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; - -import { AdvancedInfoFormComponent } from './forms/advanced-info-form.component'; -import { OrganizationInfoFormComponent } from './forms/organization-info-form.component'; -import { MetadataUiFormComponent } from './forms/metadata-ui-form.component'; -import { KeyInfoFormComponent } from './forms/key-info-form.component'; -import { AssertionFormComponent } from './forms/assertion-form.component'; -import { DescriptorInfoFormComponent } from './forms/descriptor-info-form.component'; -import { RelyingPartyFormComponent } from './forms/relying-party-form.component'; -import { AttributeReleaseFormComponent } from './forms/attribute-release-form.component'; -import { LogoutFormComponent } from './forms/logout-form.component'; -import { FinishFormComponent } from './forms/finish-form.component'; -import { ProviderFormFragmentComponent } from './forms/provider-form-fragment.component'; - -import { SharedModule } from '../../../shared/shared.module'; -import { DomainModule } from '../../domain/domain.module'; -import { I18nModule } from '../../../i18n/i18n.module'; - -export const COMPONENTS = [ - AdvancedInfoFormComponent, - OrganizationInfoFormComponent, - MetadataUiFormComponent, - KeyInfoFormComponent, - AssertionFormComponent, - LogoutFormComponent, - DescriptorInfoFormComponent, - RelyingPartyFormComponent, - AttributeReleaseFormComponent, - FinishFormComponent, - ProviderFormFragmentComponent -]; - -export const declarations = [ - ...COMPONENTS, -]; - -@NgModule({ - declarations: declarations, - entryComponents: COMPONENTS, - exports: [ - ...declarations - ], - imports: [ - CommonModule, - DomainModule, - ReactiveFormsModule, - RouterModule, - NgbPopoverModule, - NgbModalModule, - SharedModule, - I18nModule - ], - providers: [] -}) -export class ProviderEditorFormModule {} diff --git a/ui/src/app/metadata/domain/component/summary-property.component.spec.ts b/ui/src/app/metadata/domain/component/summary-property.component.spec.ts index 45433c74d..bc1c4a1d2 100644 --- a/ui/src/app/metadata/domain/component/summary-property.component.spec.ts +++ b/ui/src/app/metadata/domain/component/summary-property.component.spec.ts @@ -1,16 +1,11 @@ import { Component, ViewChild } from '@angular/core'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; -import { StoreModule, Store, combineReducers } from '@ngrx/store'; -import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; +import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; import { SummaryPropertyComponent } from './summary-property.component'; -import * as fromRoot from '../reducer'; import { SchemaFormModule, WidgetRegistry, DefaultWidgetRegistry } from 'ngx-schema-form'; -import * as fromWizard from '../../../wizard/reducer'; -import { Wizard } from '../../../wizard/model'; -import { MetadataProvider } from '../../domain/model'; import { Property } from '../model/property'; import { MockI18nModule } from '../../../../testing/i18n.stub'; @@ -39,18 +34,14 @@ describe('Summary Property Component', () => { let fixture: ComponentFixture; let instance: TestHostComponent; let app: SummaryPropertyComponent; - let store: Store; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ NgbDropdownModule.forRoot(), + NgbPopoverModule.forRoot(), RouterTestingModule, SchemaFormModule.forRoot(), - StoreModule.forRoot({ - provider: combineReducers(fromRoot.reducers), - wizard: combineReducers(fromWizard.reducers) - }), MockI18nModule ], declarations: [ @@ -62,9 +53,6 @@ describe('Summary Property Component', () => { ] }).compileComponents(); - store = TestBed.get(Store); - spyOn(store, 'dispatch'); - fixture = TestBed.createComponent(TestHostComponent); instance = fixture.componentInstance; app = instance.componentUnderTest; diff --git a/ui/src/app/metadata/domain/component/unsaved-entity.dialog.spec.ts b/ui/src/app/metadata/domain/component/unsaved-entity.dialog.spec.ts index b5381baa6..e47af9c90 100644 --- a/ui/src/app/metadata/domain/component/unsaved-entity.dialog.spec.ts +++ b/ui/src/app/metadata/domain/component/unsaved-entity.dialog.spec.ts @@ -1,27 +1,25 @@ import { Component, ViewChild } from '@angular/core'; import { TestBed, async, ComponentFixture} from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; -import { SharedModule } from '../../../shared/shared.module'; -import { UnsavedProviderComponent } from './unsaved-provider.dialog'; +import { UnsavedEntityComponent } from './unsaved-entity.dialog'; import { NgbActiveModalStub } from '../../../../testing/modal.stub'; import { MockI18nModule } from '../../../../testing/i18n.stub'; @Component({ template: ` - + ` }) class TestHostComponent { - @ViewChild(UnsavedProviderComponent) - public componentUnderTest: UnsavedProviderComponent; + @ViewChild(UnsavedEntityComponent) + public componentUnderTest: UnsavedEntityComponent; } describe('Unsaved Provider Dialog Component', () => { let fixture: ComponentFixture; let instance: TestHostComponent; - let cmp: UnsavedProviderComponent; + let cmp: UnsavedEntityComponent; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -29,7 +27,7 @@ describe('Unsaved Provider Dialog Component', () => { MockI18nModule ], declarations: [ - UnsavedProviderComponent, + UnsavedEntityComponent, TestHostComponent ], providers: [ diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts b/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts index 14f028bbe..208de10dc 100644 --- a/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts +++ b/ui/src/app/metadata/domain/component/wizard-summary.component.spec.ts @@ -1,29 +1,26 @@ import { Component, ViewChild } from '@angular/core'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; -import { StoreModule, Store, combineReducers } from '@ngrx/store'; -import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; +import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; -import { ProviderWizardSummaryComponent, getStepProperties } from './provider-wizard-summary.component'; -import * as fromRoot from '../reducer'; +import { getStepProperties, WizardSummaryComponent } from './wizard-summary.component'; import { SchemaFormModule, WidgetRegistry, DefaultWidgetRegistry } from 'ngx-schema-form'; -import * as fromWizard from '../../../wizard/reducer'; import { Wizard } from '../../../wizard/model'; import { MetadataProvider } from '../../domain/model'; import { SummaryPropertyComponent } from './summary-property.component'; import { SCHEMA } from '../../../../testing/form-schema.stub'; -import { MetadataProviderWizard } from '../model'; import { MockI18nModule } from '../../../../testing/i18n.stub'; +import { MetadataProviderWizard } from '../../provider/model'; @Component({ template: ` - + ` }) class TestHostComponent { - @ViewChild(ProviderWizardSummaryComponent) - public componentUnderTest: ProviderWizardSummaryComponent; + @ViewChild(WizardSummaryComponent) + public componentUnderTest: WizardSummaryComponent; private _summary; @@ -40,23 +37,19 @@ describe('Provider Wizard Summary Component', () => { let fixture: ComponentFixture; let instance: TestHostComponent; - let app: ProviderWizardSummaryComponent; - let store: Store; + let app: WizardSummaryComponent; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ NgbDropdownModule.forRoot(), + NgbPopoverModule.forRoot(), RouterTestingModule, SchemaFormModule.forRoot(), - StoreModule.forRoot({ - provider: combineReducers(fromRoot.reducers), - wizard: combineReducers(fromWizard.reducers) - }), MockI18nModule ], declarations: [ - ProviderWizardSummaryComponent, + WizardSummaryComponent, SummaryPropertyComponent, TestHostComponent ], @@ -65,9 +58,6 @@ describe('Provider Wizard Summary Component', () => { ] }).compileComponents(); - store = TestBed.get(Store); - spyOn(store, 'dispatch'); - fixture = TestBed.createComponent(TestHostComponent); instance = fixture.componentInstance; app = instance.componentUnderTest; diff --git a/ui/src/app/metadata/domain/component/wizard-summary.component.ts b/ui/src/app/metadata/domain/component/wizard-summary.component.ts index 8a77bd1b0..bcd82b1a4 100644 --- a/ui/src/app/metadata/domain/component/wizard-summary.component.ts +++ b/ui/src/app/metadata/domain/component/wizard-summary.component.ts @@ -68,8 +68,7 @@ export class WizardSummaryComponent implements OnChanges { columns: Array[]; steps: WizardStep[]; - constructor() { - } + constructor() {} ngOnChanges(changes: SimpleChanges): void { if (changes.summary && this.summary) { diff --git a/ui/src/app/metadata/domain/domain.module.ts b/ui/src/app/metadata/domain/domain.module.ts index b5a075336..ffee8cf1d 100644 --- a/ui/src/app/metadata/domain/domain.module.ts +++ b/ui/src/app/metadata/domain/domain.module.ts @@ -2,6 +2,7 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; import { HttpModule } from '@angular/http'; import { EffectsModule } from '@ngrx/effects'; import { CommonModule } from '@angular/common'; +import { NgbPopoverModule, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; import { ResolverService } from './service/resolver.service'; import { ListValuesService } from './service/list-values.service'; @@ -17,7 +18,7 @@ import { AttributesService } from './service/attributes.service'; import { I18nModule } from '../../i18n/i18n.module'; import { WizardSummaryComponent } from './component/wizard-summary.component'; import { SummaryPropertyComponent } from './component/summary-property.component'; -import { NgbPopoverModule, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; + import { UnsavedEntityComponent } from './component/unsaved-entity.dialog'; import { EditorNavComponent } from './component/editor-nav.component'; import { RouterModule } from '@angular/router'; diff --git a/ui/src/app/metadata/domain/domain.util.spec.ts b/ui/src/app/metadata/domain/domain.util.spec.ts index f5e775495..d8b749098 100644 --- a/ui/src/app/metadata/domain/domain.util.spec.ts +++ b/ui/src/app/metadata/domain/domain.util.spec.ts @@ -37,9 +37,9 @@ describe('Domain Utility methods', () => { describe('mergeProviderOrderFn', () => { const providers = [ - { resourceId: 'foo', name: 'foo', '@type': 'foo', enabled: true, xmlId: 'id', sortKey: 1, metadataFilters: [] }, - { resourceId: 'bar', name: 'bar', '@type': 'bar', enabled: false, xmlId: 'id2', sortKey: 2, metadataFilters: [] }, - { resourceId: 'baz', name: 'baz', '@type': 'baz', enabled: false, xmlId: 'id3', sortKey: 3, metadataFilters: [] } + { id: 'foo', name: 'foo', '@type': 'foo', enabled: true, xmlId: 'id', sortKey: 1, metadataFilters: [] }, + { id: 'bar', name: 'bar', '@type': 'bar', enabled: false, xmlId: 'id2', sortKey: 2, metadataFilters: [] }, + { id: 'baz', name: 'baz', '@type': 'baz', enabled: false, xmlId: 'id3', sortKey: 3, metadataFilters: [] } ]; it('1 should sort the list accordingly', () => { let order = ['bar', 'foo', 'baz'], diff --git a/ui/src/app/metadata/domain/service/draft.service.spec.ts b/ui/src/app/metadata/domain/service/draft.service.spec.ts index bc88dc941..199a301d9 100644 --- a/ui/src/app/metadata/domain/service/draft.service.spec.ts +++ b/ui/src/app/metadata/domain/service/draft.service.spec.ts @@ -28,7 +28,7 @@ describe(`EntityDraftService`, () => { describe('find', () => { it(`should return an observable of the list from the store`, (done: DoneFn) => { let id = 'foo'; - let e = new FileBackedHttpMetadataResolver({ entityId: id }); + let e = new FileBackedHttpMetadataResolver({ id: id }); let list = [e]; spyOn(service.storage, 'query').and.returnValue(list); service.find(id).subscribe(entity => { diff --git a/ui/src/app/metadata/filter/container/edit-filter.component.spec.ts b/ui/src/app/metadata/filter/container/edit-filter.component.spec.ts index b6e8595c4..b38fb4256 100644 --- a/ui/src/app/metadata/filter/container/edit-filter.component.spec.ts +++ b/ui/src/app/metadata/filter/container/edit-filter.component.spec.ts @@ -1,9 +1,7 @@ import { TestBed, ComponentFixture } from '@angular/core/testing'; import { ReactiveFormsModule, FormBuilder } from '@angular/forms'; import { StoreModule, Store, combineReducers } from '@ngrx/store'; -import { NewFilterComponent } from './new-filter.component'; import * as fromFilter from '../reducer'; -import { ProviderEditorFormModule } from '../../domain/component'; import { ProviderStatusEmitter, ProviderValueEmitter } from '../../domain/service/provider-change-emitter.service'; import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; import { NavigatorService } from '../../../core/service/navigator.service'; @@ -35,7 +33,6 @@ describe('New Metadata Filter Page', () => { 'filter': combineReducers(fromFilter.reducers), }), ReactiveFormsModule, - ProviderEditorFormModule, NgbPopoverModule, SharedModule, HttpClientModule, diff --git a/ui/src/app/metadata/filter/container/new-filter.component.spec.ts b/ui/src/app/metadata/filter/container/new-filter.component.spec.ts index 44bbfecfc..b872f2f09 100644 --- a/ui/src/app/metadata/filter/container/new-filter.component.spec.ts +++ b/ui/src/app/metadata/filter/container/new-filter.component.spec.ts @@ -3,7 +3,6 @@ import { ReactiveFormsModule, FormBuilder } from '@angular/forms'; import { StoreModule, Store, combineReducers } from '@ngrx/store'; import { NewFilterComponent } from './new-filter.component'; import * as fromFilter from '../reducer'; -import { ProviderEditorFormModule } from '../../domain/component'; import { ProviderStatusEmitter, ProviderValueEmitter } from '../../domain/service/provider-change-emitter.service'; import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; import { NavigatorService } from '../../../core/service/navigator.service'; @@ -34,7 +33,6 @@ describe('New Metadata Filter Page', () => { 'filter': combineReducers(fromFilter.reducers), }), ReactiveFormsModule, - ProviderEditorFormModule, NgbPopoverModule, SharedModule, HttpClientModule, diff --git a/ui/src/app/metadata/filter/filter.module.ts b/ui/src/app/metadata/filter/filter.module.ts index 8f4d2e509..34997c563 100644 --- a/ui/src/app/metadata/filter/filter.module.ts +++ b/ui/src/app/metadata/filter/filter.module.ts @@ -8,7 +8,6 @@ import { EffectsModule } from '@ngrx/effects'; import { NewFilterComponent } from './container/new-filter.component'; import { reducers } from './reducer'; -import { ProviderEditorFormModule } from '../domain/component'; import { FilterEffects } from './effect/filter.effect'; import { NgbPopoverModule, NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; import { SearchDialogComponent } from './component/search-dialog.component'; @@ -36,7 +35,6 @@ import { I18nModule } from '../../i18n/i18n.module'; imports: [ CommonModule, ReactiveFormsModule, - ProviderEditorFormModule, NgbPopoverModule, NgbModalModule, SharedModule, diff --git a/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.spec.ts b/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.spec.ts index b5cbe9d8d..4ecd91c66 100644 --- a/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.spec.ts +++ b/ui/src/app/metadata/manager/container/dashboard-resolvers-list.component.spec.ts @@ -26,12 +26,14 @@ describe('Dashboard Resolvers List Page', () => { let draft = new FileBackedHttpMetadataResolver({ entityId: 'foo', - serviceProviderName: 'bar' + serviceProviderName: 'bar', + id: '1' }), resolver = new FileBackedHttpMetadataResolver({ entityId: 'foo', serviceProviderName: 'foo', - id: '1' + id: '1', + createdDate: new Date().toDateString() }); beforeEach(() => { @@ -125,7 +127,9 @@ describe('Dashboard Resolvers List Page', () => { it('should route to the wizard page', () => { spyOn(router, 'navigate'); instance.edit(draft); - expect(router.navigate).toHaveBeenCalledWith(['metadata', 'resolver', draft.entityId, 'wizard']); + expect(router.navigate).toHaveBeenCalledWith(['metadata', 'resolver', 'new'], { + queryParams: { id: '1' } + }); }); }); diff --git a/ui/src/app/metadata/provider/container/provider-edit-step.component.spec.ts b/ui/src/app/metadata/provider/container/provider-edit-step.component.spec.ts index 21646b3a6..866d0d647 100644 --- a/ui/src/app/metadata/provider/container/provider-edit-step.component.spec.ts +++ b/ui/src/app/metadata/provider/container/provider-edit-step.component.spec.ts @@ -8,7 +8,6 @@ import * as fromRoot from '../reducer'; import * as fromWizard from '../../../wizard/reducer'; import { SchemaFormModule, WidgetRegistry, DefaultWidgetRegistry } from 'ngx-schema-form'; import { SharedModule } from '../../../shared/shared.module'; -import { SetDefinition } from '../../../wizard/action/wizard.action'; import { FileBackedHttpMetadataProviderEditor } from '../model'; @Component({ @@ -27,6 +26,7 @@ describe('Provider Edit Step Component', () => { let instance: TestHostComponent; let app: ProviderEditStepComponent; let store: Store; + let storeSpy: any; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -42,6 +42,17 @@ describe('Provider Edit Step Component', () => { index: 'common', disabled: false, definition: FileBackedHttpMetadataProviderEditor, + schemaPath: '', + loading: false, + schema: { + type: 'object', + properties: { + foo: { + type: 'string' + } + } + }, + locked: false, schemaCollection: [] } }) @@ -57,7 +68,7 @@ describe('Provider Edit Step Component', () => { }).compileComponents(); store = TestBed.get(Store); - spyOn(store, 'dispatch'); + storeSpy = spyOn(store, 'dispatch'); fixture = TestBed.createComponent(TestHostComponent); instance = fixture.componentInstance; @@ -71,10 +82,10 @@ describe('Provider Edit Step Component', () => { describe('updateStatus method', () => { it('should update the status with provided errors', () => { + storeSpy.calls.reset(); app.currentPage = 'common'; app.updateStatus({value: 'common'}); - app.updateStatus({value: 'foo'}); - expect(store.dispatch).toHaveBeenCalledTimes(3); + expect(store.dispatch).toHaveBeenCalledTimes(1); }); }); diff --git a/ui/src/app/metadata/provider/container/provider-edit.component.spec.ts b/ui/src/app/metadata/provider/container/provider-edit.component.spec.ts index 951d48c77..2736093b2 100644 --- a/ui/src/app/metadata/provider/container/provider-edit.component.spec.ts +++ b/ui/src/app/metadata/provider/container/provider-edit.component.spec.ts @@ -11,7 +11,7 @@ import * as fromWizard from '../../../wizard/reducer'; import { SharedModule } from '../../../shared/shared.module'; import { ActivatedRouteStub } from '../../../../testing/activated-route.stub'; import { FileBackedHttpMetadataProviderEditor } from '../model'; -import { ProviderEditorNavComponent } from '../component/provider-editor-nav.component'; +import { EditorNavComponent } from '../../domain/component/editor-nav.component'; import { NgbModalStub } from '../../../../testing/modal.stub'; import { MetadataProvider } from '../../domain/model'; import { of } from 'rxjs'; @@ -59,6 +59,10 @@ describe('Provider Edit Component', () => { index: 'common', disabled: false, definition: FileBackedHttpMetadataProviderEditor, + schemaPath: '', + loading: false, + schema: {}, + locked: false, schemaCollection: [] } }) @@ -68,7 +72,7 @@ describe('Provider Edit Component', () => { declarations: [ ProviderEditComponent, TestHostComponent, - ProviderEditorNavComponent + EditorNavComponent ], providers: [ DifferentialService, diff --git a/ui/src/app/metadata/provider/container/provider-filter-list.component.spec.ts b/ui/src/app/metadata/provider/container/provider-filter-list.component.spec.ts index ee0450db2..e31a548c8 100644 --- a/ui/src/app/metadata/provider/container/provider-filter-list.component.spec.ts +++ b/ui/src/app/metadata/provider/container/provider-filter-list.component.spec.ts @@ -6,7 +6,7 @@ import { NgbDropdownModule, NgbModalModule, NgbModal } from '@ng-bootstrap/ng-bo import { ProviderFilterListComponent } from './provider-filter-list.component'; import * as fromRoot from '../reducer'; import * as fromWizard from '../../../wizard/reducer'; -import { ProviderEditorNavComponent } from '../component/provider-editor-nav.component'; +import { EditorNavComponent } from '../../domain/component/editor-nav.component'; import { ValidFormIconComponent } from '../../../shared/component/valid-form-icon.component'; import { DeleteFilterComponent } from '../component/delete-filter.component'; import { NgbModalStub } from '../../../../testing/modal.stub'; @@ -42,7 +42,7 @@ describe('Provider Filter List Component', () => { ], declarations: [ ProviderFilterListComponent, - ProviderEditorNavComponent, + EditorNavComponent, ValidFormIconComponent, DeleteFilterComponent, TestHostComponent diff --git a/ui/src/app/metadata/provider/container/provider-wizard-step.component.ts b/ui/src/app/metadata/provider/container/provider-wizard-step.component.ts index db8e461ee..05d121bba 100644 --- a/ui/src/app/metadata/provider/container/provider-wizard-step.component.ts +++ b/ui/src/app/metadata/provider/container/provider-wizard-step.component.ts @@ -46,8 +46,6 @@ export class ProviderWizardStepComponent implements OnDestroy { this.definition$ = this.store.select(fromWizard.getWizardDefinition); this.changes$ = this.store.select(fromProvider.getEntityChanges); - this.schema$.subscribe(s => console.log(s)); - this.validators$ = this.definition$.pipe( withLatestFrom( this.store.select(fromProvider.getProviderNames), diff --git a/ui/src/app/metadata/provider/container/provider-wizard.component.spec.ts b/ui/src/app/metadata/provider/container/provider-wizard.component.spec.ts index bbeb4f907..9678fffa0 100644 --- a/ui/src/app/metadata/provider/container/provider-wizard.component.spec.ts +++ b/ui/src/app/metadata/provider/container/provider-wizard.component.spec.ts @@ -3,13 +3,13 @@ import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { StoreModule, Store, combineReducers } from '@ngrx/store'; -import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; +import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; import { ProviderWizardComponent } from './provider-wizard.component'; import * as fromRoot from '../reducer'; import { WizardModule } from '../../../wizard/wizard.module'; -import { ProviderWizardSummaryComponent } from '../component/provider-wizard-summary.component'; -import { SummaryPropertyComponent } from '../component/summary-property.component'; +import { WizardSummaryComponent } from '../../domain/component/wizard-summary.component'; +import { SummaryPropertyComponent } from '../../domain/component/summary-property.component'; import * as fromWizard from '../../../wizard/reducer'; import { MockI18nModule } from '../../../../testing/i18n.stub'; @@ -35,6 +35,7 @@ describe('Provider Wizard Component', () => { imports: [ WizardModule, NgbDropdownModule.forRoot(), + NgbPopoverModule.forRoot(), RouterTestingModule, StoreModule.forRoot({ provider: combineReducers(fromRoot.reducers), @@ -45,7 +46,7 @@ describe('Provider Wizard Component', () => { declarations: [ ProviderWizardComponent, SummaryPropertyComponent, - ProviderWizardSummaryComponent, + WizardSummaryComponent, TestHostComponent ] }).compileComponents(); diff --git a/ui/src/app/metadata/provider/reducer/editor.reducer.spec.ts b/ui/src/app/metadata/provider/reducer/editor.reducer.spec.ts index 9ab661f87..37c32302a 100644 --- a/ui/src/app/metadata/provider/reducer/editor.reducer.spec.ts +++ b/ui/src/app/metadata/provider/reducer/editor.reducer.spec.ts @@ -2,11 +2,6 @@ import { reducer, initialState as snapshot } from './editor.reducer'; import { EditorActionTypes, ClearEditor, - LockEditor, - LoadSchemaRequest, - LoadSchemaFail, - LoadSchemaSuccess, - UnlockEditor, SelectProviderType } from '../action/editor.action'; @@ -25,36 +20,6 @@ describe('Provider Editor Reducer', () => { }); }); - describe(`${EditorActionTypes.LOCK}`, () => { - it('should reset to initial state', () => { - expect(reducer(snapshot, new LockEditor())).toEqual({ ...snapshot, locked: true }); - }); - }); - - describe(`${EditorActionTypes.UNLOCK}`, () => { - it('should reset to initial state', () => { - expect(reducer(snapshot, new UnlockEditor())).toEqual({ ...snapshot, locked: false }); - }); - }); - - describe(`${EditorActionTypes.LOAD_SCHEMA_REQUEST}`, () => { - it('should reset to initial state', () => { - expect(reducer(snapshot, new LoadSchemaRequest('foo'))).toEqual({ ...snapshot, schemaPath: 'foo', loading: true }); - }); - }); - - describe(`${EditorActionTypes.LOAD_SCHEMA_FAIL}`, () => { - it('should reset to initial state', () => { - expect(reducer(snapshot, new LoadSchemaFail(new Error('fail')))).toEqual({ ...snapshot }); - }); - }); - - describe(`${EditorActionTypes.LOAD_SCHEMA_REQUEST}`, () => { - it('should reset to initial state', () => { - expect(reducer(snapshot, new LoadSchemaSuccess({}))).toEqual({ ...snapshot, schema: {} }); - }); - }); - describe(`${EditorActionTypes.SELECT_PROVIDER_TYPE}`, () => { it('should reset to initial state', () => { expect(reducer(snapshot, new SelectProviderType('foo'))).toEqual({ ...snapshot, type: 'foo' }); diff --git a/ui/src/app/metadata/provider/reducer/index.spec.ts b/ui/src/app/metadata/provider/reducer/index.spec.ts deleted file mode 100644 index 7fb68e2ca..000000000 --- a/ui/src/app/metadata/provider/reducer/index.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -import * as fromProvider from './'; -import { MetadataProvider } from '../../domain/model'; -import { mergeOrderFn } from '../../domain/domain.util'; - -describe(`provider reducer/selector functions`, () => { - - describe('getSchemaParseFn', () => { - const schema = { - properties: { - foo: { - type: 'string' - } - } - }; - const schema2 = { - properties: { - foo: { - type: 'object', - properties: { - bar: { - type: 'string' - } - } - } - } - }; - it('should lock all properties', () => { - expect(fromProvider.getSchemaParseFn(schema, true)).toEqual({ - ...schema, - properties: { - ...schema.properties, - foo: { - ...schema.properties.foo, - readOnly: true - } - } - }); - }); - - it('should unlock all properties', () => { - expect(fromProvider.getSchemaParseFn(schema, false)).toEqual({ - ...schema, - properties: { - ...schema.properties, - foo: { - type: 'string', - readOnly: false - } - } - }); - }); - - it('should lock child properties properties', () => { - expect(fromProvider.getSchemaParseFn(schema2, true)).toEqual({ - ...schema, - properties: { - ...schema2.properties, - foo: { - ...schema2.properties.foo, - readOnly: true, - properties: { - bar: { - ...schema2.properties.foo.properties.bar, - readOnly: true - } - } - } - } - }); - }); - }); - - describe('getSchemaLockedFn', () => { - it('should return true if the step is locked', () => { - expect(fromProvider.getSchemaLockedFn({ locked: true }, false)).toEqual(false); - }); - }); -}); diff --git a/ui/src/app/metadata/domain/component/forms/finish-form.component.html b/ui/src/app/metadata/resolver/component/finish-form.component.html similarity index 100% rename from ui/src/app/metadata/domain/component/forms/finish-form.component.html rename to ui/src/app/metadata/resolver/component/finish-form.component.html diff --git a/ui/src/app/metadata/domain/component/forms/finish-form.component.scss b/ui/src/app/metadata/resolver/component/finish-form.component.scss similarity index 73% rename from ui/src/app/metadata/domain/component/forms/finish-form.component.scss rename to ui/src/app/metadata/resolver/component/finish-form.component.scss index 71ade4d37..0f9488141 100644 --- a/ui/src/app/metadata/domain/component/forms/finish-form.component.scss +++ b/ui/src/app/metadata/resolver/component/finish-form.component.scss @@ -1,4 +1,4 @@ -@import '../../../../../theme/_palette'; +@import '../../../../theme/_palette'; .value:empty { &::after { diff --git a/ui/src/app/metadata/domain/component/forms/finish-form.component.spec.ts b/ui/src/app/metadata/resolver/component/finish-form.component.spec.ts similarity index 80% rename from ui/src/app/metadata/domain/component/forms/finish-form.component.spec.ts rename to ui/src/app/metadata/resolver/component/finish-form.component.spec.ts index fd1fa6945..eddbd6ae8 100644 --- a/ui/src/app/metadata/domain/component/forms/finish-form.component.spec.ts +++ b/ui/src/app/metadata/resolver/component/finish-form.component.spec.ts @@ -3,19 +3,19 @@ import { TestBed, ComponentFixture } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute, Router } from '@angular/router'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; import { NgbPopoverModule, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap'; -import { ListValuesService } from '../../../domain/service/list-values.service'; -import { FinishFormComponent } from './finish-form.component'; -import { RouterStub, RouterLinkStubDirective } from '../../../../../testing/router.stub'; -import { ActivatedRouteStub } from '../../../../../testing/activated-route.stub'; -import * as stubs from '../../../../../testing/resolver.stub'; -import { FileBackedHttpMetadataResolver } from '../../entity'; -import { InputDefaultsDirective } from '../../../../shared/directive/input-defaults.directive'; -import { MockI18nModule } from '../../../../../testing/i18n.stub'; -import { MockListValueService } from '../../../../../testing/list-values.stub'; -import { MockSharedModule } from '../../../../../testing/shared.stub'; +import { ProviderValueEmitter, ProviderStatusEmitter } from '../../domain/service/provider-change-emitter.service'; +import { ListValuesService } from '../../domain/service/list-values.service'; +import { FinishFormComponent } from './finish-form.component'; +import { RouterStub, RouterLinkStubDirective } from '../../../../testing/router.stub'; +import { ActivatedRouteStub } from '../../../../testing/activated-route.stub'; +import * as stubs from '../../../../testing/resolver.stub'; +import { FileBackedHttpMetadataResolver } from '../../domain/entity'; +import { InputDefaultsDirective } from '../../../shared/directive/input-defaults.directive'; +import { MockI18nModule } from '../../../../testing/i18n.stub'; +import { MockListValueService } from '../../../../testing/list-values.stub'; +import { MockSharedModule } from '../../../../testing/shared.stub'; @Component({ template: `` diff --git a/ui/src/app/metadata/domain/component/forms/finish-form.component.ts b/ui/src/app/metadata/resolver/component/finish-form.component.ts similarity index 87% rename from ui/src/app/metadata/domain/component/forms/finish-form.component.ts rename to ui/src/app/metadata/resolver/component/finish-form.component.ts index f7a3a80df..e7e84641a 100644 --- a/ui/src/app/metadata/domain/component/forms/finish-form.component.ts +++ b/ui/src/app/metadata/resolver/component/finish-form.component.ts @@ -2,9 +2,9 @@ import { Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectionStrategy import { FormBuilder, FormGroup } from '@angular/forms'; import { Observable } from 'rxjs'; import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { MetadataResolver } from '../../../domain/model'; -import { ListValuesService } from '../../../domain/service/list-values.service'; +import { ProviderStatusEmitter, ProviderValueEmitter } from '../../domain/service/provider-change-emitter.service'; +import { MetadataResolver } from '../../domain/model'; +import { ListValuesService } from '../../domain/service/list-values.service'; @Component({ selector: 'finish-form', diff --git a/ui/src/app/metadata/domain/component/forms/provider-form-fragment.component.spec.ts b/ui/src/app/metadata/resolver/component/provider-form-fragment.component.spec.ts similarity index 95% rename from ui/src/app/metadata/domain/component/forms/provider-form-fragment.component.spec.ts rename to ui/src/app/metadata/resolver/component/provider-form-fragment.component.spec.ts index 290acaeaa..bf81f8c8a 100644 --- a/ui/src/app/metadata/domain/component/forms/provider-form-fragment.component.spec.ts +++ b/ui/src/app/metadata/resolver/component/provider-form-fragment.component.spec.ts @@ -2,7 +2,7 @@ import { TestBed, ComponentFixture } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { ProviderFormFragmentComponent } from './provider-form-fragment.component'; -import { ProviderValueEmitter, ProviderStatusEmitter } from '../../../domain/service/provider-change-emitter.service'; +import { ProviderValueEmitter, ProviderStatusEmitter } from '../../domain/service/provider-change-emitter.service'; describe('Resolver Form Fragment Component', () => { diff --git a/ui/src/app/metadata/domain/component/forms/provider-form-fragment.component.ts b/ui/src/app/metadata/resolver/component/provider-form-fragment.component.ts similarity index 89% rename from ui/src/app/metadata/domain/component/forms/provider-form-fragment.component.ts rename to ui/src/app/metadata/resolver/component/provider-form-fragment.component.ts index 746dfe7f8..c376a7043 100644 --- a/ui/src/app/metadata/domain/component/forms/provider-form-fragment.component.ts +++ b/ui/src/app/metadata/resolver/component/provider-form-fragment.component.ts @@ -4,11 +4,11 @@ import { FormBuilder, FormGroup, FormControlName } from '@angular/forms'; import { Observable, Subject, Subscription } from 'rxjs'; import { takeUntil, startWith } from 'rxjs/operators'; -import { ProviderStatusEmitter, ProviderValueEmitter } from '../../../domain/service/provider-change-emitter.service'; -import { MetadataResolver } from '../../../domain/model'; +import { ProviderStatusEmitter, ProviderValueEmitter } from '../../domain/service/provider-change-emitter.service'; +import { MetadataResolver } from '../../domain/model'; -import * as constants from '../../../../shared/constant'; -import { removeNulls } from '../../../../shared/util'; +import * as constants from '../../../shared/constant'; +import { removeNulls } from '../../../shared/util'; @Component({ selector: 'provider-form-fragment', diff --git a/ui/src/app/metadata/resolver/component/unsaved-dialog.component.html b/ui/src/app/metadata/resolver/component/unsaved-dialog.component.html deleted file mode 100644 index 94327908a..000000000 --- a/ui/src/app/metadata/resolver/component/unsaved-dialog.component.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - Save your information? - - - - You have not completed the wizard! Do you wish to save this information? You can finish the wizard later by clicking the "Edit" - - icon on the dashboard. - - You have not saved your changes. If you exit this screen, your changes will be lost. - - - - diff --git a/ui/src/app/metadata/resolver/component/unsaved-dialog.component.ts b/ui/src/app/metadata/resolver/component/unsaved-dialog.component.ts deleted file mode 100644 index 9373e352f..000000000 --- a/ui/src/app/metadata/resolver/component/unsaved-dialog.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Component, Input, OnChanges } from '@angular/core'; - -import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; -import { Store, Action } from '@ngrx/store'; -import { Subject } from 'rxjs/Subject'; - -import * as fromEditor from '../reducer'; - -@Component({ - selector: 'unsaved-dialog', - templateUrl: './unsaved-dialog.component.html' -}) -export class UnsavedDialogComponent { - @Input() message; - @Input() action: Action; - - readonly subject: Subject = new Subject(); - - constructor( - public activeModal: NgbActiveModal, - private store: Store - ) { } - - close(): void { - this.store.dispatch(this.action); - this.activeModal.close(); - } - - dismiss(): void { - this.activeModal.dismiss(); - } -} diff --git a/ui/src/app/metadata/resolver/component/wizard-nav.component.html b/ui/src/app/metadata/resolver/component/wizard-nav.component.html deleted file mode 100644 index 34d85715b..000000000 --- a/ui/src/app/metadata/resolver/component/wizard-nav.component.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - Back - - - {{ previousPage.index }}. - - - - - - {{ currentPage.index }} - - - - - - - - - - - - - {{ nextPage.index }}. - - - - Next - - - - - - Save - - - Save - - - - - diff --git a/ui/src/app/metadata/resolver/component/wizard-nav.component.spec.ts b/ui/src/app/metadata/resolver/component/wizard-nav.component.spec.ts deleted file mode 100644 index 78dc71edc..000000000 --- a/ui/src/app/metadata/resolver/component/wizard-nav.component.spec.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { Component, ViewChild } from '@angular/core'; -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { StoreModule, Store, combineReducers } from '@ngrx/store'; -import { WizardNavComponent } from './wizard-nav.component'; -import * as fromResolver from '../reducer'; -import { ProviderEditorFormModule } from '../../domain/component'; -import { DomainModule } from '../../domain/domain.module'; -import { SharedModule } from '../../../shared/shared.module'; -import { MockI18nModule } from '../../../../testing/i18n.stub'; - -@Component({ - template: - ` - ` -}) -class TestHostComponent { - config: any = { - index: 1 - }; - - @ViewChild(WizardNavComponent) - public navUnderTest: WizardNavComponent; - - configure(opts: any): void { - this.config = Object.assign({}, this.config, opts); - } - - onNext(): void {} - onPrevious(): void {} - onSave(): void {} -} - -describe('Wizard Nav Component', () => { - let fixture: ComponentFixture; - let store: Store; - let instance: TestHostComponent; - let wizard: WizardNavComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [], - imports: [ - NoopAnimationsModule, - StoreModule.forRoot({ - 'resolver': combineReducers(fromResolver.reducers), - }), - ReactiveFormsModule, - DomainModule, - SharedModule, - ProviderEditorFormModule, - MockI18nModule - ], - declarations: [TestHostComponent, WizardNavComponent], - }).compileComponents(); - }); - - beforeEach(() => { - store = TestBed.get(Store); - spyOn(store, 'dispatch').and.callThrough(); - - fixture = TestBed.createComponent(TestHostComponent); - instance = fixture.componentInstance; - wizard = instance.navUnderTest; - instance.configure({ index: 1 }); - fixture.detectChanges(); - }); - - it('should compile', () => { - expect(fixture).toBeDefined(); - }); - - describe('ngOnChanges lifecycle event', () => { - it('should set currentPage when an index is provided', () => { - instance.configure({index: 2}); - fixture.detectChanges(); - expect(wizard.currentPage).toBeDefined(); - }); - }); -}); diff --git a/ui/src/app/metadata/resolver/component/wizard-nav.component.ts b/ui/src/app/metadata/resolver/component/wizard-nav.component.ts deleted file mode 100644 index e743c887e..000000000 --- a/ui/src/app/metadata/resolver/component/wizard-nav.component.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Component, Input, Output, EventEmitter, OnChanges } from '@angular/core'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { Store } from '@ngrx/store'; -import * as fromResolver from '../reducer'; -import { WIZARD as WizardDef, EditorFlowDefinition } from '../editor-definition.const'; - -@Component({ - selector: 'wizard-nav', - templateUrl: './wizard-nav.component.html' -}) -export class WizardNavComponent implements OnChanges { - @Input() index: number; - @Output() onNext = new EventEmitter(); - @Output() onPrevious = new EventEmitter(); - @Output() onSave = new EventEmitter(); - - currentPage: any = {}; - previousPage: any = {}; - nextPage: any = {}; - isLastPage = false; - isFirstPage = false; - wizardIsValid$: Observable; - wizardIsInvalid$: Observable; - wizardIsSaving$: Observable; - - wizard: EditorFlowDefinition[] = WizardDef; - - constructor( - private store: Store - ) {} - - ngOnChanges(): void { - this.currentPage = WizardDef.find(r => r.index === this.index); - this.previousPage = WizardDef.find(r => r.index === this.index - 1); - this.nextPage = WizardDef.find(r => r.index === this.index + 1); - this.isLastPage = WizardDef[WizardDef.length - 1].index === this.index; - this.isFirstPage = WizardDef[0].index === this.index; - this.wizard = WizardDef; - - this.wizardIsValid$ = this.store.select(fromResolver.getEntityIsValid); - this.wizardIsSaving$ = this.store.select(fromResolver.getEntityIsSaving); - this.wizardIsInvalid$ = this.wizardIsValid$.pipe(map(valid => !valid)); - } -} /* istanbul ignore next */ diff --git a/ui/src/app/metadata/resolver/container/new-resolver.component.spec.ts b/ui/src/app/metadata/resolver/container/new-resolver.component.spec.ts index 68090592f..bf0f91506 100644 --- a/ui/src/app/metadata/resolver/container/new-resolver.component.spec.ts +++ b/ui/src/app/metadata/resolver/container/new-resolver.component.spec.ts @@ -15,13 +15,14 @@ import { NavigatorService } from '../../../core/service/navigator.service'; import * as fromResolver from '../reducer'; import { ActivatedRouteStub } from '../../../../testing/activated-route.stub'; import { MockI18nModule } from '../../../../testing/i18n.stub'; +import { of } from 'rxjs'; describe('New Resolver Page', () => { let fixture: ComponentFixture; let store: Store; let instance: NewResolverComponent; let activatedRoute: ActivatedRouteStub = new ActivatedRouteStub(); - activatedRoute.testParamMap = { id: 'foo' }; + activatedRoute.testParamMap = { id: 'foo', events: of({}) }; beforeEach(() => { TestBed.configureTestingModule({ diff --git a/ui/src/app/metadata/resolver/editor-definition.const.ts b/ui/src/app/metadata/resolver/editor-definition.const.ts deleted file mode 100644 index 6d9166252..000000000 --- a/ui/src/app/metadata/resolver/editor-definition.const.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { AdvancedInfoFormComponent } from '../domain/component/forms/advanced-info-form.component'; -import { OrganizationInfoFormComponent } from '../domain/component/forms/organization-info-form.component'; -import { MetadataUiFormComponent } from '../domain/component/forms/metadata-ui-form.component'; -import { KeyInfoFormComponent } from '../domain/component/forms/key-info-form.component'; -import { LogoutFormComponent } from '../domain/component/forms/logout-form.component'; -import { AssertionFormComponent } from '../domain/component/forms/assertion-form.component'; -import { DescriptorInfoFormComponent } from '../domain/component/forms/descriptor-info-form.component'; -import { RelyingPartyFormComponent } from '../domain/component/forms/relying-party-form.component'; -import { AttributeReleaseFormComponent } from '../domain/component/forms/attribute-release-form.component'; -import { FinishFormComponent } from '../domain/component/forms/finish-form.component'; - -export interface EditorFlowDefinition { - index: number; - path: string; - label: string; - component: any; -} - -export const COMMON: EditorFlowDefinition[] = [ - { index: 3, path: 'metadata-ui', label: 'label.metadata-ui', component: MetadataUiFormComponent }, - { index: 4, path: 'descriptor-info', label: 'label.descriptor-info', component: DescriptorInfoFormComponent }, - { index: 5, path: 'logout-endpoints', label: 'label.logout-endpoints', component: LogoutFormComponent }, - { index: 6, path: 'key-info', label: 'label.key-info', component: KeyInfoFormComponent }, - { index: 7, path: 'assertion', label: 'label.assertion', component: AssertionFormComponent }, - { index: 8, path: 'relying-party', label: 'label.relying-party', component: RelyingPartyFormComponent }, - { index: 9, path: 'attribute', label: 'label.attribute-release', component: AttributeReleaseFormComponent } -]; - -export const EDITOR: EditorFlowDefinition[] = [ - { index: 2, path: 'sp-org-info', label: 'label.sp-org-info', component: AdvancedInfoFormComponent }, - ...COMMON -]; - -export const WIZARD: EditorFlowDefinition[] = [ - { index: 2, path: 'org-info', label: 'label.org-info', component: OrganizationInfoFormComponent }, - ...COMMON, - { index: 10, path: 'finish', label: 'label.finished', component: FinishFormComponent } -]; diff --git a/ui/src/app/metadata/resolver/effect/draft-collection.effect.spec.ts b/ui/src/app/metadata/resolver/effect/draft-collection.effect.spec.ts index 1c951e718..19760a1b4 100644 --- a/ui/src/app/metadata/resolver/effect/draft-collection.effect.spec.ts +++ b/ui/src/app/metadata/resolver/effect/draft-collection.effect.spec.ts @@ -1,14 +1,17 @@ import { TestBed } from '@angular/core/testing'; import { Actions } from '@ngrx/effects'; +import { StoreModule } from '@ngrx/store'; +import { Router } from '@angular/router'; import { TestActions, getActions } from '../../../../testing/effect.util'; import { DraftCollectionEffects, getPayload } from './draft-collection.effects'; import { EntityDraftService } from '../../domain/service/draft.service'; import { MetadataResolver } from '../../domain/model'; -import { Router } from '@angular/router'; import { RouterStub } from '../../../../testing/router.stub'; import { AddDraftRequest } from '../action/draft.action'; import { FileBackedHttpMetadataResolver } from '../../domain/entity'; +import * as fromRoot from '../../../app.reducer'; + describe('Draft Collection Effects', () => { let effects: DraftCollectionEffects; @@ -32,6 +35,9 @@ describe('Draft Collection Effects', () => { { provide: Actions, useFactory: getActions }, { provide: Router, useClass: RouterStub } ], + imports: [ + StoreModule.forRoot(fromRoot.reducers) + ] }); effects = TestBed.get(DraftCollectionEffects); diff --git a/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts b/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts index 41c55764b..26e8dc34d 100644 --- a/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts +++ b/ui/src/app/metadata/resolver/reducer/collection.reducer.spec.ts @@ -7,14 +7,14 @@ let resolvers: MetadataResolver[] = [ { id: '1', entityId: 'foo', serviceProviderName: 'bar', createdDate: 'Tue Apr 17 2018 13:33:54 GMT-0700 (MST)' } as MetadataResolver, { id: '2', entityId: 'baz', serviceProviderName: 'fin', createdDate: 'Tue Apr 17 2018 13:34:07 GMT-0700 (MST)' } as MetadataResolver ], - snapshot: fromCollection.CollectionState = { - ids: [resolvers[0].id, resolvers[1].id], - entities: { - [resolvers[0].id]: resolvers[0], - [resolvers[1].id]: resolvers[1] - }, - selectedResolverId: null - }; +snapshot: fromCollection.CollectionState = { + ids: [resolvers[0].id, resolvers[1].id], + entities: { + [resolvers[0].id]: resolvers[0], + [resolvers[1].id]: resolvers[1] + }, + selectedResolverId: null +}; describe('Resolver Reducer', () => { const initialState: fromCollection.CollectionState = { diff --git a/ui/src/app/metadata/resolver/reducer/draft.reducer.spec.ts b/ui/src/app/metadata/resolver/reducer/draft.reducer.spec.ts index 936581814..880c70c6a 100644 --- a/ui/src/app/metadata/resolver/reducer/draft.reducer.spec.ts +++ b/ui/src/app/metadata/resolver/reducer/draft.reducer.spec.ts @@ -4,14 +4,14 @@ import * as draftActions from '../action/draft.action'; import { MetadataResolver } from '../../domain/model'; let drafts: MetadataResolver[] = [ - { entityId: 'foo', serviceProviderName: 'bar' } as MetadataResolver, - { entityId: 'baz', serviceProviderName: 'fin' } as MetadataResolver + { id: 'foo', serviceProviderName: 'bar' } as MetadataResolver, + { id: 'baz', serviceProviderName: 'fin' } as MetadataResolver ], snapshot: fromDrafts.DraftState = { - ids: [drafts[0].entityId, drafts[1].entityId], + ids: [drafts[0].id, drafts[1].id], entities: { - [drafts[0].entityId]: drafts[0], - [drafts[1].entityId]: drafts[1] + [drafts[0].id]: drafts[0], + [drafts[1].id]: drafts[1] }, selectedDraftId: null }; @@ -46,10 +46,10 @@ describe('Draft Reducer', () => { it('should update the draft of the specified entityId', () => { let changes = { ...drafts[1], serviceProviderName: 'foo' }, expected = { - ids: [drafts[0].entityId, drafts[1].entityId], + ids: [drafts[0].id, drafts[1].entityId], entities: { - [drafts[0].entityId]: drafts[0], - [drafts[1].entityId]: changes + [drafts[0].id]: drafts[0], + [drafts[1].id]: changes }, selectedDraftId: null }; @@ -61,7 +61,7 @@ describe('Draft Reducer', () => { }); it('should return state if the entityId is not found', () => { - let changes = { ...drafts[1], serviceEnabled: true, entityId: 'bar' }; + let changes = { ...drafts[1], serviceEnabled: true, id: 'bar' }; const action = new draftActions.UpdateDraftSuccess({id: changes.id, changes}); const result = reducer({ ...snapshot }, action); @@ -73,11 +73,11 @@ describe('Draft Reducer', () => { it('should update the selected draft id', () => { let id = 'foo', expected = { ...snapshot, selectedDraftId: id }; - const action = new draftActions.SelectDraft(id); + const action = new draftActions.SelectDraftSuccess(id); const result = reducer({ ...snapshot }, action); expect(result).toEqual( - Object.assign({}, initialState, expected) + { ...initialState, ...expected } ); }); }); diff --git a/ui/src/app/metadata/resolver/reducer/entity.reducer.spec.ts b/ui/src/app/metadata/resolver/reducer/entity.reducer.spec.ts index deaa49327..630b0b998 100644 --- a/ui/src/app/metadata/resolver/reducer/entity.reducer.spec.ts +++ b/ui/src/app/metadata/resolver/reducer/entity.reducer.spec.ts @@ -7,15 +7,15 @@ import { } from '../action/entity.action'; import { MetadataResolver } from '../../domain/model'; -describe('Editor Reducer', () => { - const initialState: fromEntity.EditorState = { +describe('Entity Reducer', () => { + const initialState: fromEntity.EntityState = { saving: false, status: {}, changes: {} as MetadataResolver }; const changes = { - entityId: 'foo', + id: 'foo', serviceProviderName: 'bar' } as MetadataResolver; @@ -32,26 +32,28 @@ describe('Editor Reducer', () => { const action = new UpdateStatus(status); const result = reducer(initialState, action); expect(result).toEqual( - Object.assign({}, initialState, { - formStatus: status - }) + { + ...initialState, + ...{ status } + } ); }); }); - describe('Editor Update Changes', () => { + describe('Entity Update Changes', () => { it('should add changes of the provided form', () => { const action = new UpdateChanges(changes); const result = reducer(initialState, action); expect(result).toEqual( - Object.assign({}, initialState, { - changes: changes - }) + { + ...initialState, + ...{ changes } + } ); }); }); - describe('Editor Clear', () => { + describe('Entity Clear', () => { it('should remove changes', () => { const action = new Clear(); const result = reducer(initialState, action); @@ -63,21 +65,9 @@ describe('Editor Reducer', () => { }); }); - describe('Editor Save', () => { - it('should remove changes', () => { - const action = new UpdateChanges(changes); - const result = reducer(initialState, action); - expect(result).toEqual( - Object.assign({}, initialState, { - changes: initialState.changes - }) - ); - }); - }); - describe('Selectors', () => { it('should aggregate the status', () => { - expect(fromEntity.isEditorValid({ + expect(fromEntity.isEntitySaving({ saving: false, changes: {} as MetadataResolver, status: { @@ -88,15 +78,15 @@ describe('Editor Reducer', () => { }); it('should calculate a saved status based on changes', () => { - expect(fromEntity.isEditorSaving({ + expect(fromEntity.isEntitySaved({ saving: false, changes: {} as MetadataResolver, status: {} })).toBe(true); - expect(fromEntity.isEditorSaving({ + expect(fromEntity.isEntitySaved({ saving: false, - changes: {organization: {}, entityId: 'bar'} as MetadataResolver, + changes: {organization: {}, id: 'bar'} as MetadataResolver, status: {} })).toBe(false); }); @@ -110,13 +100,13 @@ describe('Editor Reducer', () => { }); it('should return `saving` status', () => { - expect(fromEntity.isEditorSaving({ + expect(fromEntity.isEntitySaving({ saving: false, changes: {} as MetadataResolver, status: {} })).toBe(false); - expect(fromEntity.isEditorSaving({ + expect(fromEntity.isEntitySaving({ saving: true, changes: {} as MetadataResolver, status: {} diff --git a/ui/src/app/metadata/resolver/resolver.module.ts b/ui/src/app/metadata/resolver/resolver.module.ts index cdba38585..296943927 100644 --- a/ui/src/app/metadata/resolver/resolver.module.ts +++ b/ui/src/app/metadata/resolver/resolver.module.ts @@ -5,11 +5,9 @@ import { HttpClientModule } from '@angular/common/http'; import { ReactiveFormsModule, FormsModule } from '@angular/forms'; import { StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; -import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; +import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; import { NewResolverComponent } from './container/new-resolver.component'; - -import { ProviderEditorFormModule } from '../domain/component'; import { UploadResolverComponent } from './container/upload-resolver.component'; import { BlankResolverComponent } from './container/blank-resolver.component'; import { CopyResolverComponent } from './container/copy-resolver.component'; @@ -21,11 +19,9 @@ import { CopyIsSetGuard } from './guard/copy-isset.guard'; import { CopyResolverEffects } from './effect/copy.effect'; import { DomainModule } from '../domain/domain.module'; import { ResolverWizardComponent } from './container/resolver-wizard.component'; -import { WizardNavComponent } from './component/wizard-nav.component'; import { ResolverCollectionEffects } from './effect/collection.effects'; import { DraftCollectionEffects } from './effect/draft-collection.effects'; import { WizardEffects } from './effect/wizard.effect'; -import { UnsavedDialogComponent } from './component/unsaved-dialog.component'; import { I18nModule } from '../../i18n/i18n.module'; import { MetadataSourceWizard } from '../domain/model/wizards/metadata-source-wizard'; import { METADATA_SOURCE_WIZARD, METADATA_SOURCE_EDITOR } from './wizard-definition'; @@ -37,6 +33,8 @@ import { ResolverEditComponent } from './container/resolver-edit.component'; import { ResolverEditStepComponent } from './container/resolver-edit-step.component'; import { ResolverSelectComponent } from './container/resolver-select.component'; import { MetadataSourceEditor } from '../domain/model/wizards/metadata-source-editor'; +import { FinishFormComponent } from './component/finish-form.component'; +import { ProviderFormFragmentComponent } from './component/provider-form-fragment.component'; @NgModule({ declarations: [ @@ -48,14 +46,12 @@ import { MetadataSourceEditor } from '../domain/model/wizards/metadata-source-ed ResolverEditComponent, ResolverEditStepComponent, ResolverSelectComponent, - WizardNavComponent, - UnsavedDialogComponent, ResolverWizardComponent, - ResolverWizardStepComponent - ], - entryComponents: [ - UnsavedDialogComponent + ResolverWizardStepComponent, + FinishFormComponent, + ProviderFormFragmentComponent ], + entryComponents: [], imports: [ DomainModule, SharedModule, @@ -64,16 +60,13 @@ import { MetadataSourceEditor } from '../domain/model/wizards/metadata-source-ed RouterModule, ReactiveFormsModule, FormsModule, - ProviderEditorFormModule, NgbDropdownModule, I18nModule, WizardModule, - FormModule - ], - exports: [ - ProviderEditorFormModule, - WizardNavComponent + FormModule, + NgbPopoverModule ], + exports: [], providers: [] }) export class ResolverModule { diff --git a/ui/src/app/wizard/reducer/index.spec.ts b/ui/src/app/wizard/reducer/index.spec.ts index ec2a2a848..dd407ba01 100644 --- a/ui/src/app/wizard/reducer/index.spec.ts +++ b/ui/src/app/wizard/reducer/index.spec.ts @@ -87,4 +87,79 @@ describe('wizard index selectors', () => { expect(selectors.getModelFn(step)).toEqual({}); }); }); + + describe(`reducer/selector logic functions`, () => { + + describe('getSchemaParseFn', () => { + const schema = { + properties: { + foo: { + type: 'string' + } + } + }; + const schema2 = { + properties: { + foo: { + type: 'object', + properties: { + bar: { + type: 'string' + } + } + } + } + }; + it('should lock all properties', () => { + expect(selectors.getSchemaParseFn(schema, true)).toEqual({ + ...schema, + properties: { + ...schema.properties, + foo: { + ...schema.properties.foo, + readOnly: true + } + } + }); + }); + + it('should unlock all properties', () => { + expect(selectors.getSchemaParseFn(schema, false)).toEqual({ + ...schema, + properties: { + ...schema.properties, + foo: { + type: 'string', + readOnly: false + } + } + }); + }); + + it('should lock child properties properties', () => { + expect(selectors.getSchemaParseFn(schema2, true)).toEqual({ + ...schema, + properties: { + ...schema2.properties, + foo: { + ...schema2.properties.foo, + readOnly: true, + properties: { + bar: { + ...schema2.properties.foo.properties.bar, + readOnly: true + } + } + } + } + }); + }); + }); + + describe('getSchemaLockedFn', () => { + it('should return true if the step is locked', () => { + expect(selectors.getSchemaLockedFn({ locked: true }, false)).toEqual(false); + }); + }); + }); }); diff --git a/ui/src/app/wizard/reducer/index.ts b/ui/src/app/wizard/reducer/index.ts index 8540fe2ff..0d7176565 100644 --- a/ui/src/app/wizard/reducer/index.ts +++ b/ui/src/app/wizard/reducer/index.ts @@ -17,8 +17,8 @@ export interface State extends fromRoot.State { } export function getSchemaParseFn(schema, locked): any { - if (!schema) { - return null; + if (!schema || !schema.properties) { + return schema; } return { ...schema, diff --git a/ui/src/app/wizard/reducer/wizard.reducer.spec.ts b/ui/src/app/wizard/reducer/wizard.reducer.spec.ts index c922c226d..8a50eb116 100644 --- a/ui/src/app/wizard/reducer/wizard.reducer.spec.ts +++ b/ui/src/app/wizard/reducer/wizard.reducer.spec.ts @@ -1,6 +1,19 @@ import { reducer, initialState as snapshot } from './wizard.reducer'; import * as selectors from './wizard.reducer'; -import { WizardActionTypes, ClearWizard, AddSchema, SetDisabled, SetDefinition, SetIndex, UpdateDefinition } from '../action/wizard.action'; +import { + WizardActionTypes, + ClearWizard, + AddSchema, + SetDisabled, + SetDefinition, + SetIndex, + LockEditor, + LoadSchemaRequest, + LoadSchemaFail, + LoadSchemaSuccess, + UnlockEditor, + UpdateDefinition +} from '../action/wizard.action'; import { SCHEMA } from '../../../testing/form-schema.stub'; import { MetadataProviderWizard, FileBackedHttpMetadataProviderWizard } from '../../metadata/provider/model'; @@ -63,6 +76,36 @@ describe('Wizard Reducer', () => { }); }); + describe(`${WizardActionTypes.LOCK}`, () => { + it('should reset to initial state', () => { + expect(reducer(snapshot, new LockEditor())).toEqual({ ...snapshot, locked: true }); + }); + }); + + describe(`${WizardActionTypes.UNLOCK}`, () => { + it('should reset to initial state', () => { + expect(reducer(snapshot, new UnlockEditor())).toEqual({ ...snapshot, locked: false }); + }); + }); + + describe(`${WizardActionTypes.LOAD_SCHEMA_REQUEST}`, () => { + it('should reset to initial state', () => { + expect(reducer(snapshot, new LoadSchemaRequest('foo'))).toEqual({ ...snapshot, schemaPath: 'foo', loading: true }); + }); + }); + + describe(`${WizardActionTypes.LOAD_SCHEMA_FAIL}`, () => { + it('should reset to initial state', () => { + expect(reducer(snapshot, new LoadSchemaFail(new Error('fail')))).toEqual({ ...snapshot }); + }); + }); + + describe(`${WizardActionTypes.LOAD_SCHEMA_REQUEST}`, () => { + it('should reset to initial state', () => { + expect(reducer(snapshot, new LoadSchemaSuccess({}))).toEqual({ ...snapshot, schema: {} }); + }); + }); + describe('selector functions', () => { it('should return pieces of state', () => { expect(selectors.getCollection(snapshot)).toEqual(snapshot.schemaCollection); diff --git a/ui/src/testing/activated-route.stub.ts b/ui/src/testing/activated-route.stub.ts index f41853bf9..9fe7c432a 100644 --- a/ui/src/testing/activated-route.stub.ts +++ b/ui/src/testing/activated-route.stub.ts @@ -31,6 +31,10 @@ export class ActivatedRouteStub { return this.paramMap; } + get queryParams() { + return this.paramMap; + } + get firstChild(): ActivatedRouteStub { return this._firstChild; }
- * These three fields must all be entered if any single field has a value. -
- Contact Information: - - Add Contact - -
- Assertion Consumer Service Endpoints: - - Add Endpoint - -
- X509 Certificates: - Add Certificate -
- Logout Endpoints: - Add Endpoint -
- Contact Information: - Add Contact -
- You have not completed the wizard! Do you wish to save this information? You can finish the wizard later by clicking the "Edit" - - icon on the dashboard. -
You have not saved your changes. If you exit this screen, your changes will be lost.