diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.spec.ts index 0299836d7da9..35f1d2ffd704 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.spec.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.spec.ts @@ -17,10 +17,13 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ParameterTable } from './parameter-table.component'; +import { ParameterItem, ParameterTable } from './parameter-table.component'; import { provideMockStore } from '@ngrx/store/testing'; import { initialState } from '../../../state/parameter-context-listing/parameter-context-listing.reducer'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { EditParameterResponse } from '../../../../../state/shared'; +import { Observable, of } from 'rxjs'; +import { Parameter } from '@nifi/shared'; describe('ParameterTable', () => { let component: ParameterTable; @@ -39,4 +42,73 @@ describe('ParameterTable', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should handle no parameters with no edits', () => { + component.writeValue([]); + expect(component.serializeParameters()).toEqual([]); + }); + + it('should handle no parameters with one added', () => { + component.writeValue([]); + + const parameter: Parameter = { + name: 'param', + value: 'value', + description: 'asdf', + sensitive: false + }; + component.createNewParameter = (): Observable => { + return of({ + parameter, + valueChanged: true + }); + }; + component.newParameterClicked(); + + expect(component.serializeParameters()).toEqual([{ parameter }]); + }); + + it('should handle no parameters with one added and then edited', () => { + component.writeValue([]); + + const parameter: Parameter = { + name: 'param', + value: 'value', + description: 'asdf', + sensitive: false + }; + component.createNewParameter = (): Observable => { + return of({ + parameter, + valueChanged: true + }); + }; + component.newParameterClicked(); + + const parameterItem: ParameterItem = component.dataSource.data[0]; + expect(parameterItem.originalEntity.parameter).toEqual(parameter); + + const description = 'updated description'; + component.editParameter = (): Observable => { + return of({ + parameter: { + name: 'param', + value: null, + sensitive: false, + description + }, + valueChanged: false + }); + }; + component.editClicked(parameterItem); + + expect(component.serializeParameters()).toEqual([ + { + parameter: { + ...parameter, + description + } + } + ]); + }); }); diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts index c2572ace4c8a..381bb12e12e0 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/parameter-contexts/ui/parameter-context-listing/parameter-table/parameter-table.component.ts @@ -353,10 +353,19 @@ export class ParameterTable implements AfterViewInit, ControlValueAccessor { if (!item.updatedEntity) { item.updatedEntity = { parameter: { - ...item.originalEntity.parameter, - value: null + ...item.originalEntity.parameter } }; + + // if this parameter is an existing parameter, we want to mark the value as null. a null value + // for existing parameters will indicate to the server that the value is unchanged. this is needed + // for sensitive parameters where the value isn't available client side. for new parameters which + // are not known on the server should not have their value cleared. this is relevant when the user + // created a new parameter and then subsequents edits it (e.g. to change the description) before + // submission. + if (!item.added) { + item.updatedEntity.parameter.value = null; + } } let hasChanged: boolean = response.valueChanged; @@ -434,7 +443,10 @@ export class ParameterTable implements AfterViewInit, ControlValueAccessor { this.onChange(this.serializeParameters()); } - private serializeParameters(): any[] { + /** + * Serializes the Parameters. Not private for testing purposes. + */ + serializeParameters(): any[] { const parameters: ParameterItem[] = this.dataSource.data; // only include dirty items