adds support for the nonOwner attribute to compliance policy change set. updates type definitions related to compliance policy. fixes issue with saving a compliance policy after edit.

This commit is contained in:
Seyi Adebajo 2017-12-14 12:57:17 -08:00
parent fcc1c5544b
commit f100e66235
9 changed files with 105 additions and 102 deletions

View File

@ -5,10 +5,10 @@ import {
Classification, Classification,
ComplianceFieldIdValue, ComplianceFieldIdValue,
IComplianceField, IComplianceField,
IFieldIdentifierOption,
SuggestionIntent, SuggestionIntent,
getDefaultSecurityClassification, getDefaultSecurityClassification,
IComplianceFieldFormatOption IComplianceFieldFormatOption,
IComplianceFieldIdentifierOption
} from 'wherehows-web/constants'; } from 'wherehows-web/constants';
import { IComplianceDataType } from 'wherehows-web/typings/api/list/compliance-datatypes'; import { IComplianceDataType } from 'wherehows-web/typings/api/list/compliance-datatypes';
import { fieldChangeSetRequiresReview } from 'wherehows-web/utils/datasets/compliance-policy'; import { fieldChangeSetRequiresReview } from 'wherehows-web/utils/datasets/compliance-policy';
@ -90,10 +90,10 @@ export default class DatasetComplianceRow extends DatasetTableRow {
/** /**
* Dropdown options for each compliance field / record * Dropdown options for each compliance field / record
* @type {Array<IFieldIdentifierOption>} * @type {Array<IComplianceFieldIdentifierOption>}
* @memberof DatasetComplianceRow * @memberof DatasetComplianceRow
*/ */
complianceFieldIdDropdownOptions: Array<IFieldIdentifierOption>; complianceFieldIdDropdownOptions: Array<IComplianceFieldIdentifierOption>;
/** /**
* Reference to the current value of the field's SuggestionIntent if present * Reference to the current value of the field's SuggestionIntent if present
@ -141,10 +141,10 @@ export default class DatasetComplianceRow extends DatasetTableRow {
/** /**
* Takes a field property and extracts the value on the current policy if a suggestion currently exists for the field * Takes a field property and extracts the value on the current policy if a suggestion currently exists for the field
* @param {('logicalType' | 'identifierType')} fieldProp * @param {('logicalType' | 'identifierType')} fieldProp
* @returns {(string | void)} * @returns {(string | null)}
* @memberof DatasetComplianceRow * @memberof DatasetComplianceRow
*/ */
getCurrentValueBeforeSuggestion(fieldProp: 'logicalType' | 'identifierType'): string | void { getCurrentValueBeforeSuggestion(fieldProp: 'logicalType' | 'identifierType'): string | null {
/** /**
* Current value on policy prior to the suggested value * Current value on policy prior to the suggested value
* @type {string} * @type {string}
@ -152,40 +152,40 @@ export default class DatasetComplianceRow extends DatasetTableRow {
const value = get(get(this, 'field'), fieldProp); const value = get(get(this, 'field'), fieldProp);
if (hasEnumerableKeys(get(this, 'prediction')) && value) { if (hasEnumerableKeys(get(this, 'prediction')) && value) {
/** const { label: currentIdType } = getWithDefault(this, 'complianceFieldIdDropdownOptions', []).findBy(
* Field drop down options 'value',
*/ value
const complianceFieldIdDropdownOptions = get(this, 'complianceFieldIdDropdownOptions'); ) || { label: null };
/** const { value: currentLogicalType }: Pick<IComplianceFieldFormatOption, 'value'> = getWithDefault(
* Convenience function to get `label` attribute on the display properties object this,
* @param {(Array<IFieldIdentifierOption> | IFieldIdentifierOption)} [dropDownOptions=[]] 'fieldFormats',
*/ []
const getLabel = (dropDownOptions: Array<IFieldIdentifierOption> = []) => ).findBy('value', value) || { value: null };
((Array.isArray(dropDownOptions) && dropDownOptions.findBy('value', value)) || { label: void 0 }).label;
return { return {
identifierType: getLabel(complianceFieldIdDropdownOptions), identifierType: currentIdType,
logicalType: logicalType: currentLogicalType
(get(this, 'fieldFormats').find(({ value: format }) => format === value) || { value: void 0 }).value || void 0
}[fieldProp]; }[fieldProp];
} }
return null;
} }
/** /**
* Returns a computed value for the field identifierType * Returns a computed value for the field identifierType
* @type {ComputedProperty<ComplianceFieldIdValue>} * @type {ComputedProperty<IComplianceField['identifierType']>}
* @memberof DatasetComplianceRow * @memberof DatasetComplianceRow
*/ */
identifierType = computed('field.identifierType', 'prediction', function( identifierType = computed('field.identifierType', 'prediction', function(
this: DatasetComplianceRow this: DatasetComplianceRow
): ComplianceFieldIdValue { ): IComplianceField['identifierType'] {
/** /**
* Describes the interface for the options bag param passed into the getIdentifierType function below * Describes the interface for the options bag param passed into the getIdentifierType function below
* @interface IGetIdentParams * @interface IGetIdentParams
*/ */
interface IGetIdentParams { interface IGetIdentParams {
identifierType: ComplianceFieldIdValue; identifierType: IComplianceField['identifierType'];
prediction: { identifierType: ComplianceFieldIdValue } | void; prediction: { identifierType: ComplianceFieldIdValue } | void;
} }
@ -194,14 +194,11 @@ export default class DatasetComplianceRow extends DatasetTableRow {
* Inner function takes the field.identifierType and prediction values, and * Inner function takes the field.identifierType and prediction values, and
* returns the identifierType to be rendered in the ui * returns the identifierType to be rendered in the ui
* @param {IGetIdentParams} params * @param {IGetIdentParams} params
* @returns {ComplianceFieldIdValue} * @returns {IComplianceField.identifierType}
*/ */
const getIdentifierType = (params: IGetIdentParams): ComplianceFieldIdValue => { const getIdentifierType = (params: IGetIdentParams): IComplianceField['identifierType'] => {
const { const { identifierType, prediction } = params;
identifierType, return prediction ? prediction.identifierType : identifierType;
prediction: { identifierType: suggestedIdentifierType } = { identifierType: void 0 }
} = params;
return suggestedIdentifierType || identifierType;
}; };
return getIdentifierType({ identifierType, prediction }); return getIdentifierType({ identifierType, prediction });
@ -209,40 +206,43 @@ export default class DatasetComplianceRow extends DatasetTableRow {
/** /**
* Gets the identifierType on the compliance policy before the suggested value * Gets the identifierType on the compliance policy before the suggested value
* @type {ComputedProperty<string>} * @type {ComputedProperty<string | null>}
* @memberof DatasetComplianceRow * @memberof DatasetComplianceRow
*/ */
identifierTypeBeforeSuggestion = computed('identifierType', function(): string | void { identifierTypeBeforeSuggestion = computed('identifierType', function(): string | null {
return this.getCurrentValueBeforeSuggestion('identifierType'); return this.getCurrentValueBeforeSuggestion('identifierType');
}); });
/** /**
* Gets the logicalType on the compliance policy before the suggested value * Gets the logicalType on the compliance policy before the suggested value
* @type {ComputedProperty<string>} * @type {ComputedProperty<string | null>}
* @memberof DatasetComplianceRow * @memberof DatasetComplianceRow
*/ */
logicalTypeBeforeSuggestion = computed('logicalType', function(): string | void { logicalTypeBeforeSuggestion = computed('logicalType', function(): string | null {
return this.getCurrentValueBeforeSuggestion('logicalType'); return this.getCurrentValueBeforeSuggestion('logicalType');
}); });
/** /**
* A list of field formats that are determined based on the field identifierType * A list of field formats that are determined based on the field identifierType
* @type ComputedProperty<Array<IComplianceDataType.supportedFieldFormats> | void> * @type ComputedProperty<Array<IComplianceFieldFormatOption>>
* @memberof DatasetComplianceRow * @memberof DatasetComplianceRow
*/ */
fieldFormats = computed('isIdType', function(this: DatasetComplianceRow): Array<IComplianceFieldFormatOption> { fieldFormats = computed('isIdType', function(this: DatasetComplianceRow): Array<IComplianceFieldFormatOption> {
const identifierType: ComplianceFieldIdValue = get(get(this, 'field'), 'identifierType'); const identifierType = get(get(this, 'field'), 'identifierType') || '';
const { isIdType, complianceDataTypes } = getProperties(this, ['isIdType', 'complianceDataTypes']); const { isIdType, complianceDataTypes } = getProperties(this, ['isIdType', 'complianceDataTypes']);
const complianceDataType = complianceDataTypes.findBy('id', identifierType); const complianceDataType = complianceDataTypes.findBy('id', identifierType);
let fieldFormatOptions: Array<IComplianceFieldFormatOption> = [];
if (complianceDataType && isIdType) { if (complianceDataType && isIdType) {
const supportedFieldFormats = complianceDataType.supportedFieldFormats || []; const supportedFieldFormats = complianceDataType.supportedFieldFormats || fieldFormatOptions;
const fieldFormatOptions = supportedFieldFormats.map(format => ({ value: format, label: format })); const supportedFormatOptions = supportedFieldFormats.map(format => ({ value: format, label: format }));
return fieldFormatOptions.length > 1 ? [unSelectedFieldFormatValue, ...fieldFormatOptions] : fieldFormatOptions; return supportedFormatOptions.length
? [unSelectedFieldFormatValue, ...supportedFormatOptions]
: supportedFormatOptions;
} }
return []; return fieldFormatOptions;
}); });
/** /**
@ -251,11 +251,10 @@ export default class DatasetComplianceRow extends DatasetTableRow {
* @memberof DatasetComplianceRow * @memberof DatasetComplianceRow
*/ */
isIdType: ComputedProperty<boolean> = computed('field.identifierType', function(this: DatasetComplianceRow): boolean { isIdType: ComputedProperty<boolean> = computed('field.identifierType', function(this: DatasetComplianceRow): boolean {
const identifierType: ComplianceFieldIdValue = get(get(this, 'field'), 'identifierType'); const { field: { identifierType }, complianceDataTypes } = getProperties(this, ['field', 'complianceDataTypes']);
const complianceDataTypes = get(this, 'complianceDataTypes'); const { idType } = complianceDataTypes.findBy('id', identifierType || '') || { idType: false };
const complianceDataType = complianceDataTypes.findBy('id', identifierType) || { idType: false };
return complianceDataType.idType; return idType;
}); });
/** /**
@ -264,15 +263,16 @@ export default class DatasetComplianceRow extends DatasetTableRow {
* @memberof DatasetComplianceRow * @memberof DatasetComplianceRow
*/ */
isPiiType = computed('field.identifierType', function(this: DatasetComplianceRow): boolean { isPiiType = computed('field.identifierType', function(this: DatasetComplianceRow): boolean {
const identifierType: ComplianceFieldIdValue = get(get(this, 'field'), 'identifierType'); const { identifierType } = get(this, 'field');
return !get(this, 'isIdType') && ![ComplianceFieldIdValue.None, null].includes(identifierType); // If identifierType exists, and field is not idType or None or null
return !!identifierType && !get(this, 'isIdType') && ![ComplianceFieldIdValue.None, null].includes(identifierType);
}); });
/** /**
* The fields logical type, rendered as an Object * The fields logical type, rendered as an Object
* If a prediction exists for this field, the predicted value is shown instead * If a prediction exists for this field, the predicted value is shown instead
* @type {(ComputedProperty<IFieldFormatDropdownOption | void>)} * @type {(ComputedProperty<IComplianceField.logicalType>)}
* @memberof DatasetComplianceRow * @memberof DatasetComplianceRow
*/ */
logicalType = computed('field.logicalType', 'prediction', function( logicalType = computed('field.logicalType', 'prediction', function(
@ -296,7 +296,7 @@ export default class DatasetComplianceRow extends DatasetTableRow {
*/ */
classification = computed('field.classification', 'field.identifierType', 'complianceDataTypes', function( classification = computed('field.classification', 'field.identifierType', 'complianceDataTypes', function(
this: DatasetComplianceRow this: DatasetComplianceRow
): Classification | null { ): IComplianceField['classification'] {
const { field: { identifierType, classification }, complianceDataTypes } = getProperties(this, [ const { field: { identifierType, classification }, complianceDataTypes } = getProperties(this, [
'field', 'field',
'complianceDataTypes' 'complianceDataTypes'

View File

@ -468,7 +468,7 @@ export default Component.extend({
return columnFieldProps.reduce((acc, { identifierField, dataType }) => { return columnFieldProps.reduce((acc, { identifierField, dataType }) => {
const currentPrivacyAttrs = getKeysOnField( const currentPrivacyAttrs = getKeysOnField(
['identifierType', 'logicalType', 'securityClassification'], ['identifierType', 'logicalType', 'securityClassification', 'nonOwner'],
identifierField, identifierField,
complianceEntities complianceEntities
); );
@ -654,10 +654,11 @@ export default Component.extend({
const datasetFields = get( const datasetFields = get(
this, this,
'compliancePolicyChangeSet' 'compliancePolicyChangeSet'
).map(({ identifierField, identifierType, logicalType, classification }) => ({ ).map(({ identifierField, identifierType, logicalType, nonOwner, classification }) => ({
identifierField, identifierField,
identifierType, identifierType,
logicalType, logicalType,
nonOwner,
securityClassification: classification securityClassification: classification
})); }));
// Fields that do not have a logicalType, and no identifierType or identifierType is `fieldIdentifierTypes.none` // Fields that do not have a logicalType, and no identifierType or identifierType is `fieldIdentifierTypes.none`
@ -685,7 +686,8 @@ export default Component.extend({
identifierField, identifierField,
identifierType: fieldIdentifierTypes.none.value, identifierType: fieldIdentifierTypes.none.value,
logicalType: null, logicalType: null,
securityClassification: null securityClassification: null,
nonOwner: false
})); }));
const confirmHandler = (function() { const confirmHandler = (function() {
@ -976,14 +978,16 @@ export default Component.extend({
* @param {String} identifierType * @param {String} identifierType
*/ */
onFieldIdentifierTypeChange({ identifierField }, { value: identifierType = null }) { onFieldIdentifierTypeChange({ identifierField }, { value: identifierType = null }) {
const currentComplianceEntities = get(this, 'compliancePolicyChangeSet'); const complianceEntitiesChangeSet = get(this, 'compliancePolicyChangeSet');
// A reference to the current field in the compliance list, it should exist even for empty complianceEntities // A reference to the current field in the compliance list, it should exist even for empty complianceEntities
// since this is a reference created in the working copy: compliancePolicyChangeSet // since this is a reference created in the working copy: compliancePolicyChangeSet
const currentFieldInComplianceList = currentComplianceEntities.findBy('identifierField', identifierField); const changeSetComplianceField = complianceEntitiesChangeSet.findBy('identifierField', identifierField);
setProperties(currentFieldInComplianceList, { // Reset field attributes on change to field in change set
setProperties(changeSetComplianceField, {
identifierType, identifierType,
logicalType: null, logicalType: null,
nonOwner: false,
isDirty: true isDirty: true
}); });

View File

@ -1,12 +1,6 @@
import Component from '@ember/component'; import Component from '@ember/component';
import { get } from '@ember/object'; import { get } from '@ember/object';
import { import { ISecurityClassificationOption, securityClassificationDropdownOptions } from 'wherehows-web/constants';
Classification,
ISecurityClassificationOption,
securityClassificationDropdownOptions
} from 'wherehows-web/constants';
type NullOrClassification = null | Classification;
export default class SchemalessTagging extends Component { export default class SchemalessTagging extends Component {
classNames = ['schemaless-tagging']; classNames = ['schemaless-tagging'];
@ -21,7 +15,9 @@ export default class SchemalessTagging extends Component {
* Interface for parent supplied onClassificationChange action * Interface for parent supplied onClassificationChange action
* @memberof SchemalessTagging * @memberof SchemalessTagging
*/ */
onClassificationChange: (securityClassification: NullOrClassification) => NullOrClassification; onClassificationChange: (
securityClassification: ISecurityClassificationOption['value']
) => ISecurityClassificationOption['value'];
/** /**
* Flag indicating that the dataset contains personally identifiable data * Flag indicating that the dataset contains personally identifiable data
@ -46,10 +42,10 @@ export default class SchemalessTagging extends Component {
/** /**
* The current dataset classification value * The current dataset classification value
* @type {(null | Classification)} * @type { ISecurityClassificationOption.value}
* @memberof SchemalessTagging * @memberof SchemalessTagging
*/ */
classification: null | Classification; classification: ISecurityClassificationOption['value'];
actions = { actions = {
/** /**

View File

@ -1,34 +1,41 @@
import Ember from 'ember'; import Ember from 'ember';
import { ComplianceFieldIdValue, IdLogicalType } from 'wherehows-web/constants/datasets/compliance'; import { Classification, ComplianceFieldIdValue, IdLogicalType } from 'wherehows-web/constants/datasets/compliance';
import { IComplianceDataType } from 'wherehows-web/typings/api/list/compliance-datatypes'; import { IComplianceDataType } from 'wherehows-web/typings/api/list/compliance-datatypes';
import { arrayMap } from 'wherehows-web/utils/array'; import { arrayMap } from 'wherehows-web/utils/array';
const { String: { htmlSafe } } = Ember; const { String: { htmlSafe } } = Ember;
/** /**
* Defines the interface field identifier drop downs * Defines the generic interface field identifier drop downs
* @interface IFieldIdentifierOption * @interface IFieldIdentifierOption
* @template T
*/ */
interface IFieldIdentifierOption { interface IFieldIdentifierOption<T> {
value: string; value: T;
label: string; label: string;
isDisabled?: boolean; isDisabled?: boolean;
} }
/** /**
* Defines the interface for compliance data type field options * Defines the interface for compliance data type field option
* @interface IComplianceFieldIdentifierOption * @interface IComplianceFieldIdentifierOption
* @extends {IFieldIdentifierOption} * @extends {IFieldIdentifierOption<ComplianceFieldIdValue>}
*/ */
interface IComplianceFieldIdentifierOption extends IFieldIdentifierOption { interface IComplianceFieldIdentifierOption extends IFieldIdentifierOption<ComplianceFieldIdValue> {}
value: ComplianceFieldIdValue;
}
interface IComplianceFieldFormatOption { /**
value: IdLogicalType | null; * Defines the interface for a compliance field format dropdown option
label: string; * @interface IComplianceFieldFormatOption
isDisabled?: boolean; * @extends {(IFieldIdentifierOption<IdLogicalType | null>)}
} */
interface IComplianceFieldFormatOption extends IFieldIdentifierOption<IdLogicalType | null> {}
/**
* Defines the interface for an each security classification dropdown option
* @interface ISecurityClassificationOption
* @extends {(IFieldIdentifierOption<Classification | null>)}
*/
interface ISecurityClassificationOption extends IFieldIdentifierOption<Classification | null> {}
/** /**
* Defines a map of values for the compliance policy on a dataset * Defines a map of values for the compliance policy on a dataset
@ -44,7 +51,7 @@ const compliancePolicyStrings = {
invalidPolicyData: 'Received policy in an unexpected format! Please check the provided attributes and try again.', invalidPolicyData: 'Received policy in an unexpected format! Please check the provided attributes and try again.',
helpText: { helpText: {
classification: classification:
'The default value is taken from go/dht and should be good enough in most cases. ' + 'This security classification is from go/dht and should be good enough in most cases. ' +
'You can optionally override it if required by house security.' 'You can optionally override it if required by house security.'
} }
}; };
@ -114,7 +121,7 @@ export {
complianceSteps, complianceSteps,
hiddenTrackingFields, hiddenTrackingFields,
getComplianceSteps, getComplianceSteps,
IFieldIdentifierOption,
IComplianceFieldIdentifierOption, IComplianceFieldIdentifierOption,
IComplianceFieldFormatOption IComplianceFieldFormatOption,
ISecurityClassificationOption
}; };

View File

@ -98,10 +98,11 @@ interface INonIdLogicalTypesSignature {
* @interface IComplianceField * @interface IComplianceField
*/ */
interface IComplianceField { interface IComplianceField {
identifierType: ComplianceFieldIdValue; identifierType: ComplianceFieldIdValue | void;
logicalType: IdLogicalType | null; logicalType: IdLogicalType | null;
classification: Classification | null; classification: Classification | null;
privacyPolicyExists: boolean; privacyPolicyExists: boolean;
nonOwner: boolean;
isDirty: boolean; isDirty: boolean;
suggestion?: { suggestion?: {
identifierType: ComplianceFieldIdValue; identifierType: ComplianceFieldIdValue;

View File

@ -1,5 +1,6 @@
import Ember from 'ember'; import Ember from 'ember';
import { capitalize } from '@ember/string'; import { capitalize } from '@ember/string';
import { ISecurityClassificationOption } from 'wherehows-web/constants/dataset-compliance';
import { import {
Classification, Classification,
nonIdFieldLogicalTypes, nonIdFieldLogicalTypes,
@ -10,18 +11,9 @@ import {
IdLogicalType, IdLogicalType,
ComplianceFieldIdValue ComplianceFieldIdValue
} from 'wherehows-web/constants/datasets/compliance'; } from 'wherehows-web/constants/datasets/compliance';
import { IComplianceField } from 'wherehows-web/constants/index';
import { IComplianceDataType } from 'wherehows-web/typings/api/list/compliance-datatypes'; import { IComplianceDataType } from 'wherehows-web/typings/api/list/compliance-datatypes';
/**
* Defines the interface for an each security classification dropdown option
* @export
* @interface ISecurityClassificationOption
*/
export interface ISecurityClassificationOption {
value: '' | Classification;
label: string;
}
/** /**
* Describes the interface for a drop down option for the field format column in the compliance table * Describes the interface for a drop down option for the field format column in the compliance table
* *
@ -65,11 +57,12 @@ const formatAsCapitalizedStringWithSpaces = (string: string) => capitalize(strin
* @type {Array<ISecurityClassificationOption>} * @type {Array<ISecurityClassificationOption>}
*/ */
const securityClassificationDropdownOptions: Array<ISecurityClassificationOption> = [ const securityClassificationDropdownOptions: Array<ISecurityClassificationOption> = [
'', null,
...classifiers.sort() ...classifiers.sort()
].map((value: '' | Classification) => ({ ].map((value: ISecurityClassificationOption['value']) => ({
value, value,
label: value ? formatAsCapitalizedStringWithSpaces(value) : '...' label: value ? formatAsCapitalizedStringWithSpaces(value) : 'Unspecified',
isDisabled: !value
})); }));
/** /**
@ -144,9 +137,9 @@ const fieldIdentifierTypeValues: Array<ComplianceFieldIdValue> = Object.values(C
*/ */
const getDefaultSecurityClassification = ( const getDefaultSecurityClassification = (
complianceDataTypes: Array<IComplianceDataType> = [], complianceDataTypes: Array<IComplianceDataType> = [],
identifierType: ComplianceFieldIdValue identifierType: IComplianceField['identifierType']
): IComplianceDataType['defaultSecurityClassification'] | null => { ): IComplianceDataType['defaultSecurityClassification'] | null => {
const complianceDataType = complianceDataTypes.findBy('id', identifierType); const complianceDataType = complianceDataTypes.findBy('id', identifierType || '');
return complianceDataType ? complianceDataType.defaultSecurityClassification : null; return complianceDataType ? complianceDataType.defaultSecurityClassification : null;
}; };

View File

@ -127,7 +127,7 @@
{{#row.cell}} {{#row.cell}}
<section class="compliance-depends compliance-depends--visible"> <section class="compliance-depends compliance-depends--visible">
<div class="dataset-compliance-fields__form-input"> <div class="dataset-compliance-fields__form-input">
Field ID Type Field Type
<a <a
target="_blank" target="_blank"
href="http://go/metadata_acquisition#ProjectOverview-compliance"> href="http://go/metadata_acquisition#ProjectOverview-compliance">
@ -157,7 +157,7 @@
Field Format Field Format
<a <a
target="_blank" target="_blank"
href="http://go/gdpr-taxonomy#MetadataTaxonomyforDataSets-DatasetLevelTags"> href="http://go/metadata_acquisition#ProjectOverview-compliance">
<sup> <sup>
More Info More Info

View File

@ -152,7 +152,8 @@ const mergeMappedColumnFieldsWithSuggestions = (mappedColumnFields = {}, fieldSu
securityClassification, securityClassification,
policyModificationTime, policyModificationTime,
privacyPolicyExists, privacyPolicyExists,
isDirty isDirty,
nonOwner
} = mappedColumnFields[fieldName]; } = mappedColumnFields[fieldName];
const suggestion = fieldSuggestionMap[identifierField]; const suggestion = fieldSuggestionMap[identifierField];
@ -163,6 +164,7 @@ const mergeMappedColumnFieldsWithSuggestions = (mappedColumnFields = {}, fieldSu
logicalType, logicalType,
privacyPolicyExists, privacyPolicyExists,
isDirty, isDirty,
nonOwner,
classification: securityClassification classification: securityClassification
}; };

View File

@ -22,7 +22,7 @@ test('it shows the current classification', function(assert) {
assert.expect(3); assert.expect(3);
this.render(hbs`{{datasets/schemaless-tagging classification=classification}}`); this.render(hbs`{{datasets/schemaless-tagging classification=classification}}`);
assert.equal(document.querySelector(`select`).value, '', "displays '' when not set"); assert.equal(document.querySelector(`select`).value, 'Unspecified', "displays 'Unspecified' when not set");
this.set('classification', Classification.LimitedDistribution); this.set('classification', Classification.LimitedDistribution);