desktop-portal-0.0.1.0: test/Desktop/Portal/FileChooserSpec.hs
module Desktop.Portal.FileChooserSpec (spec) where
import Control.Monad (void)
import DBus (InterfaceName, toVariant)
import Data.ByteString (ByteString)
import Data.Default.Class (def)
import Data.Text (Text)
import Data.Word (Word32)
import Desktop.Portal (ChoiceCombo (..), ChoiceComboOption (..), ChoiceComboSelection (..), Filter (..), FilterFileType (..), OpenFileOptions (..), OpenFileResults (..), SaveFileOptions (..), SaveFileResults (..))
import Desktop.Portal qualified as Portal
import Desktop.Portal.TestUtil
import Test.Hspec (Spec, anyException, around, describe, it, shouldBe, shouldThrow)
fileChooserInterface :: InterfaceName
fileChooserInterface = "org.freedesktop.portal.FileChooser"
spec :: Spec
spec = do
around withTestBus $ do
describe "openFile" $ do
it "should encode request with all Nothings" $ \client -> do
body <- savingRequestArguments client fileChooserInterface "OpenFile" $ do
void (Portal.openFile def)
body
`shouldBe` [ toVariantText "",
toVariantText "",
toVariantMap []
]
it "should encode request with all Justs" $ \client -> do
body <- savingRequestArguments client fileChooserInterface "OpenFile" $ do
void . Portal.openFile $
OpenFileOptions
{ parentWindow = Just "_parentWindow",
title = Just "_title",
acceptLabel = Just "_acceptLabel",
modal = Just True,
multiple = Just True,
directory = Just True,
filters =
Just
[ Filter
{ name = "_filterName",
fileTypes = [GlobFilter "*.txt", MimeFilter "application/json"]
}
],
currentFilter =
Just
( Filter
{ name = "_currentFilterName",
fileTypes = [GlobFilter "*.jpg", MimeFilter "image/jpeg"]
}
),
choices =
Just
[ ChoiceCombo
{ id = "_choiceId",
label_ = "_choiceLabel",
choices = [ChoiceComboOption {id = "_ccoId", label_ = "_ccoLabel"}],
defaultChoiceId = "_defaultChoiceId"
}
]
}
body
`shouldBe` [ toVariantText "_parentWindow",
toVariantText "_title",
toVariantMap
[ ("accept_label", toVariantText "_acceptLabel"),
("modal", toVariant True),
("multiple", toVariant True),
("directory", toVariant True),
( "filters",
toVariant
[ ( "_filterName" :: Text,
[ (0 :: Word32, "*.txt" :: Text),
(1 :: Word32, "application/json" :: Text)
]
)
]
),
( "current_filter",
toVariant
( "_currentFilterName" :: Text,
[ (0 :: Word32, "*.jpg" :: Text),
(1 :: Word32, "image/jpeg" :: Text)
]
)
),
( "choices",
toVariant
[ ( "_choiceId" :: Text,
"_choiceLabel" :: Text,
[("_ccoId" :: Text, "_ccoLabel" :: Text)],
"_defaultChoiceId" :: Text
)
]
)
]
]
it "should decode response with all Nothings" $ \client -> do
let responseBody = successResponse [("uris", toVariant ["file:///a/b/c" :: Text])]
withMethodResponse client fileChooserInterface "OpenFile" responseBody $ do
info <- Portal.openFile def >>= Portal.await
info
`shouldBe` Just
(OpenFileResults {uris = ["file:///a/b/c"], choices = Nothing, currentFilter = Nothing})
it "should decode response with all Justs" $ \client -> do
let responseBody =
successResponse
[ ("uris", toVariant ["file:///a/b/c" :: Text]),
("choices", toVariant [("_comboId" :: Text, "_optionId" :: Text)]),
("current_filter", toVariant ("_filterId" :: Text, [(0 :: Word32, "*.md" :: Text)]))
]
withMethodResponse client fileChooserInterface "OpenFile" responseBody $ do
info <- Portal.openFile def >>= Portal.await
info
`shouldBe` Just
( OpenFileResults
{ uris = ["file:///a/b/c"],
choices = Just [ChoiceComboSelection {comboId = "_comboId", optionId = "_optionId"}],
currentFilter = Just Filter {name = "_filterId", fileTypes = [GlobFilter "*.md"]}
}
)
it "should fail to decode invalid response" $ \client ->
withMethodResponse client fileChooserInterface "OpenFile" (successResponse []) $ do
(Portal.openFile def >>= Portal.await) `shouldThrow` anyException
describe "saveFile" $ do
it "should encode request with all Nothings" $ \client -> do
body <- savingRequestArguments client fileChooserInterface "SaveFile" $ do
void (Portal.saveFile def)
body
`shouldBe` [ toVariantText "",
toVariantText "",
toVariantMap []
]
it "should encode request with all Justs" $ \client -> do
body <- savingRequestArguments client fileChooserInterface "SaveFile" $ do
void . Portal.saveFile $
SaveFileOptions
{ parentWindow = Just "_parentWindow",
title = Just "_title",
acceptLabel = Just "_acceptLabel",
modal = Just True,
filters =
Just
[ Filter
{ name = "_filterName",
fileTypes = [GlobFilter "*.txt", MimeFilter "application/json"]
}
],
currentFilter =
Just
( Filter
{ name = "_currentFilterName",
fileTypes = [GlobFilter "*.jpg", MimeFilter "image/jpeg"]
}
),
choices =
Just
[ ChoiceCombo
{ id = "_choiceId",
label_ = "_choiceLabel",
choices = [ChoiceComboOption {id = "_ccoId", label_ = "_ccoLabel"}],
defaultChoiceId = "_defaultChoiceId"
}
],
currentName = Just "some_name",
currentFolder = Just "/some/folder",
currentFile = Just "/some/file"
}
body
`shouldBe` [ toVariantText "_parentWindow",
toVariantText "_title",
toVariantMap
[ ("accept_label", toVariantText "_acceptLabel"),
("modal", toVariant True),
( "filters",
toVariant
[ ( "_filterName" :: Text,
[ (0 :: Word32, "*.txt" :: Text),
(1 :: Word32, "application/json" :: Text)
]
)
]
),
( "current_filter",
toVariant
( "_currentFilterName" :: Text,
[ (0 :: Word32, "*.jpg" :: Text),
(1 :: Word32, "image/jpeg" :: Text)
]
)
),
( "choices",
toVariant
[ ( "_choiceId" :: Text,
"_choiceLabel" :: Text,
[("_ccoId" :: Text, "_ccoLabel" :: Text)],
"_defaultChoiceId" :: Text
)
]
),
("current_name", toVariantText "some_name"),
("current_folder", toVariant ("/some/folder\0" :: ByteString)),
("current_file", toVariant ("/some/file\0" :: ByteString))
]
]
it "should decode response with all Nothings" $ \client -> do
let responseBody = successResponse [("uris", toVariant ["file:///a/b/c" :: Text])]
withMethodResponse client fileChooserInterface "SaveFile" responseBody $ do
info <- Portal.saveFile def >>= Portal.await
info
`shouldBe` Just
(SaveFileResults {uris = ["file:///a/b/c"], choices = Nothing, currentFilter = Nothing})
it "should decode response with all Justs" $ \client -> do
let responseBody =
successResponse
[ ("uris", toVariant ["file:///a/b/c" :: Text]),
("choices", toVariant [("_comboId" :: Text, "_optionId" :: Text)]),
("current_filter", toVariant ("_filterId" :: Text, [(0 :: Word32, "*.md" :: Text)]))
]
withMethodResponse client fileChooserInterface "SaveFile" responseBody $ do
info <- Portal.saveFile def >>= Portal.await
info
`shouldBe` Just
( SaveFileResults
{ uris = ["file:///a/b/c"],
choices = Just [ChoiceComboSelection {comboId = "_comboId", optionId = "_optionId"}],
currentFilter = Just Filter {name = "_filterId", fileTypes = [GlobFilter "*.md"]}
}
)
it "should fail to decode invalid response" $ \client ->
withMethodResponse client fileChooserInterface "SaveFile" (successResponse []) $ do
(Portal.openFile def >>= Portal.await) `shouldThrow` anyException