purescript-httpurple/test/Test/HTTPure/HeadersSpec.purs
Hardy Jones 5d7c2c8bda Use CaseInsensitiveString for Headers (#138)
* v0.8.1

* Add failing tests for `Headers`

There's currently a bug with `Headers`:
if a header is created with uppercase characters, it can never be found.
The problem is that we only look for lowercase characters in the
`Lookup` instance for `Headers`.

* Convert `Headers` to use `CaseInsensitiveString`

In an effort to be more true to HTTP,
we make the header keys case-insensitive.
This fixes the issue of looking up a header where the casing is different,
Since `CaseInsensitiveString`s compare in a way that ignore casing.

The API for consumers for `Headers` stays the same,
but we get more correct code.
A win for all!
2019-04-25 20:06:15 -07:00

130 lines
4.8 KiB
Haskell

module Test.HTTPure.HeadersSpec where
import Prelude
import Effect.Class as EffectClass
import Data.Maybe as Maybe
import Data.Tuple as Tuple
import Test.Spec as Spec
import HTTPure.Headers as Headers
import HTTPure.Lookup ((!!))
import Test.HTTPure.TestHelpers as TestHelpers
import Test.HTTPure.TestHelpers ((?=))
lookupSpec :: TestHelpers.Test
lookupSpec = Spec.describe "lookup" do
Spec.describe "when the string is in the header set" do
Spec.describe "when searching with lowercase" do
Spec.it "is Just the string" do
Headers.header "x-test" "test" !! "x-test" ?= Maybe.Just "test"
Spec.describe "when searching with uppercase" do
Spec.it "is Just the string" do
Headers.header "x-test" "test" !! "X-Test" ?= Maybe.Just "test"
Spec.describe "when the string is uppercase" do
Spec.describe "when searching with lowercase" do
Spec.it "is Just the string" do
Headers.header "X-Test" "test" !! "x-test" ?= Maybe.Just "test"
Spec.describe "when searching with uppercase" do
Spec.it "is Just the string" do
Headers.header "X-Test" "test" !! "X-Test" ?= Maybe.Just "test"
Spec.describe "when the string is not in the header set" do
Spec.it "is Nothing" do
((Headers.empty !! "X-Test") :: Maybe.Maybe String) ?= Maybe.Nothing
showSpec :: TestHelpers.Test
showSpec = Spec.describe "show" do
Spec.it "is a string representing the headers in HTTP format" do
let mock = Headers.header "Test1" "1" <> Headers.header "Test2" "2"
show mock ?= "Test1: 1\nTest2: 2\n\n"
eqSpec :: TestHelpers.Test
eqSpec = Spec.describe "eq" do
Spec.describe "when the two Headers contain the same keys and values" do
Spec.it "is true" do
Headers.header "Test1" "test1" == Headers.header "Test1" "test1" ?= true
Spec.describe "when the two Headers contain different keys and values" do
Spec.it "is false" do
Headers.header "Test1" "test1" == Headers.header "Test2" "test2" ?= false
Spec.describe "when the two Headers contain only different values" do
Spec.it "is false" do
Headers.header "Test1" "test1" == Headers.header "Test1" "test2" ?= false
Spec.describe "when the one Headers contains additional keys and values" do
Spec.it "is false" do
let mock = Headers.header "Test1" "1" <> Headers.header "Test2" "2"
Headers.header "Test1" "1" == mock ?= false
appendSpec :: TestHelpers.Test
appendSpec = Spec.describe "append" do
Spec.describe "when there are multiple keys" do
Spec.it "appends the headers correctly" do
let mock1 = Headers.header "Test1" "1" <> Headers.header "Test2" "2"
let mock2 = Headers.header "Test3" "3" <> Headers.header "Test4" "4"
let mock3 = Headers.headers
[ Tuple.Tuple "Test1" "1"
, Tuple.Tuple "Test2" "2"
, Tuple.Tuple "Test3" "3"
, Tuple.Tuple "Test4" "4"
]
mock1 <> mock2 ?= mock3
Spec.describe "when there is a duplicated key" do
Spec.it "uses the last appended value" do
let mock = Headers.header "Test" "foo" <> Headers.header "Test" "bar"
mock ?= Headers.header "Test" "bar"
readSpec :: TestHelpers.Test
readSpec = Spec.describe "read" do
Spec.describe "with no headers" do
Spec.it "is an empty Map" do
request <- TestHelpers.mockRequest "" "" "" "" []
Headers.read request ?= Headers.empty
Spec.describe "with headers" do
Spec.it "is a Map with the contents of the headers" do
let testHeader = [Tuple.Tuple "X-Test" "test"]
request <- TestHelpers.mockRequest "" "" "" "" testHeader
Headers.read request ?= Headers.headers testHeader
writeSpec :: TestHelpers.Test
writeSpec = Spec.describe "write" do
Spec.it "writes the headers to the response" do
header <- EffectClass.liftEffect do
mock <- TestHelpers.mockResponse
Headers.write mock $ Headers.header "X-Test" "test"
pure $ TestHelpers.getResponseHeader "X-Test" mock
header ?= "test"
emptySpec :: TestHelpers.Test
emptySpec = Spec.describe "empty" do
Spec.it "is an empty Map in an empty Headers" do
show Headers.empty ?= "\n"
headerSpec :: TestHelpers.Test
headerSpec = Spec.describe "header" do
Spec.it "creates a singleton Headers" do
show (Headers.header "X-Test" "test") ?= "X-Test: test\n\n"
headersFunctionSpec :: TestHelpers.Test
headersFunctionSpec = Spec.describe "headers" do
Spec.it "is equivalent to using Headers.header with <>" do
test ?= expected
where
test =
Headers.headers
[ Tuple.Tuple "X-Test-1" "1"
, Tuple.Tuple "X-Test-2" "2"
]
expected = Headers.header "X-Test-1" "1" <> Headers.header "X-Test-2" "2"
headersSpec :: TestHelpers.Test
headersSpec = Spec.describe "Headers" do
lookupSpec
showSpec
eqSpec
appendSpec
readSpec
writeSpec
emptySpec
headerSpec
headersFunctionSpec