content: {-# LANGUAGE OverloadedStrings #-}
  module Icepeak.Server.AccessControlSpec (spec) where
  
  import Test.Hspec (Spec, describe, it, shouldBe)
  
  import qualified Data.Aeson as Aeson
  import Test.Hspec.QuickCheck (prop)
  import Test.QuickCheck.Instances ()
  
  import Icepeak.Server.AccessControl
  
  import OrphanInstances ()
  
  spec :: Spec
  spec = do
    describe "AccessControl" $ do
      let testClaim = IcepeakClaim
            [ AuthPath ["foo"] [ModeRead]
            , AuthPath ["foo", "bar"] [ModeWrite]
            , AuthPath ["a", "b"] [ModeRead, ModeWrite]
            ]
  
      prop "empty whitelist disallows everything" $ \path mode ->
        let emptyClaim = IcepeakClaim []
        in not $ isAuthorizedByClaim emptyClaim path mode
  
      prop "empty path in whitelist allows everything" $ \path mode ->
        let allClaim = IcepeakClaim [AuthPath [] [ModeRead, ModeWrite]]
        in isAuthorizedByClaim allClaim path mode
  
      prop "allowEverything claim allows everything" $ isAuthorizedByClaim allowEverything
  
      it "should allow access to sub-paths" $ do
        isAuthorizedByClaim testClaim ["foo", "1"] ModeRead `shouldBe` True
        isAuthorizedByClaim testClaim ["foo", "bar"] ModeRead `shouldBe` True
        isAuthorizedByClaim testClaim ["foo", "bar", "1"] ModeWrite `shouldBe` True
  
      it "should disallow access to non-whitelisted paths" $ do
        isAuthorizedByClaim testClaim ["foo", "1"] ModeWrite `shouldBe` False
        isAuthorizedByClaim testClaim ["a"] ModeRead `shouldBe` False
        isAuthorizedByClaim testClaim ["a", "c"] ModeWrite `shouldBe` False
  
      prop "serializing and deserializing claim is identity" $ \claim ->
        Aeson.fromJSON (Aeson.toJSON claim) == Aeson.Success (claim :: IcepeakClaim)
  