Skip to content

Commit 0c2009c

Browse files
committed
document and clarify group-wide overwrite conflict rejection
1 parent 5483bb6 commit 0c2009c

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

src/Components/src/Page/ProvenanceGrouping/EditorActions.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ module AssignmentErrors =
128128
$"Cannot assign {property.Header.Category.Name}: every target must either have no value or exactly one value for this annotation."
129129
| ValueAssignmentError.MultiplePropertyValues(property, setIds) ->
130130
let targets = setIds |> String.concat ", "
131-
$"Cannot overwrite {property.Header.Category.Name}: {targets} already has multiple values for this annotation."
131+
$"Cannot overwrite {property.Header.Category.Name}: {targets} hold more than one distinct value for this annotation, so no single value can be replaced."
132132
| ValueAssignmentError.UpstreamPropertyNotAssigned property ->
133133
$"Cannot assign {property.Header.Category.Name} to a new entity in this layer. This annotation originated in '{property.OriginSource.Name}' and can only replace an existing assignment."
134134

tests/Shared/ProvenanceGrouping.Tests.fs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3066,6 +3066,65 @@ let uiStateTests =
30663066
Expect.equal setIds [ "input-a"; "input-b" ] "The rejection should identify the assigned targets."
30673067
| other -> failwithf "Expected a multiple-value rejection, got %A" other
30683068

3069+
testCase "property value drop plan rejects members whose single values conflict across the group"
3070+
<| fun _ ->
3071+
let species = propertyHeader FixtureKinds.characteristicProperty "Species"
3072+
let inputHeader = ioHeader FixtureKinds.sampleEndpoint "Input [Sample Name]"
3073+
3074+
let model =
3075+
model
3076+
"assay-table"
3077+
[
3078+
propertyValue "pv-input-a-species" species (ProvenanceValue.Text "Arabidopsis") None None
3079+
propertyValue "pv-input-b-species" species (ProvenanceValue.Text "Chlamydomonas") None None
3080+
]
3081+
[
3082+
inputSet "input-a" "assay-table" inputHeader "Input A" [ "pv-input-a-species" ]
3083+
inputSet "input-b" "assay-table" inputHeader "Input B" [ "pv-input-b-species" ]
3084+
] [] []
3085+
3086+
let group: DisplayGroup = {
3087+
Id = "manual"
3088+
TableName = "assay-table"
3089+
Side = ProvenanceSide.Input
3090+
GroupingValues = []
3091+
Members = [
3092+
{
3093+
SetId = "input-a"
3094+
Name = "Input A"
3095+
PropertyValueIds = [ "pv-input-a-species" ]
3096+
}
3097+
{
3098+
SetId = "input-b"
3099+
Name = "Input B"
3100+
PropertyValueIds = [ "pv-input-b-species" ]
3101+
}
3102+
]
3103+
}
3104+
3105+
let source: Types.ValueAssignmentSource = {
3106+
CopiedFrom = None
3107+
Property = propertyKeyIn model species
3108+
Value = ProvenanceValue.Text "A. thaliana"
3109+
Unit = None
3110+
}
3111+
3112+
// Intentionally stricter than the pre-origin-aware planner: each member
3113+
// has exactly one value, but no single existing group value can be
3114+
// replaced safely, so the drop is rejected instead of confirmed.
3115+
match ValueAssignment.planPropertyValueDrop source group model with
3116+
| Error(Types.ValueAssignmentError.MultiplePropertyValues(property, setIds)) ->
3117+
Expect.equal
3118+
property
3119+
(propertyKeyIn model species)
3120+
"The rejection should retain exact property identity."
3121+
3122+
Expect.equal
3123+
setIds
3124+
[ "input-a"; "input-b" ]
3125+
"Every member holding a conflicting value should be identified."
3126+
| other -> failwithf "Expected a cross-member conflict rejection, got %A" other
3127+
30693128
testCase "property value drop plan overwrites one distinct value represented by several occurrence IDs"
30703129
<| fun _ ->
30713130
let temperature = propertyHeader FixtureKinds.parameterProperty "Temperature"

0 commit comments

Comments
 (0)