module Main where import Control.Monad.IO.Class (liftIO) import Web.Scotty hiding (request) import Web.Scotty.Fay import qualified Network.HTTP.Types as HTTP import Network.Wai import Network.Wai.Test import Test.Framework import Test.Framework.Providers.HUnit import qualified Test.HUnit.Base as H import System.Directory main :: IO () main = do dir <- getCurrentDirectory putStrLn dir tests >>= defaultMain tests :: IO [Test] tests = sequence [ waiTest "compiles Fay" test_compilesFay , waiTest "serveFay captures everything under base" test_capturesEverything , waiTest "imports" test_imports , waiTest "directory traversal" test_directoryTraversal , return $ testGroup "configuration" $ [ testCase "configuring src dir" test_configuringSrcDir , testCase "configuring base path" test_configuringBasePath ] ] waiTest :: String -> Session () -> IO Test waiTest name session = do app' <- scottyApp app return $ testCase name $ runSession session app' app :: ScottyM () app = do serveFay (under "/fay" . from "test/fay-resources") get "/" $ do text "this is the root" get "/fay/shouldnt-get-here" $ do text "it shouldn't get here" -- This is handy to have when debugging interactively. runScottyApp :: IO () runScottyApp = scotty 3000 app assertBool :: String -> Bool -> Session () assertBool str p = liftIO $ H.assertBool str p assertNotStatus :: Int -> SResponse -> Session () assertNotStatus i SResponse{simpleStatus = s} = assertBool (concat [ "Expected a status other than " , show i ]) $ i /= sc where sc = HTTP.statusCode s assertJavaScriptRenderedOk :: SResponse -> Session () assertJavaScriptRenderedOk response = do assertStatus 200 response assertHeader "Content-Type" "text/javascript" response test_compilesFay :: Session () test_compilesFay = do let req = setPath defaultRequest "/fay/Fact.hs" resp <- request req assertJavaScriptRenderedOk resp test_capturesEverything :: Session () test_capturesEverything = do let req = setPath defaultRequest "/fay/shouldnt-get-here" resp <- request req assertNotStatus 200 resp test_imports :: Session () test_imports = do let req = setPath defaultRequest "/fay/Fib.hs" resp <- request req assertJavaScriptRenderedOk resp test_directoryTraversal :: Session () test_directoryTraversal = do let req = setPath defaultRequest "/fay/test/Fib/../Fib.hs" resp <- request req assertNotStatus 200 resp assertEq :: (Eq a, Show a) => a -> a -> H.Assertion assertEq = H.assertEqual "" test_configuringSrcDir :: H.Assertion test_configuringSrcDir = assertEq "src" $ (configSrcDir . buildConfig $ (under "/js" . from "src")) test_configuringBasePath :: H.Assertion test_configuringBasePath = assertEq "/js" $ (configBasePath . buildConfig $ (under "/js" . from "src"))