packages feed

wai-make-assets-0.1: test/Network/Wai/MakeAssetsSpec.hs

{-# LANGUAGE OverloadedStrings #-}

module Network.Wai.MakeAssetsSpec where

import           Control.Exception
import           Control.Lens
import           Data.ByteString.Lazy (isPrefixOf)
import           Data.List (intercalate)
import           Network.Wai.Handler.Warp
import           Network.Wreq
import           System.Directory
import           System.IO.Silently
import           Test.Hspec
import           Test.Mockery.Directory

import           Network.Wai.MakeAssets

spec :: Spec
spec = do
  around_ silence $ do
    describe "serverClient" $ do
      it "returns static files" $ do
        inTempDirectory $ do
          createDirectoryIfMissing True "client"
          createDirectoryIfMissing True "assets"
          writeFile "assets/foo" "bar"
          writeFile "client/Makefile" "all:\n\ttrue"
          testWithApplication serveAssets $ \ port -> do
            let url = "http://localhost:" ++ show port ++ "/foo"
            response <- get url
            response ^. responseBody `shouldBe` "bar"

      it "runs 'make' in 'client/' before answering requests" $ do
        inTempDirectory $ do
          createDirectoryIfMissing True "client"
          createDirectoryIfMissing True "assets"
          writeFile "client/Makefile" "all:\n\techo bar > ../assets/foo"
          testWithApplication serveAssets $ \ port -> do
            let url = "http://localhost:" ++ show port ++ "/foo"
            response <- get url
            response ^. responseBody `shouldBe` "bar\n"

      it "returns the error messages in case 'make' fails" $ do
        inTempDirectory $ do
          createDirectoryIfMissing True "client"
          createDirectoryIfMissing True "assets"
          writeFile "client/Makefile" "all:\n\t>&2 echo error message ; false"
          testWithApplication serveAssets $ \ port -> do
            let url = "http://localhost:" ++ show port ++ "/foo"
            response <- getWith acceptErrors url
            let body = response ^. responseBody
            body `shouldSatisfy` ("make error:\nerror message\n" `isPrefixOf`)

      context "complains about missing files or directories" $ do
        it "missing client/" $ do
          inTempDirectory $ do
            createDirectoryIfMissing True "assets"
            let expected = intercalate "\n" $
                  "missing directory: 'client/'" :
                  "Please create 'client/'." :
                  "(You should put sources for assets in there.)" :
                  []
            testWithApplication serveAssets (\ _ -> return ())
              `shouldThrow` errorCall expected

        it "missing client/Makefile" $ do
          inTempDirectory $ do
            createDirectoryIfMissing True "client"
            createDirectoryIfMissing True "assets"
            let expected = intercalate "\n" $
                  "missing file: 'client/Makefile'" :
                  "Please create 'client/Makefile'." :
                  "(Which will be invoked to build the assets. It should put compiled assets into 'assets/'.)" :
                  []
            testWithApplication serveAssets (\ _ -> return ())
              `shouldThrow` errorCall expected

        it "missing assets/" $ do
          inTempDirectory $ do
            touch "client/Makefile"
            let expected = intercalate "\n" $
                  "missing directory: 'assets/'" :
                  "Please create 'assets/'." :
                  "(All files in 'assets/' will be served.)" :
                  []
            catch (testWithApplication serveAssets (\ _ -> return ())) $
              \ (ErrorCall message) -> do
                message `shouldBe` expected

acceptErrors :: Options
acceptErrors = defaults &
  checkStatus .~ Just (\ _ _ _ -> Nothing)