brian-watkins / elm-spec / Spec.Http

Observe, and make claims about HTTP requests during a spec.

Here's an example:

First, create an HttpResponseStub that defines the response to return when a request is sent by the program.

successStub : HttpResponseStub
successStub =
  Spec.Http.Stub.for (Spec.Http.Route.post "http://fake-api.com/api/sports")
    |> Spec.Http.Stub.withStatus 201

Now, you could write a spec that checks to see if the request body contains a value:

Spec.describe "some request"
[ Spec.scenario "the post is successful" (
    Spec.given (
      Spec.Setup.init (App.init testFlags)
        |> Spec.Setup.withView App.view
        |> Spec.Setup.withUpdate App.update
        |> Spec.Http.Stub.serve [ successStub ]
    )
    |> Spec.when "the request is sent"
      [ Spec.Markup.target << by [ id "request-button" ]
      , Spec.Markup.Event.click
      ]
    |> Spec.it "sends the correct request" (
      Spec.Http.observeRequests
          (Spec.Http.Route.post "http://fake-api.com/api/sports")
        |> Spec.expect (Spec.Claim.isListWhere
          [ Spec.Http.body
              (Spec.Http.asJson <|
                Json.field "name" Json.string)
              (Spec.Claim.isEqual Debug.toString "bowling")
          ]
        )
    )
  )
]

Observe HTTP Requests


type HttpRequest

Represents an HTTP request made by the program in the course of the scenario.

observeRequests : Route.HttpRoute -> Spec.Observer.Observer model (List HttpRequest)

Observe HTTP requests that match the given route.

For example:

Spec.Http.observeRequests (Spec.Http.Route.get "http://fake.com/fake")
  |> Spec.expect (Spec.Claim.isListWhere
    [ Spec.Http.header "Authorization" <|
      Spec.Claim.isSomethingWhere <|
      Spec.Claim.isStringContaining 1 "some-fun-token"
    ]
  )

clearRequestHistory : Spec.Step.Step model msg

A step that clears the history of HTTP requests received.

Any HTTP requests made prior to executing this step will not be observed.

It can be useful to clear the HTTP request history when a scenario results in many HTTP requests, but you care about observing only those that occur after a certain point.

Make Claims About HTTP Requests

url : Spec.Claim.Claim String -> Spec.Claim.Claim HttpRequest

Claim that the url of an HTTP request satisfies the given claim.

In the example below, we claim that there is one GET request to a url containing fake.com and that url has the query parameter sport=bowling.

Spec.Http.observeRequests (Spec.Http.Route.route "GET" <| Matching "fake\\.com")
  |> Spec.expect (Spec.Claim.isListWhere
    [ Spec.Http.url <|
      Spec.Claim.isStringContaining 1 "sport=bowling"
    ]
  )

This claims makes the most sense when observing requests that match a route defined with a regular expression, as in the example above.

header : String -> Spec.Claim.Claim (Maybe String) -> Spec.Claim.Claim HttpRequest

Claim that an HTTP request has a header that satisfies the given claim.

For example, if the observed request has an Authorization header with the value Bearer some-fun-token, then the following claim would be accepted:

Spec.Http.header "Authorization" <|
  Spec.Claim.isSomethingWhere <|
  Spec.Claim.isStringContaining 1 "some-fun-token"

Note that HTTP header names are case-insensitive, so the capitalization of the first argument doesn't matter.

body : HttpRequestDataAssertion a -> Spec.Claim.Claim a -> Spec.Claim.Claim HttpRequest

Claim that an HTTP request has a body with data that satisfies the given claim.

For example, if the body of the observed request were {"sport":"bowling"}, then the following claim would be accepted:

Spec.Http.body
  (Spec.Http.asJson <|
    Json.Decode.field "sport" Json.Decode.string)
  (Spec.Claim.isEqual Debug.toString "bowling")

bodyPart : String -> HttpRequestDataAssertion a -> Spec.Claim.Claim (List a) -> Spec.Claim.Claim HttpRequest

Claim that an HTTP request has a multipart body with a named part that satisfies the given claim.

There can be multiple parts, all with the same name. They should all be the same type of data.

For example, if the observed request had a multipart body with a part called image that contains a file named fun-image.png, then the following claim would be accepted:

Spec.Http.bodyPart "image" Spec.Http.asFile <|
  Spec.Claim.isListWhere
    [ Spec.Claim.specifyThat File.name <|
        Spec.Claim.isEqual Debug.toString "fun-image.png"
    ]


type HttpRequestDataAssertion a

Asserts that an HTTP request body (or part of that body) is data of a certain type.

asText : HttpRequestDataAssertion String

Claim that some HTTP request data is text that satisfies the given claim.

Note: If you create a request with Http.emptyBody then the given claim will be evaluated against the empty string.

asJson : Json.Decode.Decoder a -> HttpRequestDataAssertion a

Claim that some HTTP request data is text that can be decoded with the given JSON decoder into a value that satisfies the given claim.

For example, if the body of the observed request were {"sport":"bowling"}, then the following claim would be accepted:

Spec.Http.body
  (Spec.Http.asJson <|
    Json.Decode.field "sport" Json.Decode.string)
  (Spec.Claim.isEqual Debug.toString "bowling")

asFile : HttpRequestDataAssertion File

Claim that some HTTP request data is a File that satisfies the given claim.

For example, if the body of an observed request is a File with the name funFile.txt, then the following claim would be accepted:

Spec.Http.body Spec.Http.asFile
  <| Spec.Claim.specifyThat File.name
  <| Claim.isStringContaining 1 "funFile.txt"


type alias Blob =
{ mimeType : String
, data : Bytes 
}

When Bytes are sent as the HTTP request body or as part of the HTTP request body, a MIME type must be specified. This value groups Bytes together with their associated MIME type.

asBlob : HttpRequestDataAssertion Blob

Claim that some HTTP request data is a Blob that satisfies the given claim.

For example, if the body of an observed request is binary data with a width of 12, then the following claim would be accepted:

Spec.Http.body Spec.Http.binaryData
  <| Spec.Claim.specifyThat .data
  <| Spec.Claim.specifyThat Bytes.width
  <| Claim.isEqual Debug.toString 12

Debug

logRequests : Spec.Step.Step model msg

A step that logs to the console any HTTP requests received prior to executing this step.

You might use this step to help debug a rejected observation.