Add post example (#41)
This commit is contained in:
parent
4ca1378f7d
commit
b8169e4fdb
10
docs/Examples/Post/Example.md
Normal file
10
docs/Examples/Post/Example.md
Normal file
@ -0,0 +1,10 @@
|
||||
# Post Example
|
||||
|
||||
This is a basic example of handling a Post. It will respond to a HTTP POST on
|
||||
any path with the post body in the response body.
|
||||
|
||||
To run the example server, run:
|
||||
|
||||
```bash
|
||||
make example EXAMPLE=Post
|
||||
```
|
31
docs/Examples/Post/Main.purs
Normal file
31
docs/Examples/Post/Main.purs
Normal file
@ -0,0 +1,31 @@
|
||||
module Post where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.Eff.Console as Console
|
||||
import Data.StrMap as StrMap
|
||||
import HTTPure as HTTPure
|
||||
|
||||
-- | Serve the example server on this port
|
||||
port :: Int
|
||||
port = 8084
|
||||
|
||||
-- | Shortcut for `show port`
|
||||
portS :: String
|
||||
portS = show port
|
||||
|
||||
-- | Route to the correct handler
|
||||
router :: forall e. HTTPure.Request -> HTTPure.ResponseM e
|
||||
router (HTTPure.Post _ _ body) = pure $ HTTPure.OK StrMap.empty body
|
||||
router _ = pure $ HTTPure.OK StrMap.empty ""
|
||||
|
||||
-- | Boot up the server
|
||||
main :: forall e. HTTPure.ServerM (console :: Console.CONSOLE | e)
|
||||
main = HTTPure.serve port router do
|
||||
Console.log $ " ┌───────────────────────────────────────────┐"
|
||||
Console.log $ " │ Server now up on port " <> portS <> " │"
|
||||
Console.log $ " │ │"
|
||||
Console.log $ " │ To test, run: │"
|
||||
Console.log $ " │ > curl -XPOST --data test localhost:" <> portS <> " │"
|
||||
Console.log $ " │ # => test │"
|
||||
Console.log $ " └───────────────────────────────────────────┘"
|
@ -3,37 +3,48 @@ module HTTPure.IntegrationSpec where
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.Eff.Class as EffClass
|
||||
import Data.StrMap as StrMap
|
||||
import Test.Spec as Spec
|
||||
import Test.Spec.Assertions as Assertions
|
||||
|
||||
import HTTPure.SpecHelpers as SpecHelpers
|
||||
|
||||
import Headers as Headers
|
||||
import HelloWorld as HelloWorld
|
||||
import MultiRoute as MultiRoute
|
||||
import Headers as Headers
|
||||
import Post as Post
|
||||
|
||||
headersSpec :: SpecHelpers.Test
|
||||
headersSpec = Spec.it "runs the headers example" do
|
||||
EffClass.liftEff Headers.main
|
||||
header <- SpecHelpers.getHeader 8082 StrMap.empty "/" "X-Example"
|
||||
header `Assertions.shouldEqual` "hello world!"
|
||||
response <- SpecHelpers.get 8082 (StrMap.singleton "X-Input" "test") "/"
|
||||
response `Assertions.shouldEqual` "test"
|
||||
|
||||
helloWorldSpec :: SpecHelpers.Test
|
||||
helloWorldSpec = Spec.it "runs the hello world example" do
|
||||
EffClass.liftEff HelloWorld.main
|
||||
response <- SpecHelpers.get "http://localhost:8080"
|
||||
response <- SpecHelpers.get 8080 StrMap.empty "/"
|
||||
response `Assertions.shouldEqual` "hello world!"
|
||||
|
||||
multiRouteSpec :: SpecHelpers.Test
|
||||
multiRouteSpec = Spec.it "runs the multi route example" do
|
||||
EffClass.liftEff MultiRoute.main
|
||||
hello <- SpecHelpers.get "http://localhost:8081/hello"
|
||||
hello <- SpecHelpers.get 8081 StrMap.empty "/hello"
|
||||
hello `Assertions.shouldEqual` "hello"
|
||||
goodbye <- SpecHelpers.get "http://localhost:8081/goodbye"
|
||||
goodbye <- SpecHelpers.get 8081 StrMap.empty "/goodbye"
|
||||
goodbye `Assertions.shouldEqual` "goodbye"
|
||||
|
||||
headersSpec :: SpecHelpers.Test
|
||||
headersSpec = Spec.it "runs the headers example" do
|
||||
EffClass.liftEff Headers.main
|
||||
header <- SpecHelpers.getHeader "http://localhost:8082" "X-Example"
|
||||
header `Assertions.shouldEqual` "hello world!"
|
||||
postSpec :: SpecHelpers.Test
|
||||
postSpec = Spec.it "runs the post example" do
|
||||
EffClass.liftEff Post.main
|
||||
response <- SpecHelpers.post 8084 StrMap.empty "/" "test"
|
||||
response `Assertions.shouldEqual` "test"
|
||||
|
||||
integrationSpec :: SpecHelpers.Test
|
||||
integrationSpec = Spec.describe "Integration" do
|
||||
headersSpec
|
||||
helloWorldSpec
|
||||
multiRouteSpec
|
||||
headersSpec
|
||||
postSpec
|
||||
|
@ -21,7 +21,7 @@ serveSpec :: SpecHelpers.Test
|
||||
serveSpec = Spec.describe "serve" do
|
||||
Spec.it "boots a server on the given port" do
|
||||
EffClass.liftEff $ Server.serve 7901 mockRouter $ pure unit
|
||||
out <- SpecHelpers.get "http://localhost:7901/test"
|
||||
out <- SpecHelpers.get 7901 StrMap.empty "/test"
|
||||
out `Assertions.shouldEqual` "/test"
|
||||
|
||||
serverSpec :: SpecHelpers.Test
|
||||
|
@ -7,6 +7,7 @@ import Control.Monad.Eff as Eff
|
||||
import Control.Monad.Eff.Exception as Exception
|
||||
import Control.Monad.ST as ST
|
||||
import Data.Maybe as Maybe
|
||||
import Data.Options as Options
|
||||
import Data.String as StringUtil
|
||||
import Data.StrMap as StrMap
|
||||
import Node.Encoding as Encoding
|
||||
@ -40,19 +41,29 @@ type Test = Spec.Spec TestEffects Unit
|
||||
-- | The type for the entire test suite.
|
||||
type TestSuite = Eff.Eff TestEffects Unit
|
||||
|
||||
-- | Given an HTTPClient.Request, close the request stream so the request can be
|
||||
-- | fired.
|
||||
endRequest :: forall e.
|
||||
HTTPClient.Request -> Eff.Eff (http :: HTTP.HTTP | e) Unit
|
||||
endRequest request = Stream.end (HTTPClient.requestAsStream request) $ pure unit
|
||||
|
||||
-- | Given a URL, a failure handler, and a success handler, create an HTTP
|
||||
-- | client request.
|
||||
getResponse :: forall e.
|
||||
String ->
|
||||
Aff.Aff (http :: HTTP.HTTP | e) HTTPClient.Response
|
||||
getResponse url = Aff.makeAff \_ success ->
|
||||
HTTPClient.requestFromURI url success >>= endRequest
|
||||
request :: forall e.
|
||||
Int ->
|
||||
String ->
|
||||
StrMap.StrMap String ->
|
||||
String ->
|
||||
String ->
|
||||
Aff.Aff (http :: HTTP.HTTP | e) HTTPClient.Response
|
||||
request port method headers path body = Aff.makeAff \_ success -> do
|
||||
req <- HTTPClient.request options success
|
||||
let stream = HTTPClient.requestAsStream req
|
||||
_ <- Stream.writeString stream Encoding.UTF8 body noop
|
||||
Stream.end stream noop
|
||||
noop
|
||||
where
|
||||
noop = pure unit
|
||||
options =
|
||||
HTTPClient.method `Options.assoc` method <>
|
||||
HTTPClient.hostname `Options.assoc` "localhost" <>
|
||||
HTTPClient.port `Options.assoc` port <>
|
||||
HTTPClient.path `Options.assoc` path <>
|
||||
HTTPClient.headers `Options.assoc` HTTPClient.RequestHeaders headers
|
||||
|
||||
-- | Given an ST String buffer and a new string, concatenate that new string
|
||||
-- | onto the ST buffer.
|
||||
@ -71,8 +82,22 @@ toString response = Aff.makeAff \_ success -> do
|
||||
|
||||
-- | Run an HTTP GET with the given url and return an Aff that contains the
|
||||
-- | string with the response body.
|
||||
get :: forall e. String -> Aff.Aff (HTTPRequestEffects e) String
|
||||
get url = getResponse url >>= toString
|
||||
get :: forall e.
|
||||
Int ->
|
||||
StrMap.StrMap String ->
|
||||
String ->
|
||||
Aff.Aff (HTTPRequestEffects e) String
|
||||
get port headers path = request port "GET" headers path "" >>= toString
|
||||
|
||||
-- | Run an HTTP POST with the given url and body and return an Aff that
|
||||
-- | contains the string with the response body.
|
||||
post :: forall e.
|
||||
Int ->
|
||||
StrMap.StrMap String ->
|
||||
String ->
|
||||
String ->
|
||||
Aff.Aff (HTTPRequestEffects e) String
|
||||
post port headers path body = request port "POST" headers path body >>= toString
|
||||
|
||||
-- | Convert a request to an Aff containing the string with the given header
|
||||
-- | value.
|
||||
@ -85,10 +110,13 @@ extractHeader header = unmaybe <<< lookup <<< HTTPClient.responseHeaders
|
||||
-- | Run an HTTP GET with the given url and return an Aff that contains the
|
||||
-- | string with the header value for the given header.
|
||||
getHeader :: forall e.
|
||||
Int ->
|
||||
StrMap.StrMap String ->
|
||||
String ->
|
||||
String ->
|
||||
Aff.Aff (HTTPRequestEffects e) String
|
||||
getHeader url header = extractHeader header <$> getResponse url
|
||||
getHeader port headers path header =
|
||||
extractHeader header <$> request port "GET" headers path ""
|
||||
|
||||
-- | An effect encapsulating creating a mock request object
|
||||
foreign import data MOCK_REQUEST :: Eff.Effect
|
||||
|
Loading…
Reference in New Issue
Block a user