module Main where import Control.Monad.Error ( MonadError ) import qualified Network.WindowsLive.App as Live import qualified Data.URLEncoded as URLEnc import Network.WindowsLive.Login ( processToken, getLoginUrl, baseUrl ) import Network.WindowsLive.ConsentToken ( processConsentToken ) import Network.URI ( relativeTo, uriQuery ) import Test.HUnit import System.Exit import System.IO ( stderr ) -- A login token from a response from login.live.com loginToken :: String loginToken = "0HlkHc47u2pVQKrkm3zzvvfUbIxS%2FfdOkiHsvbUnUUeVlZ21O%2F%2BYbvXDGTEMc%2BG\ \%2BQ78pf8LLG1lsO3FAcbsJdeMcOZhwuaqubx7%2BDZq2WtOdK%2F3XJw39kWMPSvUrzwSa\ \6aT1l1oi6UHPFuBpKSVq4NXHbnZb0IfSWwv%2BNa3BkiIY%2BZyxCjV5k%2BYbLD4Xz9%2B\ \s" -- A consent token from a response from consent.live.com consentToken :: String consentToken = "eact%3DvFcrnZDughQ9O2jrtckfcEF26jJcvdYE6U3Dh%252Fs6y2ZAB8T%252FyaFoehz1\ \Y8Flp%252Bh6o3FB2BFormNo4on3xXDYmCc6NXnw4HLnO314bmsl4apTga1ekfbo49xfzjh\ \1uncXJNwKrRYdeF5qeqBAdtdFbz3vwKsqxlbLuMnEdImGervS5UNE88lbGaS7bVv28FySwQ\ \d1U9dlOi5H%252FUf7X9hfPCVquifMG%252BFLfdUgRUFRbFXJlp%252F8iV4J7uzV1JX3Q\ \l7TAKtj%252FOHeL0Cmr5q5qJZxO55JljZwFfhy6NNKcZniQzWFsKqFAAzEYEnBuNSU4sRR\ \dm5hHS7LzrTdSdo1EcZLT01PdmE%252FcUEH2W9m7cO1FNuKSzxWcdi%252BojCUK6UwbSD\ \TxFMs3zEiUHsHh5Ue24JCq9ocTpPg3GJTebVLLVltQHfvXXsycS12FetlrGxbgvxrfqqX7F\ \gw04aDyQjCOFidub9Rtfh9%252BF4VsqAHS2uedCs%252FC7kjBT8pwyP0GBeELRlDmZ1Uy\ \3LwZSNK%252FycC8so%252BaH%252FQAQJDfIk%252F539ZiNkQkyukrRx9eceirNr24gUj\ \8h7%252BzC9%252FuPAkubOJAXOVKx0ROr1EcDJZpUeLax4RDx53tM0S5egPgmpLQ%252Br\ \gdWeCgWZuXmah71lWt65ewqggRs%252FEWsBvFbqZ0UVWQnN6iOx1h%252B6qrDjS5wx5Nv\ \tmT6E1rHGzPkLUAh8BT1TioltoLwpnZYRr8vimahrYgI19QSft5Lplouay8t9POSCG%252B\ \RrZLLGUXvvyW6EkdNLdNQbeudcBt3kE7H5iYiZWL8n0nAukqJtEql100tKEfntAW1PZQ4Zy\ \yIA%252F%252BaXwfVXOVztu1GnYmVGl8uK4%252BqsqW797bgvktj%252BroGfY5CbBwlU\ \rywUA2Zy4NupJH3jm0rf5PvN6UzyscygPTNnPxgrzvdVHJizvz9%252BIcf%252F%252Bs8\ \Oh4OIiwXKBXW4CvmVu1yFqD%252FvkrqF8P4UpqE7fiJOP20Lw%252FfRpac5Dl0gvJK08I\ \E8unTy8s0uKwdy0BIa2EpZV4Nlupp%252BWfZl2rgYDjtF8rCzA73LMtkrUpByO3JwbmRiB\ \URjvYJR%252FMvdlcWaw1CTt%252B6pOrr9YLesmJe%252FxqjfjquDx%252B%252BdkJRF\ \GT%252B2gGo4YfTTpoy7IsiQy1b1NDVVJRYmINmIj1HLOuHbKl%252F0JMOJMr0jjn7GXwT\ \wgSCg3TMZtK1W7xdoqOC8xOFdw" appId :: String appId = "000000004C00F507" secret :: String secret = "wfMkKPJdTHHi64sWrmQlGE9uBY27Pjgl" getApp :: MonadError e m => m Live.App getApp = Live.new appId secret -- Very weak tests: test that processing these good strings does not -- throw an exception processLoginTest :: Live.App -> Test processLoginTest app = test (processToken app loginToken >> return () :: IO ()) processConsentTest :: Live.App -> Test processConsentTest app = test (processConsentToken app consentToken >> return () :: IO ()) badAppTest :: Test badAppTest = test [ "validates secret" ~: assert $ fails (Live.new appId "") , "validates app id" ~: assert $ fails (Live.new "" secret) ] where fails :: Either String Live.App -> Bool fails (Left _) = True fails _ = False loginUrlTest :: Live.App -> Test loginUrlTest app = test $ do let mkt = "> =&abc#://" ctx = "123/?<{}!456" relLoginUri = getLoginUrl app (Just ctx) (Just mkt) uri <- case relLoginUri `relativeTo` baseUrl of Nothing -> fail $ "Failed to combine: " ++ show relLoginUri ++ " and " ++ show baseUrl Just u -> return u q <- case uriQuery uri of '?':qs -> URLEnc.importString qs "" -> URLEnc.importString "" unexpected -> fail $ "No ? at start of query string: " ++ show unexpected let assertQ (k, v) = assertEqual k v =<< URLEnc.lookup1 k q mapM_ assertQ [ ("appid", Live.appId app) , ("mkt", mkt) , ("appctx", ctx) ] main :: IO () main = do app <- getApp let tests = [ processConsentTest app , processLoginTest app , loginUrlTest app , badAppTest ] (testResults, _) <- runTestText (putTextToHandle stderr False) $ test tests exitWith $ if (errors testResults + failures testResults) /= 0 then ExitFailure 1 else ExitSuccess