Add retention policy option regression coverage
This commit is contained in:
@@ -21,6 +21,7 @@ import FormField from "../../components/FormField";
|
|||||||
import ToggleSwitch from "../../components/ToggleSwitch";
|
import ToggleSwitch from "../../components/ToggleSwitch";
|
||||||
import { useUnsavedDraftGuard } from "../../components/UnsavedChangesGuard";
|
import { useUnsavedDraftGuard } from "../../components/UnsavedChangesGuard";
|
||||||
import {
|
import {
|
||||||
|
privacyRetentionAuditDetailOptionDisabled,
|
||||||
privacyRetentionLocalAllowsLowerLevel,
|
privacyRetentionLocalAllowsLowerLevel,
|
||||||
privacyRetentionParentAllowsField } from
|
privacyRetentionParentAllowsField } from
|
||||||
"./policyLogic";
|
"./policyLogic";
|
||||||
@@ -70,8 +71,6 @@ type FieldDefinition = {
|
|||||||
type RawJsonValue = "inherit" | "keep" | "disable";
|
type RawJsonValue = "inherit" | "keep" | "disable";
|
||||||
type AuditDetailValue = "inherit" | PrivacyRetentionPolicy["audit_detail_level"];
|
type AuditDetailValue = "inherit" | PrivacyRetentionPolicy["audit_detail_level"];
|
||||||
|
|
||||||
const auditDetailOrder: Record<PrivacyRetentionPolicy["audit_detail_level"], number> = { full: 0, redacted: 1, minimal: 2 };
|
|
||||||
|
|
||||||
const defaultAllowLowerLevelLimits: PrivacyRetentionLimitPermissions = {
|
const defaultAllowLowerLevelLimits: PrivacyRetentionLimitPermissions = {
|
||||||
store_raw_campaign_json: true,
|
store_raw_campaign_json: true,
|
||||||
raw_campaign_json_retention_days: true,
|
raw_campaign_json_retention_days: true,
|
||||||
@@ -517,9 +516,8 @@ function RetentionDaysField({ value, disabled, placeholder, max, onChange }: {va
|
|||||||
}
|
}
|
||||||
|
|
||||||
function AuditDetailSelect({ value, includeInherit, parentValue, disabled, onChange }: {value: AuditDetailValue;includeInherit: boolean;parentValue?: PrivacyRetentionPolicy["audit_detail_level"] | null;disabled: boolean;onChange: (value: AuditDetailValue) => void;}) {
|
function AuditDetailSelect({ value, includeInherit, parentValue, disabled, onChange }: {value: AuditDetailValue;includeInherit: boolean;parentValue?: PrivacyRetentionPolicy["audit_detail_level"] | null;disabled: boolean;onChange: (value: AuditDetailValue) => void;}) {
|
||||||
const minimumOrder = parentValue ? auditDetailOrder[parentValue] : 0;
|
|
||||||
function optionDisabled(option: PrivacyRetentionPolicy["audit_detail_level"]): boolean {
|
function optionDisabled(option: PrivacyRetentionPolicy["audit_detail_level"]): boolean {
|
||||||
return auditDetailOrder[option] < minimumOrder;
|
return privacyRetentionAuditDetailOptionDisabled(option, parentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ export type RetentionPolicyLimitCarrier = {
|
|||||||
allow_lower_level_limits?: Partial<Record<PrivacyRetentionPolicyFieldKey, boolean>> | null;
|
allow_lower_level_limits?: Partial<Record<PrivacyRetentionPolicyFieldKey, boolean>> | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type PrivacyRetentionAuditDetailLevel = "full" | "redacted" | "minimal";
|
||||||
|
|
||||||
|
const auditDetailOrder: Record<PrivacyRetentionAuditDetailLevel, number> = { full: 0, redacted: 1, minimal: 2 };
|
||||||
|
|
||||||
export function privacyRetentionParentAllowsField(parentPolicy: RetentionPolicyLimitCarrier | null, key: PrivacyRetentionPolicyFieldKey): boolean {
|
export function privacyRetentionParentAllowsField(parentPolicy: RetentionPolicyLimitCarrier | null, key: PrivacyRetentionPolicyFieldKey): boolean {
|
||||||
return !parentPolicy || parentPolicy.allow_lower_level_limits?.[key] !== false;
|
return !parentPolicy || parentPolicy.allow_lower_level_limits?.[key] !== false;
|
||||||
}
|
}
|
||||||
@@ -27,3 +31,11 @@ export function privacyRetentionLocalAllowsLowerLevel(
|
|||||||
if (localValue !== undefined) return localValue && privacyRetentionParentAllowsField(parentPolicy, key);
|
if (localValue !== undefined) return localValue && privacyRetentionParentAllowsField(parentPolicy, key);
|
||||||
return privacyRetentionParentAllowsField(parentPolicy, key);
|
return privacyRetentionParentAllowsField(parentPolicy, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function privacyRetentionAuditDetailOptionDisabled(
|
||||||
|
option: PrivacyRetentionAuditDetailLevel,
|
||||||
|
parentValue?: PrivacyRetentionAuditDetailLevel | null
|
||||||
|
): boolean {
|
||||||
|
const minimumOrder = parentValue ? auditDetailOrder[parentValue] : 0;
|
||||||
|
return auditDetailOrder[option] < minimumOrder;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
type PrivacyRetentionPolicyFieldKey,
|
type PrivacyRetentionPolicyFieldKey,
|
||||||
type RetentionPolicyLimitCarrier,
|
type RetentionPolicyLimitCarrier,
|
||||||
|
privacyRetentionAuditDetailOptionDisabled,
|
||||||
privacyRetentionLocalAllowsLowerLevel,
|
privacyRetentionLocalAllowsLowerLevel,
|
||||||
privacyRetentionParentAllowsField
|
privacyRetentionParentAllowsField
|
||||||
} from "../src/features/privacy/policyLogic";
|
} from "../src/features/privacy/policyLogic";
|
||||||
@@ -32,3 +33,6 @@ assert(!privacyRetentionLocalAllowsLowerLevel(localPatch, parentPolicy, field, f
|
|||||||
assert(privacyRetentionParentAllowsField(null, field), "missing parent policy should allow local field controls");
|
assert(privacyRetentionParentAllowsField(null, field), "missing parent policy should allow local field controls");
|
||||||
assert(privacyRetentionLocalAllowsLowerLevel({}, null, field, false), "unlocked inherited lower-level controls should remain enabled");
|
assert(privacyRetentionLocalAllowsLowerLevel({}, null, field, false), "unlocked inherited lower-level controls should remain enabled");
|
||||||
assert(!privacyRetentionLocalAllowsLowerLevel({ allow_lower_level_limits: { [field]: false } }, null, field, true), "system policy can disable lower-level choices");
|
assert(!privacyRetentionLocalAllowsLowerLevel({ allow_lower_level_limits: { [field]: false } }, null, field, true), "system policy can disable lower-level choices");
|
||||||
|
assert(privacyRetentionAuditDetailOptionDisabled("full", "redacted"), "lower levels cannot widen audit detail from redacted to full");
|
||||||
|
assert(!privacyRetentionAuditDetailOptionDisabled("minimal", "redacted"), "lower levels can choose stricter audit detail than the parent");
|
||||||
|
assert(!privacyRetentionAuditDetailOptionDisabled("full", null), "system-level audit detail options are all viable");
|
||||||
|
|||||||
Reference in New Issue
Block a user