@@ -4,6 +4,10 @@ import {
44 CacheTierSchema ,
55 CacheInvalidationSchema ,
66 CacheConfigSchema ,
7+ CacheConsistencySchema ,
8+ CacheAvalanchePreventionSchema ,
9+ CacheWarmupSchema ,
10+ DistributedCacheConfigSchema ,
711} from './cache.zod' ;
812
913describe ( 'CacheStrategySchema' , ( ) => {
@@ -158,3 +162,137 @@ describe('CacheConfigSchema', () => {
158162 expect ( ( ) => CacheConfigSchema . parse ( { tiers : [ ] } ) ) . toThrow ( ) ;
159163 } ) ;
160164} ) ;
165+
166+ describe ( 'CacheConsistencySchema' , ( ) => {
167+ it ( 'should accept all consistency strategies' , ( ) => {
168+ const strategies = [ 'write_through' , 'write_behind' , 'write_around' , 'refresh_ahead' ] as const ;
169+ strategies . forEach ( strategy => {
170+ expect ( ( ) => CacheConsistencySchema . parse ( strategy ) ) . not . toThrow ( ) ;
171+ } ) ;
172+ } ) ;
173+
174+ it ( 'should reject invalid strategy' , ( ) => {
175+ expect ( ( ) => CacheConsistencySchema . parse ( 'read_through' ) ) . toThrow ( ) ;
176+ } ) ;
177+ } ) ;
178+
179+ describe ( 'CacheAvalanchePreventionSchema' , ( ) => {
180+ it ( 'should accept empty config' , ( ) => {
181+ expect ( ( ) => CacheAvalanchePreventionSchema . parse ( { } ) ) . not . toThrow ( ) ;
182+ } ) ;
183+
184+ it ( 'should accept jitter TTL config' , ( ) => {
185+ const result = CacheAvalanchePreventionSchema . parse ( {
186+ jitterTtl : { enabled : true , maxJitterSeconds : 30 } ,
187+ } ) ;
188+ expect ( result . jitterTtl ?. enabled ) . toBe ( true ) ;
189+ expect ( result . jitterTtl ?. maxJitterSeconds ) . toBe ( 30 ) ;
190+ } ) ;
191+
192+ it ( 'should accept circuit breaker config' , ( ) => {
193+ const result = CacheAvalanchePreventionSchema . parse ( {
194+ circuitBreaker : { enabled : true , failureThreshold : 10 , resetTimeout : 60 } ,
195+ } ) ;
196+ expect ( result . circuitBreaker ?. failureThreshold ) . toBe ( 10 ) ;
197+ } ) ;
198+
199+ it ( 'should accept lockout config' , ( ) => {
200+ const result = CacheAvalanchePreventionSchema . parse ( {
201+ lockout : { enabled : true , lockTimeoutMs : 3000 } ,
202+ } ) ;
203+ expect ( result . lockout ?. lockTimeoutMs ) . toBe ( 3000 ) ;
204+ } ) ;
205+
206+ it ( 'should accept full prevention config' , ( ) => {
207+ expect ( ( ) => CacheAvalanchePreventionSchema . parse ( {
208+ jitterTtl : { enabled : true } ,
209+ circuitBreaker : { enabled : true } ,
210+ lockout : { enabled : true } ,
211+ } ) ) . not . toThrow ( ) ;
212+ } ) ;
213+ } ) ;
214+
215+ describe ( 'CacheWarmupSchema' , ( ) => {
216+ it ( 'should accept minimal warmup config' , ( ) => {
217+ const result = CacheWarmupSchema . parse ( { } ) ;
218+ expect ( result . enabled ) . toBe ( false ) ;
219+ expect ( result . strategy ) . toBe ( 'lazy' ) ;
220+ } ) ;
221+
222+ it ( 'should accept eager warmup with patterns' , ( ) => {
223+ const result = CacheWarmupSchema . parse ( {
224+ enabled : true ,
225+ strategy : 'eager' ,
226+ patterns : [ 'config:*' , 'user:*' ] ,
227+ concurrency : 20 ,
228+ } ) ;
229+ expect ( result . strategy ) . toBe ( 'eager' ) ;
230+ expect ( result . patterns ) . toHaveLength ( 2 ) ;
231+ expect ( result . concurrency ) . toBe ( 20 ) ;
232+ } ) ;
233+
234+ it ( 'should accept scheduled warmup' , ( ) => {
235+ const result = CacheWarmupSchema . parse ( {
236+ enabled : true ,
237+ strategy : 'scheduled' ,
238+ schedule : '0 0 * * *' ,
239+ } ) ;
240+ expect ( result . schedule ) . toBe ( '0 0 * * *' ) ;
241+ } ) ;
242+ } ) ;
243+
244+ describe ( 'DistributedCacheConfigSchema' , ( ) => {
245+ it ( 'should accept basic distributed cache' , ( ) => {
246+ const config = DistributedCacheConfigSchema . parse ( {
247+ enabled : true ,
248+ tiers : [
249+ { name : 'l1' , type : 'memory' , maxSize : 100 } ,
250+ { name : 'l2' , type : 'redis' , maxSize : 1000 } ,
251+ ] ,
252+ invalidation : [ { trigger : 'update' , scope : 'key' } ] ,
253+ consistency : 'write_through' ,
254+ } ) ;
255+
256+ expect ( config . consistency ) . toBe ( 'write_through' ) ;
257+ } ) ;
258+
259+ it ( 'should accept full distributed cache config' , ( ) => {
260+ const config = DistributedCacheConfigSchema . parse ( {
261+ enabled : true ,
262+ tiers : [
263+ { name : 'l1' , type : 'memory' , maxSize : 100 , ttl : 60 , strategy : 'lru' } ,
264+ { name : 'l2' , type : 'redis' , maxSize : 1000 , ttl : 300 , strategy : 'lru' } ,
265+ ] ,
266+ invalidation : [ { trigger : 'update' , scope : 'key' } ] ,
267+ consistency : 'write_behind' ,
268+ avalanchePrevention : {
269+ jitterTtl : { enabled : true , maxJitterSeconds : 30 } ,
270+ circuitBreaker : { enabled : true , failureThreshold : 5 } ,
271+ lockout : { enabled : true } ,
272+ } ,
273+ warmup : {
274+ enabled : true ,
275+ strategy : 'eager' ,
276+ patterns : [ 'config:*' ] ,
277+ } ,
278+ } ) ;
279+
280+ expect ( config . consistency ) . toBe ( 'write_behind' ) ;
281+ expect ( config . avalanchePrevention ?. jitterTtl ?. enabled ) . toBe ( true ) ;
282+ expect ( config . warmup ?. strategy ) . toBe ( 'eager' ) ;
283+ } ) ;
284+
285+ it ( 'should extend CacheConfigSchema fields' , ( ) => {
286+ const config = DistributedCacheConfigSchema . parse ( {
287+ enabled : true ,
288+ tiers : [ { name : 'test' , type : 'memory' } ] ,
289+ invalidation : [ { trigger : 'update' , scope : 'key' } ] ,
290+ prefetch : true ,
291+ compression : true ,
292+ encryption : true ,
293+ } ) ;
294+
295+ expect ( config . prefetch ) . toBe ( true ) ;
296+ expect ( config . compression ) . toBe ( true ) ;
297+ } ) ;
298+ } ) ;
0 commit comments