Skip to content

Commit 0267129

Browse files
committed
test(redis): cover side effect serialization and queries
1 parent 90a063f commit 0267129

2 files changed

Lines changed: 51 additions & 1 deletion

File tree

Examples/Governance/RedisQueries/Scenarios/GovernanceRedisQueriesScenario.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
using Microsoft.Extensions.DependencyInjection;
22
using ModularityKit.Mutator.Abstractions.Context;
3+
using ModularityKit.Mutator.Abstractions.Effects;
34
using ModularityKit.Mutator.Abstractions.Intent;
45
using ModularityKit.Mutator.Abstractions.Policies;
56
using ModularityKit.Mutator.Governance.Abstractions.Lifecycle.Model;
67
using ModularityKit.Mutator.Governance.Abstractions.Queries.Contracts;
78
using ModularityKit.Mutator.Governance.Abstractions.Queries.Model.Approvals;
89
using ModularityKit.Mutator.Governance.Abstractions.Queries.Model.Decisions;
910
using ModularityKit.Mutator.Governance.Abstractions.Queries.Model.Requests;
11+
using ModularityKit.Mutator.Governance.Abstractions.Queries.Model.Requests.Filters;
1012
using ModularityKit.Mutator.Governance.Abstractions.Requests.Decisions;
1113
using ModularityKit.Mutator.Governance.Abstractions.Requests.Factory;
1214
using ModularityKit.Mutator.Governance.Abstractions.Requests.Model;
@@ -50,6 +52,16 @@ public static async Task Run()
5052
ApproverIds = new HashSet<string> { "security-lead" }
5153
}));
5254

55+
PrintSection("Requests With Actionable Side Effects");
56+
PrintRequests(await queryStore.QueryAsync(new MutationRequestQuery
57+
{
58+
SideEffects = new MutationRequestSideEffectFilter
59+
{
60+
DataContractTypes = new HashSet<string> { "examples.redis.execution-side-effect" },
61+
RequiresAction = true
62+
}
63+
}));
64+
5365
PrintSection("Recent Execution Outcomes");
5466
PrintDecisions(await queryStore.GetRecentDecisionsAsync(
5567
MutationRequestDecisionQuery.RecentExecutionOutcomes(),
@@ -152,6 +164,16 @@ private static MutationRequest CreateExecutedRequest(
152164
CreatedAt = executedAt.AddMinutes(-15),
153165
UpdatedAt = executedAt,
154166
ExecutedAt = executedAt,
167+
SideEffects =
168+
[
169+
SideEffect.Critical(
170+
type: "ExecutedRequestRequiresFollowUp",
171+
description: "Executed request still requires manual follow-up",
172+
data: new RedisExecutionSideEffectData
173+
{
174+
Ticket = "BILL-12"
175+
})
176+
],
155177
Decisions =
156178
[
157179
MutationRequestDecision.Lifecycle(
@@ -178,6 +200,12 @@ private static MutationRequest CreateExecutedRequest(
178200
]
179201
};
180202

203+
[SideEffectDataContract("examples.redis.execution-side-effect", 1)]
204+
private sealed record RedisExecutionSideEffectData
205+
{
206+
public required string Ticket { get; init; }
207+
}
208+
181209
private static void PrintSection(string title)
182210
{
183211
Console.WriteLine();

Tests/ModularityKit.Mutator.Governance.Redis.Tests/Serialization/Converters/RedisMutationRequestSerializerTests.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using ModularityKit.Mutator.Abstractions.Context;
2+
using ModularityKit.Mutator.Abstractions.Effects;
23
using ModularityKit.Mutator.Abstractions.Intent;
34
using ModularityKit.Mutator.Abstractions.Policies;
45
using ModularityKit.Mutator.Governance.Abstractions.Lifecycle.Model;
@@ -61,7 +62,17 @@ public void Roundtrip_preserves_request_shape_needed_by_governance_runtime()
6162
with
6263
{
6364
CreatedAt = new DateTimeOffset(2026, 6, 25, 9, 0, 0, TimeSpan.Zero),
64-
UpdatedAt = new DateTimeOffset(2026, 6, 25, 9, 5, 0, TimeSpan.Zero)
65+
UpdatedAt = new DateTimeOffset(2026, 6, 25, 9, 5, 0, TimeSpan.Zero),
66+
SideEffects =
67+
[
68+
SideEffect.Critical(
69+
type: "WorkflowRejected",
70+
description: "Workflow rejection requires action",
71+
data: new RedisGovernanceSideEffectData
72+
{
73+
Ticket = "INC-42"
74+
})
75+
]
6576
};
6677

6778
var json = RedisMutationRequestSerializer.Serialize(request);
@@ -75,9 +86,20 @@ public void Roundtrip_preserves_request_shape_needed_by_governance_runtime()
7586
Assert.Equal(BlastRadiusScope.Module, roundtrip.Intent.EstimatedBlastRadius?.Scope);
7687
Assert.Equal("platform", roundtrip.Intent.Metadata["risk-owner"]);
7788
Assert.Equal("security", roundtrip.Metadata["team"]);
89+
Assert.Single(roundtrip.SideEffects);
90+
Assert.Equal("WorkflowRejected", roundtrip.SideEffects[0].Type);
91+
Assert.Equal("redis.governance.side-effect", roundtrip.SideEffects[0].DataContractType);
92+
Assert.True(roundtrip.SideEffects[0].TryGetData<RedisGovernanceSideEffectData>(out var sideEffectData));
93+
Assert.Equal("INC-42", sideEffectData!.Ticket);
7894
Assert.Single(roundtrip.Requirements);
7995
Assert.Single(roundtrip.ApprovalRequirements);
8096
Assert.Equal("security-lead", roundtrip.ApprovalRequirements[0].ApproverId);
8197
Assert.Equal(3, roundtrip.Decisions.Count);
8298
}
99+
100+
[SideEffectDataContract("redis.governance.side-effect", 1)]
101+
private sealed record RedisGovernanceSideEffectData
102+
{
103+
public required string Ticket { get; init; }
104+
}
83105
}

0 commit comments

Comments
 (0)