hstratus-drive-0.1.0.0: test/HStratus/Drive/EndpointsSpec.hs
{-# LANGUAGE OverloadedStrings #-}
{- |
Module : HStratus.Drive.EndpointsSpec
Copyright : (c) 2026 Tim Emiola
Maintainer : Tim Emiola <adetokunbo@emio.la>
SPDX-License-Identifier: BSD-3-Clause
Tests for the iCloud Drive CloudKit endpoint and request-body builders.
-}
module HStratus.Drive.EndpointsSpec (spec) where
import Data.Aeson (Value, decode, object)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Map.Strict as Map
import Data.Text (Text)
import Network.HStratus.Internal.Drive.Endpoints
( downloadTokenReq
, mkDriveEndpoints
, nodeDetailsBody
, nodeDetailsReq
)
import Network.HStratus.Internal.Drive.Node (DriveNodeId (..), rootNodeId)
import Network.HStratus.Session (AccountData (..), Credentials (..), Session (..), Webservice (..))
import Network.HTTP.Client (Request (..))
import Network.HTTP.Types (methodGet, methodPost)
import Test.Hspec
spec :: Spec
spec = describe "Network.HStratus.Internal.Drive.Endpoints" $ do
ep <- runIO (mkDriveEndpoints testAccountData testSession)
describe "nodeDetailsBody" $ do
it "encodes the node id and partialData=false" $
nodeDetailsBody rootNodeId
`shouldBe` ( "[{\"drivewsid\":\"FOLDER::com.apple.CloudDocs::root\""
<> ",\"partialData\":false}]"
:: LBS.ByteString
)
it "produces valid JSON for node ids containing quotes or backslashes" $
(decode (nodeDetailsBody (DriveNodeId "folder/with\"quote\\here")) :: Maybe Value)
`shouldNotBe` Nothing
describe "nodeDetailsReq" $ do
it "targets retrieveItemDetailsInFolders" $
path (nodeDetailsReq ep)
`shouldSatisfy` BS.isSuffixOf "/retrieveItemDetailsInFolders"
it "uses POST" $
method (nodeDetailsReq ep) `shouldBe` methodPost
it "includes clientId query param" $
queryString (nodeDetailsReq ep)
`shouldSatisfy` BS.isInfixOf "clientId=auth-test-client-id"
describe "downloadTokenReq" $ do
let req = downloadTokenReq "DOC-001" "com.apple.CloudDocs" ep
it "targets /ws/<zone>/download/by_id" $
path req
`shouldSatisfy` BS.isSuffixOf "/ws/com.apple.CloudDocs/download/by_id"
it "uses GET" $
method req `shouldBe` methodGet
it "includes clientId in query string" $
queryString req `shouldSatisfy` BS.isInfixOf "clientId=auth-test-client-id"
it "includes document_id in query string" $
queryString req `shouldSatisfy` BS.isInfixOf "document_id=DOC-001"
-- Fixtures
testClientId :: Text
testClientId = "auth-test-client-id"
testAccountData :: AccountData
testAccountData =
AccountData
{ adHsaVersion = 2
, adHsaChallengeRequired = False
, adHsaTrustedBrowser = Just True
, adWebservices =
Map.fromList
[ ("drivews", Webservice "https://p31-drivews.icloud.com" Nothing)
, ("docws", Webservice "https://p31-docws.icloud.com" Nothing)
]
, adRaw = object []
}
testSession :: Session
testSession =
Session
{ sessionCreds = Credentials{credAccountName = "test@example.com", credPassword = "test-pass"}
, sessionTopDir = "/tmp/test"
, sessionClientId = testClientId
}