packages feed

keter-rate-limiting-plugin-0.1.0.0: test/Keter/RateLimiter/TokenBucketStateTests.hs

{-# LANGUAGE OverloadedStrings #-}

{-|
Module      : Keter.RateLimiter.TokenBucketStateTests
Description : Tests for the TokenBucketState data type.
Copyright   : (c) 2025 Oleksandr Zhabenko
License     : MIT
Maintainer  : oleksandr.zhabenko@yahoo.com
Stability   : stable
Portability : portable

This module provides unit tests for the 'TokenBucketState' data type,
ensuring its construction, JSON serialization/deserialization, and
validation logic work correctly.
-}
module Keter.RateLimiter.TokenBucketStateTests (
  -- * Test Suite
  tests
) where

import Test.Tasty
import Test.Tasty.HUnit
import Data.Aeson (encode, decode)
import qualified Data.ByteString.Lazy.Char8 as LBS
import Keter.RateLimiter.Types (TokenBucketState(..))

-- | The main test tree for 'TokenBucketState'.
tests :: TestTree
tests = testGroup "Keter.RateLimiter.TokenBucketState Tests"
  [ testCase "Construct and compare TokenBucketState" $ do
      let state = TokenBucketState { tokens = 5, lastUpdate = 1625073600 }
      state @?= TokenBucketState { tokens = 5, lastUpdate = 1625073600 }
      tokens state @?= 5
      lastUpdate state @?= 1625073600

  , testCase "JSON serialization and deserialization" $ do
      let state = TokenBucketState { tokens = 5, lastUpdate = 1625073600 }
      let json = encode state
      case decode json :: Maybe TokenBucketState of
        Nothing -> assertFailure "JSON deserialization failed"
        Just decoded -> decoded @?= state

  , testCase "Invalid JSON: negative tokens" $ do
      let invalidJson = LBS.pack "{\"tokens\":-1,\"lastUpdate\":1625073600}"
      case decode invalidJson :: Maybe TokenBucketState of
        Just _ -> assertFailure "Should fail to deserialize negative tokens"
        Nothing -> return () -- Expected failure

  , testCase "Invalid JSON: malformed input" $ do
      let invalidJson = LBS.pack "{\"tokens\":5}" -- Missing lastUpdate
      case decode invalidJson :: Maybe TokenBucketState of
        Just _ -> assertFailure "Should fail to deserialize malformed JSON"
        Nothing -> return () -- Expected failure

  , testCase "Edge case: zero tokens" $ do
      let state = TokenBucketState { tokens = 0, lastUpdate = 1625073600 }
      let json = encode state
      case decode json :: Maybe TokenBucketState of
        Nothing -> assertFailure "JSON deserialization failed for zero tokens"
        Just decoded -> decoded @?= state

  , testCase "Edge case: large valid lastUpdate" $ do
      let state = TokenBucketState { tokens = 10, lastUpdate = 1755734400 } -- Approx. 2025-08-01
      let json = encode state
      case decode json :: Maybe TokenBucketState of
        Nothing -> assertFailure "JSON deserialization failed for large lastUpdate"
        Just decoded -> decoded @?= state
  ]