elm-pages-v3-beta/tests/ServerRequestTest.elm

320 lines
11 KiB
Elm
Raw Normal View History

module ServerRequestTest exposing (all)
2022-02-26 20:38:03 +03:00
import Dict exposing (Dict)
import Expect exposing (Expectation)
2022-07-09 04:00:30 +03:00
import Form
2022-07-09 03:56:52 +03:00
import Form.Field as Field
2022-07-09 03:51:26 +03:00
import Form.Validation as Validation
2022-02-26 20:38:03 +03:00
import FormData
import Internal.Request exposing (Parser(..))
2022-02-26 20:38:03 +03:00
import Json.Decode as Decode
import Json.Encode
import Server.Request as Request
2022-02-26 20:48:36 +03:00
import Test exposing (Test, describe, test)
all : Test
all =
describe "Server.Request matching"
[ test "succeed always matches" <|
\() ->
Request.succeed ()
|> expectMatch
{ method = Request.Get
, headers = []
2022-01-24 06:30:48 +03:00
, body = Nothing
, urlQueryString = Nothing
}
, test "accept GET" <|
\() ->
Request.succeed ()
|> Request.acceptMethod ( Request.Get, [] )
|> expectMatch
{ method = Request.Get
, headers = []
2022-01-24 06:30:48 +03:00
, body = Nothing
, urlQueryString = Nothing
}
, test "accept GET doesn't match POST" <|
\() ->
Request.succeed ()
|> Request.acceptMethod ( Request.Post, [] )
|> expectNoMatch
{ method = Request.Get
, headers = []
2022-01-24 06:30:48 +03:00
, body = Nothing
, urlQueryString = Nothing
}
"Expected HTTP method POST but was GET"
, test "formData extracts fields from query params for GET" <|
\() ->
2022-07-09 18:03:02 +03:00
Request.rawFormData
|> Request.map
(\formData ->
formData
)
|> expectMatchWith
{ method = Request.Get
, headers = []
2022-01-24 06:30:48 +03:00
, body = Nothing
, urlQueryString = Just "q=hello"
}
[ ( "q", "hello" ) ]
2022-01-25 02:43:05 +03:00
, test "tries multiple form post formats" <|
\() ->
2022-08-03 11:01:22 +03:00
Request.formData
(Form.init
(\bar ->
2022-07-23 21:29:03 +03:00
{ combine =
Validation.succeed identity
|> Validation.andMap bar
, view =
\_ -> ()
}
)
2022-07-24 10:11:12 +03:00
|> Form.field "bar" Field.text
|> Form.initCombined identity
|> Form.combine identity
(Form.init
(\bar ->
{ combine =
Validation.succeed identity
|> Validation.andMap bar
, view =
\_ -> ()
}
)
|> Form.field "foo" Field.text
)
)
2022-01-25 02:43:05 +03:00
|> expectMatch
{ method = Request.Post
, headers =
[ ( "content-type", "application/x-www-form-urlencoded" )
]
2022-02-26 20:38:03 +03:00
, body =
2022-01-25 02:43:05 +03:00
Just
2022-02-26 20:38:03 +03:00
(FormData
(Dict.fromList [ ( "foo", ( "bar", [] ) ) ])
2022-02-26 20:38:03 +03:00
)
, urlQueryString = Nothing
2022-01-25 02:43:05 +03:00
}
, test "expectFormPost with missing content-type" <|
\() ->
2022-08-03 11:01:22 +03:00
Request.formData
(Form.init
(\bar ->
2022-07-23 21:29:03 +03:00
{ combine =
Validation.succeed identity
|> Validation.andMap bar
, view =
\_ -> ()
}
)
2022-07-24 10:11:12 +03:00
|> Form.field "bar" Field.text
|> Form.initCombined identity
)
|> expectNoMatch
{ method = Request.Post
, headers =
[ ( "content_type", "application/x-www-form-urlencoded" )
]
, body =
Just
(FormData
(Dict.fromList [ ( "foo", ( "bar", [] ) ) ])
)
, urlQueryString = Nothing
}
"""expectFormPost did not match - Was form POST but expected content-type `application/x-www-form-urlencoded` but the request didn't have a content-type header"""
2021-12-31 07:22:26 +03:00
-- , test "one of no match" <|
-- \() ->
-- Request.oneOf
-- [ --Request.formParserResultNew
-- -- [ Form.init
-- -- (\bar ->
-- -- Validation.succeed identity
2022-07-09 18:30:13 +03:00
-- -- |> Validation.andMap bar
-- -- )
-- -- (\_ _ -> ())
-- -- |> Form.field "first" Field.text
-- -- ],
-- Request.expectJsonBody (Decode.field "first" Decode.string)
-- , Request.expectQueryParam "first"
-- , Request.expectMultiPartFormPost
-- (\{ field } ->
-- field "first"
-- )
-- ]
-- |> expectNoMatch
-- { method = Request.Get
-- , headers =
-- [ ( "content-type", "application/x-www-form-urlencoded" )
-- ]
-- , body = Nothing
-- }
-- """Server.Request.oneOf failed in the following 4 ways:
--
--(1) expectFormPost did not match - expected method POST, but the method was GET
--
--(2) Expected content-type to be application/json but it was application/x-www-form-urlencoded
--
--(3) Internal error - expected rawUrl field but the adapter script didn't provide one.
--
--(4) Expected content-type to be multipart/form-data but it was application/x-www-form-urlencoded
--Expected HTTP method POST but was GET"""
]
type alias Request =
{ method : Request.Method
, headers : List ( String, String )
2022-02-26 20:38:03 +03:00
, body : Maybe Body
, urlQueryString : Maybe String
}
2022-02-26 20:38:03 +03:00
type Body
= FormData (Dict String ( String, List String ))
2022-02-26 20:38:03 +03:00
| JsonBody Decode.Value
| StringBody String
expectMatch : Request -> Request.Parser value -> Expectation
expectMatch request (Parser decoder) =
case
request
|> requestToJson
2022-02-26 20:38:03 +03:00
|> Decode.decodeValue decoder
of
Ok ok ->
case ok of
2022-01-28 03:03:42 +03:00
( Ok _, [] ) ->
Expect.pass
( Err innerError, otherErrors ) ->
(innerError :: otherErrors)
|> List.map Request.errorToString
|> String.join "\n"
|> Expect.fail
( Ok _, nonEmptyErrors ) ->
nonEmptyErrors
|> List.map Request.errorToString
|> String.join "\n"
|> Expect.fail
Err error ->
2022-02-26 20:38:03 +03:00
Expect.fail (Decode.errorToString error)
expectMatchWith : Request -> value -> Request.Parser value -> Expectation
expectMatchWith request expected (Parser decoder) =
case
request
|> requestToJson
|> Decode.decodeValue decoder
of
Ok ok ->
case ok of
( Ok actual, [] ) ->
actual
|> Expect.equal expected
( Err innerError, otherErrors ) ->
(innerError :: otherErrors)
|> List.map Request.errorToString
|> String.join "\n"
|> Expect.fail
( Ok _, nonEmptyErrors ) ->
nonEmptyErrors
|> List.map Request.errorToString
|> String.join "\n"
|> Expect.fail
Err error ->
Expect.fail (Decode.errorToString error)
expectNoMatch : Request -> String -> Request.Parser value -> Expectation
expectNoMatch request expectedErrorString (Parser decoder) =
case
request
|> requestToJson
2022-02-26 20:38:03 +03:00
|> Decode.decodeValue decoder
of
Ok ok ->
case ok of
2022-01-28 03:03:42 +03:00
( Ok _, [] ) ->
Expect.fail "Expected this request not to match, but instead it did match."
( Err innerError, otherErrors ) ->
(innerError :: otherErrors)
|> List.map Request.errorToString
|> String.join "\n"
|> Expect.equal expectedErrorString
( Ok _, nonEmptyErrors ) ->
nonEmptyErrors
|> List.map Request.errorToString
|> String.join "\n"
|> Expect.equal expectedErrorString
Err error ->
Expect.fail
("Expected this request to not match, but instead there was an internal error: "
2022-02-26 20:38:03 +03:00
++ Decode.errorToString error
)
requestToJson : Request -> Json.Encode.Value
requestToJson request =
Json.Encode.object
[ ( "method"
, request.method
|> Request.methodToString
|> Json.Encode.string
)
, ( "headers"
, Json.Encode.object
(List.map
(Tuple.mapSecond
Json.Encode.string
)
request.headers
)
)
2022-02-26 20:38:03 +03:00
, ( "body"
, request.body
|> Maybe.map encodeBody
2022-01-24 07:05:05 +03:00
|> Maybe.withDefault Json.Encode.null
)
, ( "query"
, Json.Encode.object
[ ( "q", Json.Encode.string "hello" )
]
)
, ( "rawUrl"
, Json.Encode.string
("http://localhost:1234/"
++ (request.urlQueryString |> Maybe.map (\q -> "?" ++ q) |> Maybe.withDefault "")
)
)
2021-12-31 07:22:26 +03:00
, ( "multiPartFormData", Json.Encode.null )
]
2022-02-26 20:38:03 +03:00
encodeBody : Body -> Decode.Value
encodeBody body =
case body of
JsonBody json ->
json
FormData formData ->
formData |> FormData.encode |> Json.Encode.string
StringBody string ->
string |> Json.Encode.string