@@ -426,12 +426,15 @@ struct KimiUsageResponseParsingTests {
426426 }
427427 """
428428
429- let response = try JSONDecoder ( ) . decode ( KimiSubscriptionStatResponse . self, from: Data ( json. utf8) )
429+ let response = try JSONDecoder ( ) . decode ( KimiSubscriptionStatsResponse . self, from: Data ( json. utf8) )
430430
431431 #expect( response. subscriptionBalance? . feature == " FEATURE_OMNI " )
432432 #expect( response. subscriptionBalance? . type == " SUBSCRIPTION " )
433433 #expect( response. subscriptionBalance? . amountUsedRatio == 1 )
434434 #expect( response. subscriptionBalance? . expireTime == " 2026-07-23T00:00:00Z " )
435+ #expect( response. ratelimitCode7d? . ratio == 0.0946 )
436+ #expect( response. ratelimitCode7d? . enabled == true )
437+ #expect( response. ratelimitCode7d? . resetTime == " 2026-07-09T06:56:36.876796734Z " )
435438 }
436439
437440 @Test
@@ -511,6 +514,11 @@ struct KimiUsageResponseParsingTests {
511514 " type " : " SUBSCRIPTION " ,
512515 " amountUsedRatio " : 0.42,
513516 " expireTime " : " 2026-07-23T00:00:00Z "
517+ },
518+ " ratelimitCode7d " : {
519+ " ratio " : 0.17,
520+ " enabled " : true,
521+ " resetTime " : " 2026-07-13T15:28:00Z "
514522 }
515523 }
516524 """
@@ -524,17 +532,23 @@ struct KimiUsageResponseParsingTests {
524532 if url. path. hasSuffix ( " /GetUsages " ) {
525533 return ( Data ( usageJSON. utf8) , response)
526534 }
535+ #expect( url. path. hasSuffix ( " /GetSubscriptionStats " ) )
527536 return ( Data ( subscriptionJSON. utf8) , response)
528537 }
529538
530539 let snapshot = try await KimiUsageFetcher . _fetchUsageForTesting (
531540 authToken: " test-token " ,
532541 transport: transport,
533542 subscriptionGrace: . seconds( 1 ) )
534- let monthly = try #require( snapshot. toUsageSnapshot ( ) . extraRateWindows? . first)
543+ let windows = try #require( snapshot. toUsageSnapshot ( ) . extraRateWindows)
544+ let monthly = try #require( windows. first { $0. id == " kimi-monthly " } )
545+ let weeklyCode = try #require( windows. first { $0. id == " kimi-code-7d " } )
535546
536547 #expect( monthly. id == " kimi-monthly " )
537548 #expect( monthly. window. usedPercent == 42 )
549+ #expect( weeklyCode. title == " Code 7-day " )
550+ #expect( weeklyCode. window. usedPercent == 17 )
551+ #expect( weeklyCode. window. windowMinutes == 7 * 24 * 60 )
538552 }
539553
540554 @Test
@@ -723,6 +737,64 @@ struct KimiUsageSnapshotConversionTests {
723737 #expect( abs ( monthly. window. usedPercent - 77.16 ) < 0.0001 )
724738 }
725739
740+ @Test
741+ func `converts subscription code weekly limit to extra windo w`() throws {
742+ let now = Date ( )
743+ let weeklyDetail = KimiUsageDetail (
744+ limit: " 2048 " ,
745+ used: " 375 " ,
746+ remaining: " 1673 " ,
747+ resetTime: " 2026-01-09T15:23:13.373329235Z " )
748+ let subscriptionCodeWeeklyLimit = KimiSubscriptionRateLimit (
749+ ratio: 0.0946 ,
750+ enabled: true ,
751+ resetTime: " 2026-07-13T15:28:00Z " )
752+
753+ let snapshot = KimiUsageSnapshot (
754+ weekly: weeklyDetail,
755+ rateLimit: nil ,
756+ subscriptionBalance: nil ,
757+ subscriptionCodeWeeklyLimit: subscriptionCodeWeeklyLimit,
758+ updatedAt: now)
759+ let usageSnapshot = snapshot. toUsageSnapshot ( )
760+
761+ let weeklyCode = try #require( usageSnapshot. extraRateWindows? . first)
762+ #expect( weeklyCode. id == " kimi-code-7d " )
763+ #expect( weeklyCode. title == " Code 7-day " )
764+ #expect( abs ( weeklyCode. window. usedPercent - 9.46 ) < 0.0001 )
765+ #expect( weeklyCode. window. windowMinutes == 7 * 24 * 60 )
766+ #expect( weeklyCode. window. resetsAt == Self . date ( " 2026-07-13T15:28:00Z " ) )
767+ }
768+
769+ @Test
770+ func `omits disabled and nonfinite subscription quota ratios`() {
771+ let weeklyDetail = KimiUsageDetail (
772+ limit: " 2048 " ,
773+ used: " 375 " ,
774+ remaining: " 1673 " ,
775+ resetTime: " 2026-01-09T15:23:13.373329235Z " )
776+ let invalidLimits = [
777+ KimiSubscriptionRateLimit ( ratio: 0.25 , enabled: false , resetTime: nil ) ,
778+ KimiSubscriptionRateLimit ( ratio: . nan, enabled: true , resetTime: nil ) ,
779+ KimiSubscriptionRateLimit ( ratio: . infinity, enabled: true , resetTime: nil ) ,
780+ ]
781+
782+ for limit in invalidLimits {
783+ let snapshot = KimiUsageSnapshot (
784+ weekly: weeklyDetail,
785+ rateLimit: nil ,
786+ subscriptionBalance: KimiSubscriptionBalance (
787+ feature: " FEATURE_OMNI " ,
788+ type: " SUBSCRIPTION " ,
789+ amountUsedRatio: . nan,
790+ expireTime: nil ) ,
791+ subscriptionCodeWeeklyLimit: limit,
792+ updatedAt: Date ( ) )
793+
794+ #expect( snapshot. toUsageSnapshot ( ) . extraRateWindows == nil )
795+ }
796+ }
797+
726798 @Test
727799 func `converts to usage snapshot without rate limit`() {
728800 let now = Date ( )
0 commit comments