module System.Taffybar.AuthSpec (spec) where import Data.List (intercalate) import System.FilePath ((), (<.>)) import Text.Printf (printf) import Test.Hspec import Test.Hspec.Core.Spec (getSpecDescriptionPath) import Test.Hspec.Golden hiding (golden) import System.Taffybar.Auth import System.Taffybar.Test.UtilSpec (withMockCommand) spec :: Spec spec = aroundAll_ (withMockPass mockDb) $ describe "passGet" $ do golden "get a password" $ show <$> passGet "hello" golden "get a password with info" $ show <$> passGet "multiline" golden "missing entry" $ show <$> passGet "missing" golden :: String -> IO String -> Spec golden description runAction = do path <- (++ words description) <$> getSpecDescriptionPath it description $ taffybarGolden (intercalate "-" path) <$> runAction taffybarGolden :: String -> String -> Golden String taffybarGolden name output = Golden { output , encodePretty = show , writeToFile = writeFile , readFromFile = readFile , goldenFile = "test/data/" name <.> "golden" , actualFile = Nothing , failFirstTime = True } mockDb :: [MockEntry] mockDb = [ mockEntry "hello" "xyzzy" [] , mockEntry "multiline" "secret" [("Username", "fred"), ("silly", "")] , fallbackEntry "" "Error: is not in the password store.\n" 1 ] withMockPass :: [MockEntry] -> IO a -> IO a withMockPass db = withMockCommand "pass" (mockScript db) data MockEntry = MockEntry { passName :: String , out :: String , err :: String , status :: Int } deriving (Show, Read, Eq) mockEntry :: String -> String -> [(String, String)] -> MockEntry mockEntry passName key info = MockEntry { passName, out = passFile key info, err = "", status = 0 } passFile :: String -> [(String, String)] -> String passFile key info = unlines (key:[k ++ ": " ++ v | (k, v) <- info]) fallbackEntry :: String -> String -> Int -> MockEntry fallbackEntry out err status = MockEntry { passName = "", .. } mockScript :: [MockEntry] -> String mockScript db = unlines ("#!/usr/bin/env bash":map makeEntry db) where makeEntry MockEntry{..} = printf template passName out err status template = unlines [ "pass_name='%s'" , "if [ -z \"$pass_name\" -o \"$2\" = \"$pass_name\" ]; then" , " echo -n '%s'" , " >&2 echo '%s'" , " exit %d" , "fi" ]