@@ -2,22 +2,30 @@ import { describe, test, expect, beforeEach, afterEach } from "vitest";
22import { createTestHttpServer } from "@epic-web/test-server/http" ;
33import { StandardMetadataManager } from "../src/v3/runMetadata/manager.js" ;
44import { ApiClient } from "../src/v3/apiClient/index.js" ;
5+ import { UpdateMetadataRequestBody } from "../src/v3/schemas/index.js" ;
6+ import { applyMetadataOperations } from "../src/v3/runMetadata/operations.js" ;
57
68describe ( "StandardMetadataManager" , ( ) => {
79 const runId = "test-run-id" ;
810 let server : Awaited < ReturnType < typeof createTestHttpServer > > ;
9- let metadataUpdates : Array < Record < string , any > > = [ ] ;
11+ let metadataUpdates : Array < UpdateMetadataRequestBody > = [ ] ;
1012 let manager : StandardMetadataManager ;
1113
1214 beforeEach ( async ( ) => {
1315 metadataUpdates = [ ] ;
16+ const store = { } ;
1417
1518 server = await createTestHttpServer ( {
1619 defineRoutes ( router ) {
1720 router . put ( "/api/v1/runs/:runId/metadata" , async ( { req } ) => {
1821 const body = await req . json ( ) ;
19- metadataUpdates . push ( body ) ;
20- return Response . json ( { metadata : body . metadata } ) ;
22+ const parsedBody = UpdateMetadataRequestBody . parse ( body ) ;
23+
24+ metadataUpdates . push ( parsedBody ) ;
25+
26+ const { newMetadata } = applyMetadataOperations ( store , parsedBody . operations ?? [ ] ) ;
27+
28+ return Response . json ( { metadata : newMetadata } ) ;
2129 } ) ;
2230 } ,
2331 } ) ;
@@ -37,13 +45,13 @@ describe("StandardMetadataManager", () => {
3745 } ) ;
3846
3947 test ( "should set and get simple keys" , ( ) => {
40- manager . setKey ( "test" , "value" ) ;
48+ manager . set ( "test" , "value" ) ;
4149 expect ( manager . getKey ( "test" ) ) . toBe ( "value" ) ;
4250 } ) ;
4351
4452 test ( "should handle JSON path keys" , ( ) => {
45- manager . setKey ( "nested" , { foo : "bar" } ) ;
46- manager . setKey ( "$.nested.path" , "value" ) ;
53+ manager . set ( "nested" , { foo : "bar" } ) ;
54+ manager . set ( "$.nested.path" , "value" ) ;
4755 expect ( manager . current ( ) ) . toEqual ( {
4856 nested : {
4957 foo : "bar" ,
@@ -53,79 +61,74 @@ describe("StandardMetadataManager", () => {
5361 } ) ;
5462
5563 test ( "should flush changes to server" , async ( ) => {
56- manager . setKey ( "test" , "value" ) ;
64+ manager . set ( "test" , "value" ) ;
5765 await manager . flush ( ) ;
5866
5967 expect ( metadataUpdates ) . toHaveLength ( 1 ) ;
60- expect ( metadataUpdates [ 0 ] ) . toEqual ( {
61- metadata : {
62- test : "value" ,
63- } ,
64- } ) ;
6568 } ) ;
6669
6770 test ( "should only flush to server when data has actually changed" , async ( ) => {
6871 // Initial set and flush
69- manager . setKey ( "test" , "value" ) ;
72+ manager . set ( "test" , "value" ) ;
7073 await manager . flush ( ) ;
7174 expect ( metadataUpdates ) . toHaveLength ( 1 ) ;
7275
7376 // Same value set again
74- manager . setKey ( "test" , "value" ) ;
77+ manager . set ( "test" , "value" ) ;
7578 await manager . flush ( ) ;
7679 // Should not trigger another update since value hasn't changed
7780 expect ( metadataUpdates ) . toHaveLength ( 1 ) ;
7881
7982 // Different value set
80- manager . setKey ( "test" , "new value" ) ;
83+ manager . set ( "test" , "new value" ) ;
8184 await manager . flush ( ) ;
8285 // Should trigger new update
8386 expect ( metadataUpdates ) . toHaveLength ( 2 ) ;
8487 } ) ;
8588
8689 test ( "should only flush to server when nested data has actually changed" , async ( ) => {
8790 // Initial nested object
88- manager . setKey ( "nested" , { foo : "bar" } ) ;
91+ manager . set ( "nested" , { foo : "bar" } ) ;
8992 await manager . flush ( ) ;
9093 expect ( metadataUpdates ) . toHaveLength ( 1 ) ;
9194
9295 // Same nested value
93- manager . setKey ( "nested" , { foo : "bar" } ) ;
96+ manager . set ( "nested" , { foo : "bar" } ) ;
9497 await manager . flush ( ) ;
9598 // Should not trigger another update
9699 expect ( metadataUpdates ) . toHaveLength ( 1 ) ;
97100
98101 // Different nested value
99- manager . setKey ( "nested" , { foo : "baz" } ) ;
102+ manager . set ( "nested" , { foo : "baz" } ) ;
100103 await manager . flush ( ) ;
101104 // Should trigger new update
102105 expect ( metadataUpdates ) . toHaveLength ( 2 ) ;
103106 } ) ;
104107
105108 test ( "should append to list with simple key" , ( ) => {
106109 // First append creates the array
107- manager . appendKey ( "myList" , "first" ) ;
110+ manager . append ( "myList" , "first" ) ;
108111 expect ( manager . getKey ( "myList" ) ) . toEqual ( [ "first" ] ) ;
109112
110113 // Second append adds to existing array
111- manager . appendKey ( "myList" , "second" ) ;
114+ manager . append ( "myList" , "second" ) ;
112115 expect ( manager . getKey ( "myList" ) ) . toEqual ( [ "first" , "second" ] ) ;
113116 } ) ;
114117
115118 test ( "should append to list with JSON path" , ( ) => {
116119 // First create nested structure
117- manager . setKey ( "nested" , { items : [ ] } ) ;
120+ manager . set ( "nested" , { items : [ ] } ) ;
118121
119122 // Append to empty array
120- manager . appendKey ( "$.nested.items" , "first" ) ;
123+ manager . append ( "$.nested.items" , "first" ) ;
121124 expect ( manager . current ( ) ) . toEqual ( {
122125 nested : {
123126 items : [ "first" ] ,
124127 } ,
125128 } ) ;
126129
127130 // Append another item
128- manager . appendKey ( "$.nested.items" , "second" ) ;
131+ manager . append ( "$.nested.items" , "second" ) ;
129132 expect ( manager . current ( ) ) . toEqual ( {
130133 nested : {
131134 items : [ "first" , "second" ] ,
@@ -135,19 +138,19 @@ describe("StandardMetadataManager", () => {
135138
136139 test ( "should convert non-array values to array when appending" , ( ) => {
137140 // Set initial non-array value
138- manager . setKey ( "value" , "initial" ) ;
141+ manager . set ( "value" , "initial" ) ;
139142
140143 // Append should convert to array
141- manager . appendKey ( "value" , "second" ) ;
144+ manager . append ( "value" , "second" ) ;
142145 expect ( manager . getKey ( "value" ) ) . toEqual ( [ "initial" , "second" ] ) ;
143146 } ) ;
144147
145148 test ( "should convert non-array values to array when appending with JSON path" , ( ) => {
146149 // Set initial nested non-array value
147- manager . setKey ( "nested" , { value : "initial" } ) ;
150+ manager . set ( "nested" , { value : "initial" } ) ;
148151
149152 // Append should convert to array
150- manager . appendKey ( "$.nested.value" , "second" ) ;
153+ manager . append ( "$.nested.value" , "second" ) ;
151154 expect ( manager . current ( ) ) . toEqual ( {
152155 nested : {
153156 value : [ "initial" , "second" ] ,
@@ -156,70 +159,60 @@ describe("StandardMetadataManager", () => {
156159 } ) ;
157160
158161 test ( "should trigger server update when appending to list" , async ( ) => {
159- manager . appendKey ( "myList" , "first" ) ;
162+ manager . append ( "myList" , "first" ) ;
160163 await manager . flush ( ) ;
161164
162165 expect ( metadataUpdates ) . toHaveLength ( 1 ) ;
163- expect ( metadataUpdates [ 0 ] ) . toEqual ( {
164- metadata : {
165- myList : [ "first" ] ,
166- } ,
167- } ) ;
168166
169- manager . appendKey ( "myList" , "second" ) ;
167+ manager . append ( "myList" , "second" ) ;
170168 await manager . flush ( ) ;
171169
172170 expect ( metadataUpdates ) . toHaveLength ( 2 ) ;
173- expect ( metadataUpdates [ 1 ] ) . toEqual ( {
174- metadata : {
175- myList : [ "first" , "second" ] ,
176- } ,
177- } ) ;
178171 } ) ;
179172
180173 test ( "should not trigger server update when appending same value" , async ( ) => {
181- manager . appendKey ( "myList" , "first" ) ;
174+ manager . append ( "myList" , "first" ) ;
182175 await manager . flush ( ) ;
183176
184177 expect ( metadataUpdates ) . toHaveLength ( 1 ) ;
185178
186179 // Append same value
187- manager . appendKey ( "myList" , "first" ) ;
180+ manager . append ( "myList" , "first" ) ;
188181 await manager . flush ( ) ;
189182
190183 // Should still be only one update
191184 expect ( metadataUpdates ) . toHaveLength ( 2 ) ;
192185 } ) ;
193186
194187 test ( "should increment and decrement keys" , ( ) => {
195- manager . incrementKey ( "counter" ) ;
188+ manager . increment ( "counter" ) ;
196189 expect ( manager . getKey ( "counter" ) ) . toBe ( 1 ) ;
197190
198- manager . incrementKey ( "counter" , 5 ) ;
191+ manager . increment ( "counter" , 5 ) ;
199192 expect ( manager . getKey ( "counter" ) ) . toBe ( 6 ) ;
200193
201- manager . decrementKey ( "counter" ) ;
194+ manager . decrement ( "counter" ) ;
202195 expect ( manager . getKey ( "counter" ) ) . toBe ( 5 ) ;
203196
204- manager . decrementKey ( "counter" , 3 ) ;
197+ manager . decrement ( "counter" , 3 ) ;
205198 expect ( manager . getKey ( "counter" ) ) . toBe ( 2 ) ;
206199 } ) ;
207200
208201 test ( "should remove value from array with simple key" , ( ) => {
209202 // Setup initial array
210- manager . setKey ( "myList" , [ "first" , "second" , "third" ] ) ;
203+ manager . set ( "myList" , [ "first" , "second" , "third" ] ) ;
211204
212205 // Remove a value
213- manager . removeFromKey ( "myList" , "second" ) ;
206+ manager . remove ( "myList" , "second" ) ;
214207 expect ( manager . getKey ( "myList" ) ) . toEqual ( [ "first" , "third" ] ) ;
215208 } ) ;
216209
217210 test ( "should remove value from array with JSON path" , ( ) => {
218211 // Setup initial nested array
219- manager . setKey ( "nested" , { items : [ "first" , "second" , "third" ] } ) ;
212+ manager . set ( "nested" , { items : [ "first" , "second" , "third" ] } ) ;
220213
221214 // Remove a value
222- manager . removeFromKey ( "$.nested.items" , "second" ) ;
215+ manager . remove ( "$.nested.items" , "second" ) ;
223216 expect ( manager . current ( ) ) . toEqual ( {
224217 nested : {
225218 items : [ "first" , "third" ] ,
@@ -229,32 +222,32 @@ describe("StandardMetadataManager", () => {
229222
230223 test ( "should handle removing non-existent value" , ( ) => {
231224 // Setup initial array
232- manager . setKey ( "myList" , [ "first" , "second" ] ) ;
225+ manager . set ( "myList" , [ "first" , "second" ] ) ;
233226
234227 // Try to remove non-existent value
235- manager . removeFromKey ( "myList" , "third" ) ;
228+ manager . remove ( "myList" , "third" ) ;
236229 expect ( manager . getKey ( "myList" ) ) . toEqual ( [ "first" , "second" ] ) ;
237230 } ) ;
238231
239232 test ( "should handle removing from non-array values" , ( ) => {
240233 // Setup non-array value
241- manager . setKey ( "value" , "string" ) ;
234+ manager . set ( "value" , "string" ) ;
242235
243236 // Try to remove from non-array
244- manager . removeFromKey ( "value" , "something" ) ;
237+ manager . remove ( "value" , "something" ) ;
245238 expect ( manager . getKey ( "value" ) ) . toBe ( "string" ) ;
246239 } ) ;
247240
248241 test ( "should remove object from array using deep equality" , ( ) => {
249242 // Setup array with objects
250- manager . setKey ( "objects" , [
243+ manager . set ( "objects" , [
251244 { id : 1 , name : "first" } ,
252245 { id : 2 , name : "second" } ,
253246 { id : 3 , name : "third" } ,
254247 ] ) ;
255248
256249 // Remove object
257- manager . removeFromKey ( "objects" , { id : 2 , name : "second" } ) ;
250+ manager . remove ( "objects" , { id : 2 , name : "second" } ) ;
258251 expect ( manager . getKey ( "objects" ) ) . toEqual ( [
259252 { id : 1 , name : "first" } ,
260253 { id : 3 , name : "third" } ,
@@ -263,30 +256,25 @@ describe("StandardMetadataManager", () => {
263256
264257 test ( "should trigger server update when removing from array" , async ( ) => {
265258 // Setup initial array
266- manager . setKey ( "myList" , [ "first" , "second" , "third" ] ) ;
259+ manager . set ( "myList" , [ "first" , "second" , "third" ] ) ;
267260 await manager . flush ( ) ;
268261 expect ( metadataUpdates ) . toHaveLength ( 1 ) ;
269262
270263 // Remove value
271- manager . removeFromKey ( "myList" , "second" ) ;
264+ manager . remove ( "myList" , "second" ) ;
272265 await manager . flush ( ) ;
273266
274267 expect ( metadataUpdates ) . toHaveLength ( 2 ) ;
275- expect ( metadataUpdates [ 1 ] ) . toEqual ( {
276- metadata : {
277- myList : [ "first" , "third" ] ,
278- } ,
279- } ) ;
280268 } ) ;
281269
282270 test ( "should not trigger server update when removing non-existent value" , async ( ) => {
283271 // Setup initial array
284- manager . setKey ( "myList" , [ "first" , "second" ] ) ;
272+ manager . set ( "myList" , [ "first" , "second" ] ) ;
285273 await manager . flush ( ) ;
286274 expect ( metadataUpdates ) . toHaveLength ( 1 ) ;
287275
288276 // Try to remove non-existent value
289- manager . removeFromKey ( "myList" , "third" ) ;
277+ manager . remove ( "myList" , "third" ) ;
290278 await manager . flush ( ) ;
291279
292280 // Should not trigger new update since nothing changed
0 commit comments