module Test.Spar.IdPIssuerUpdate where

import API.GalleyInternal
import API.Spar
import Control.Lens
import SAML2.WebSSO
import SAML2.WebSSO.Test.Util
import SetupHelpers
import Testlib.Prelude

testUpdateIdPIssuerThenDelete :: (HasCallStack) => App ()
testUpdateIdPIssuerThenDelete :: HasCallStack => App ()
testUpdateIdPIssuerThenDelete = do
  (owner, tid, _) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
1
  void $ setTeamFeatureStatus owner tid "sso" "enabled"

  -- This create->update->delete flow works, because the issuer doesn't change
  SampleIdP idpmeta1 _ _ _ <- makeSampleIdPMetadata
  idpId1 <-
    createIdp owner idpmeta1 `bindResponse` \Response
resp -> do
      Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
201
      Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"id" App Value -> (Value -> App String) -> App String
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> App String
forall a. (HasCallStack, MakesValue a) => a -> App String
asString

  SampleIdP (edIssuer .~ (idpmeta1 ^. edIssuer) -> idpmeta2) _ _ _ <- makeSampleIdPMetadata
  idpId2 <-
    updateIdp owner idpId1 idpmeta2 `bindResponse` \Response
resp -> do
      Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
200
      Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"id" App Value -> (Value -> App String) -> App String
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> App String
forall a. (HasCallStack, MakesValue a) => a -> App String
asString

  idpId1 `shouldMatch` idpId2
  (idpmeta1 ^. edIssuer) `shouldMatch` (idpmeta2 ^. edIssuer)

  deleteIdp owner idpId2 `bindResponse` \Response
resp -> do
    Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
204

  getIdp owner idpId2 `bindResponse` \Response
resp -> do
    Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
404

  -- This create->update->delete flow failed, because the issuer is updated. It
  -- now works as well.
  SampleIdP idpmeta3 _ _ _ <- makeSampleIdPMetadata
  idpId3 <-
    createIdp owner idpmeta3 `bindResponse` \Response
resp -> do
      Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
201
      Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"id" App Value -> (Value -> App String) -> App String
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> App String
forall a. (HasCallStack, MakesValue a) => a -> App String
asString

  SampleIdP idpmeta4 _ _ _ <- makeSampleIdPMetadata
  idpId4 <-
    updateIdp owner idpId3 idpmeta4 `bindResponse` \Response
resp -> do
      Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
200
      Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"id" App Value -> (Value -> App String) -> App String
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> App String
forall a. (HasCallStack, MakesValue a) => a -> App String
asString

  idpId3 `shouldMatch` idpId4
  (idpmeta3 ^. edIssuer) `shouldNotMatch` (idpmeta4 ^. edIssuer)

  deleteIdp owner idpId4 `bindResponse` \Response
resp -> do
    Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
204

  getIdp owner idpId4 `bindResponse` \Response
resp -> do
    Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
404