packages feed

pinterest-url-normalizer-0.1.1.0: test/Spec.hs

module Main (main) where

import SavePinner.PinterestURL
import System.Exit (exitFailure)

main :: IO ()
main = do
  results <- sequence
    [ expectNormalized
        "regional pin"
        "https://de.pinterest.com/pin/987654321/?utm_source=test"
        "https://www.pinterest.com/pin/987654321/"
    , expectPinId
        "slugged pin"
        "https://www.pinterest.com/pin/roasted-pineapple--68746366275/"
        "68746366275"
    , expectKind "short URL" "https://pin.it/AbC123?source=share" Short
    , expectNormalized
        "short URL normalization"
        "https://pin.it/AbC123?source=share"
        "https://pin.it/AbC123/"
    , expectKind "profile" "https://pinterest.com/savepinner/" Profile
    , expectKind "board" "https://www.pinterest.com/savepinner/media-tools/" Board
    , expectKind
        "ideas"
        "https://www.pinterest.com/ideas/space-wallpaper-4k/926295399832/"
        Ideas
    , expectRejected "lookalike" "https://www.pinterest.com.evil.example/pin/123/"
    , expectRejected "HTTP" "http://www.pinterest.com/pin/123/"
    , expectRejected "credentials" "https://user:pass@www.pinterest.com/pin/123/"
    , expectRejected "non-standard port" "https://www.pinterest.com:8443/pin/123/"
    , expectRejected "reserved path" "https://www.pinterest.com/search/pins/?q=cats"
    , expectEqual "country host" True (isPinterestHost "PINTEREST.CO.UK")
    , expectEqual "lookalike host" False (isPinterestHost "pinterest.co.uk.evil.example")
    ]
  if and results then putStrLn "All tests passed." else exitFailure

expectNormalized :: String -> String -> String -> IO Bool
expectNormalized label input expected =
  expectEqual label (Right expected) (normalizePinterestUrl input)

expectKind :: String -> String -> UrlKind -> IO Bool
expectKind label input expected =
  case parsePinterestUrl input of
    Right parsed -> expectEqual label expected (urlKind parsed)
    Left err -> reportFailure label ("unexpected parse error: " ++ show err)

expectPinId :: String -> String -> String -> IO Bool
expectPinId label input expected =
  case parsePinterestUrl input of
    Right parsed -> expectEqual label (Just expected) (pinId parsed)
    Left err -> reportFailure label ("unexpected parse error: " ++ show err)

expectRejected :: String -> String -> IO Bool
expectRejected label input = expectEqual label False (isPinterestUrl input)

expectEqual :: (Eq value, Show value) => String -> value -> value -> IO Bool
expectEqual label expected actual
  | expected == actual = putStrLn ("PASS: " ++ label) >> pure True
  | otherwise = reportFailure label ("expected " ++ show expected ++ ", got " ++ show actual)

reportFailure :: String -> String -> IO Bool
reportFailure label message = putStrLn ("FAIL: " ++ label ++ " — " ++ message) >> pure False