packages feed

aeson-decode-0.1.0.1: test/Examples/Policy.hs

module Examples.Policy (spec) where

import AesonDecode
import Essentials

import Control.Applicative (optional)
import Data.Aeson (Value)
import Data.Aeson.QQ (aesonQQ)
import Data.Text (Text)
import Data.Time.Clock.POSIX (POSIXTime)
import Prelude (fromInteger)
import Test.Hspec (it, shouldBe, Spec)

newtype Resource = Resource Text deriving (Eq, Show)

data StartTime = StartImmediately | StartTime POSIXTime deriving (Eq, Show)

newtype EndTime = EndTime POSIXTime deriving (Eq, Show)

data IpAddress = AnyIp | IpAddress Text deriving (Eq, Show)

data Policy = Policy
    { policyResource  :: Resource
    , policyStart     :: StartTime
    , policyEnd       :: EndTime
    , policyIpAddress :: IpAddress
    }
    deriving (Eq, Show)

spec :: Spec
spec = it "policy example" $ (json ^? d) `shouldBe` Just p

json :: Value
json =
    [aesonQQ|
      {
        "Statement": [
            {
              "Resource": "http://d111111abcdef8.cloudfront.net/game_download.zip",
              "Condition": {
                  "IpAddress": {"AWS:SourceIp": "192.0.2.0/24"},
                  "DateLessThan": {"AWS:EpochTime": 1357034400}
              }
            }
        ]
      }
    |]

d'time :: Decoder POSIXTime
d'time :: Decoder POSIXTime = at "AWS:EpochTime" integer <&> fromInteger

d :: Decoder Policy
d :: Decoder Policy = at ("Statement" <> only) $ do

    res   <- Resource <$> at "Resource" text

    start <- maybe StartImmediately StartTime <$>
            (optional $ at ("Condition" <> "DateGreaterThan") d'time)

    end   <- EndTime <$> at ("Condition" <> "DateLessThan") d'time

    ip    <- maybe AnyIp IpAddress <$>
            (optional $ at ("Condition" <> "IpAddress")
                            (at "AWS:SourceIp" text))

    pure $ Policy res start end ip

p :: Policy
p = Policy
    (Resource "http://d111111abcdef8.cloudfront.net/game_download.zip")
    StartImmediately
    (EndTime 1357034400)
    (IpAddress "192.0.2.0/24")