Skip to content

Commit

Permalink
Adds hwllo wrold server tests
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-k committed Nov 3, 2023
1 parent 27034d5 commit f469c26
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 4 deletions.
6 changes: 4 additions & 2 deletions mig/mig.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ test-suite mig-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Test.Api
Test.Api Test.Server.Hello
hs-source-dirs:
test
default-extensions:
Expand All @@ -107,9 +107,11 @@ test-suite mig-test
AllowAmbiguousTypes
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -Wunused-packages -threaded -rtsopts -with-rtsopts=-N
build-depends:
base >=4.7 && <5
aeson
, base >=4.7 && <5
, containers
, hspec
, http-types
, mig
, text
default-language: GHC2021
3 changes: 3 additions & 0 deletions mig/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,18 @@ tests:
main: Spec.hs
other-modules:
Test.Api
Test.Server.Hello
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- aeson
- base >= 4.7 && < 5
- containers
- mig
- hspec
- text
- http-types

2 changes: 2 additions & 0 deletions mig/src/Mig/Core/Types/Http.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ data Response = Response
, body :: ResponseBody
-- ^ response body
}
deriving (Show, Eq)

-- | Response with no content
noContentResponse :: Status -> Response
Expand All @@ -56,6 +57,7 @@ data ResponseBody
= RawResp MediaType BL.ByteString
| FileResp FilePath
| StreamResp
deriving (Show, Eq)

-- | Http request
data Request = Request
Expand Down
5 changes: 4 additions & 1 deletion mig/test/Spec.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import Test.Api qualified as Api
import Test.Server.Hello qualified as Server.Hello

import Test.Hspec

main :: IO ()
main =
hspec $ Api.spec
hspec $ do
Api.spec
Server.Hello.spec
2 changes: 1 addition & 1 deletion mig/test/Test/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Mig.Core.Api
import Test.Hspec

spec :: Spec
spec = describe "Api tests" $ do
spec = describe "api" $ do
checkRoutes
checkCaptures
checkFlatApi
Expand Down
85 changes: 85 additions & 0 deletions mig/test/Test/Server/Hello.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
module Test.Server.Hello (spec) where

import Data.Aeson qualified as Json
import Data.Map.Strict qualified as Map
import Data.Text (Text)
import Mig.Core
import Mig.Core qualified as Request (Request (..))
import Network.HTTP.Types.Method (methodGet, methodPost)
import Network.HTTP.Types.Status (ok200)
import Test.Hspec

-- hello world server

server :: Server IO
server =
"api/v1"
/. [ "hello" /. handleHello
, "bye" /. handleBye
]

handleHello :: Get IO (Resp Json Text)
handleHello = pure $ ok "hello"

handleBye :: Get IO (Resp Json Text)
handleBye = pure $ ok "bye"

-- tests

-- we use low-level representation of server as a function: Request -> m (Maybe Response)
-- to check server properties without wpawning a full server environment
spec :: Spec
spec = describe "hello world server" $ do
describe "plain route finder" $ specBy plainApiStrategy
describe "tree route finder" $ specBy treeApiStrategy

specBy :: FindRoute nf IO -> Spec
specBy finder = do
checkPositiveRoutes
checkNegativeRoutes
where
serverFun :: ServerFun IO
serverFun = fromServer finder server

checkPositiveRoutes = do
it "call routes (positive case)" $ do
serverFun helloReq `shouldReturn` helloResp
serverFun byeReq `shouldReturn` byeResp

checkNegativeRoutes = do
describe "negative cases" $ do
it "wrong path" $ do
serverFun emptyReq `shouldReturn` Nothing
serverFun wrongPathReq `shouldReturn` Nothing
it "wrong method" $ do
serverFun (helloReq{Request.method = methodPost}) `shouldReturn` Nothing
it "wrong output media type" $ do
serverFun (helloReq{Request.headers = Map.fromList [("Accept", "text/html")]}) `shouldReturn` Nothing

helloReq = emptyReq{path = ["api", "v1", "hello"]}
helloResp = Just $ jsonResp @Text "hello"

byeReq = emptyReq{path = ["api", "v1", "bye"]}
byeResp = Just $ jsonResp @Text "bye"

wrongPathReq = emptyReq{path = ["api", "v2", "hello"]}

emptyReq :: Request
emptyReq =
Request
{ path = []
, query = mempty
, capture = mempty
, headers = Map.fromList [("Accept", "application/json")]
, method = methodGet
, readBody = pure (Right "")
, isSecure = False
}

jsonResp :: (Json.ToJSON a) => a -> Response
jsonResp a =
Response
{ status = ok200
, headers = [("Content-Type", "application/json")]
, body = RawResp "application/json" (Json.encode a)
}

0 comments on commit f469c26

Please sign in to comment.