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

1657 lines
73 KiB
Elm
Raw Normal View History

module StaticHttpRequestsTests exposing (all)
2021-05-06 17:26:21 +03:00
import ApiRoute
2019-10-22 08:00:15 +03:00
import Codec
2021-06-04 03:57:57 +03:00
import DataSource exposing (DataSource)
import DataSource.File
import DataSource.Glob as Glob
import DataSource.Http
2020-12-07 19:41:10 +03:00
import Dict
2019-10-22 06:21:52 +03:00
import Expect
import Html
import Json.Decode as JD
import Json.Encode as Encode
import List.Extra
2021-06-09 01:17:56 +03:00
import NotFoundReason
import OptimizedDecoder as Decode exposing (Decoder)
2021-06-04 03:57:57 +03:00
import Pages.ContentCache as ContentCache exposing (ContentCache)
2021-04-03 00:44:40 +03:00
import Pages.Internal.Platform.Cli exposing (..)
2020-06-12 06:57:19 +03:00
import Pages.Internal.Platform.Effect as Effect exposing (Effect)
2020-06-12 06:55:19 +03:00
import Pages.Internal.Platform.ToJsPayload as ToJsPayload exposing (ToJsPayload)
import Pages.Internal.StaticHttpBody as StaticHttpBody
import Pages.Manifest as Manifest
2021-04-16 18:04:15 +03:00
import Pages.ProgramConfig exposing (ProgramConfig)
import Pages.StaticHttp.Request as Request
import PagesHttp
2021-05-23 20:44:39 +03:00
import Path
import ProgramTest exposing (ProgramTest)
2019-11-03 00:46:52 +03:00
import Regex
import RenderRequest
2019-11-12 04:48:08 +03:00
import Secrets
import Serialize
import SimulatedEffect.Cmd
2019-11-08 22:34:51 +03:00
import SimulatedEffect.Http as Http
2019-10-22 06:21:52 +03:00
import SimulatedEffect.Ports
import SimulatedEffect.Task
import Test exposing (Test, describe, only, test)
import Test.Http
all : Test
all =
describe "Static Http Requests"
[ test "initial requests are sent out" <|
\() ->
start
[ ( []
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( ""
2020-01-04 00:22:53 +03:00
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":86}"""
)
2019-10-22 08:00:15 +03:00
]
)
]
2021-04-16 18:26:59 +03:00
, test "StaticHttp request for initial are resolved" <|
\() ->
start
[ ( [ "post-1" ]
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
2021-04-16 18:26:59 +03:00
--, StaticHttp.succeed 86
)
]
--|> ProgramTest.simulateHttpOk
-- "GET"
-- "https://my-cms.com/posts"
-- """{ "posts": ["post-1"] }"""
2021-04-16 18:26:59 +03:00
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> expectSuccess
[ ( "post-1"
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":86}"""
2021-04-03 19:53:42 +03:00
)
]
2021-04-16 18:26:59 +03:00
)
]
, describe "single page renders"
[ test "single pages that are pre-rendered" <|
\() ->
startWithRoutes [ "post-1" ]
[ [ "post-1" ]
]
[]
[ ( [ "post-1" ]
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
)
]
2021-06-08 20:36:05 +03:00
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
(Codec.decoder (ToJsPayload.successCodecNew2 "" ""))
(\actualPorts ->
case actualPorts of
[ ToJsPayload.PageProgress portData ] ->
portData.is404
|> Expect.false "Expected page to be found and rendered"
_ ->
Expect.fail <| "Expected exactly 1 port of type PageProgress. Instead, got \n" ++ Debug.toString actualPorts
)
, test "data sources are not resolved 404 pages with matching route but not pre-rendered" <|
\() ->
startWithRoutes [ "post-2" ]
[ [ "post-1" ]
]
[]
[ ( [ "post-2" ]
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
)
]
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
(Codec.decoder (ToJsPayload.successCodecNew2 "" ""))
(\actualPorts ->
case actualPorts of
[ ToJsPayload.PageProgress portData ] ->
portData.is404
|> Expect.true "Expected 404 not found page"
_ ->
Expect.fail <| "Expected exactly 1 port of type PageProgress. Instead, got \n" ++ Debug.toString actualPorts
)
]
, test "the stripped JSON from the same request with different decoders is merged so the decoders succeed" <|
\() ->
start
[ ( [ "post-1" ]
, DataSource.map2 Tuple.pair
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
(Decode.field "stargazer_count" Decode.int)
)
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
(Decode.field "language" Decode.string)
)
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86, "language": "Elm" }"""
|> expectSuccess
[ ( "post-1"
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":86,"language":"Elm"}"""
)
]
)
]
, test "andThen" <|
\() ->
start
[ ( [ "elm-pages" ]
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") (Decode.succeed ())
2021-04-20 17:31:19 +03:00
|> DataSource.andThen
2021-04-03 00:44:40 +03:00
(\_ ->
DataSource.Http.get (Secrets.succeed "NEXT-REQUEST") (Decode.succeed ())
)
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""null"""
|> ProgramTest.simulateHttpOk
"GET"
"NEXT-REQUEST"
"""null"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( "elm-pages"
2020-01-04 00:22:53 +03:00
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """null"""
)
2020-01-04 00:22:53 +03:00
, ( get "NEXT-REQUEST"
, """null"""
)
]
)
]
, test "andThen chain avoids repeat requests" <|
\() ->
let
2021-06-04 03:57:57 +03:00
getReq : String -> Decoder a -> DataSource a
getReq url decoder =
DataSource.Http.request
2020-01-04 00:22:53 +03:00
(Secrets.succeed (get url))
decoder
2021-06-04 03:57:57 +03:00
pokemonDetailRequest : DataSource ()
pokemonDetailRequest =
getReq
"https://pokeapi.co/api/v2/pokemon/"
(Decode.list
(Decode.field "url" Decode.string
|> Decode.map
(\url ->
getReq url
(Decode.field "image" Decode.string)
)
)
)
2021-04-20 17:31:19 +03:00
|> DataSource.resolve
|> DataSource.map (\_ -> ())
in
start
[ ( [ "elm-pages" ], pokemonDetailRequest )
]
|> ProgramTest.simulateHttpOk
"GET"
"https://pokeapi.co/api/v2/pokemon/"
"""[
{"url": "url1"},
{"url": "url2"},
{"url": "url3"},
{"url": "url4"},
{"url": "url5"},
{"url": "url6"},
{"url": "url7"},
{"url": "url8"},
{"url": "url9"},
{"url": "url10"}
]"""
|> ProgramTest.simulateHttpOk
"GET"
"url1"
"""{"image": "image1.jpg"}"""
|> ProgramTest.simulateHttpOk
"GET"
"url2"
"""{"image": "image2.jpg"}"""
|> ProgramTest.simulateHttpOk
"GET"
"url3"
"""{"image": "image3.jpg"}"""
|> ProgramTest.simulateHttpOk
"GET"
"url4"
"""{"image": "image4.jpg"}"""
|> ProgramTest.simulateHttpOk
"GET"
"url5"
"""{"image": "image5.jpg"}"""
|> ProgramTest.simulateHttpOk
"GET"
"url6"
"""{"image": "image6.jpg"}"""
|> ProgramTest.simulateHttpOk
"GET"
"url7"
"""{"image": "image7.jpg"}"""
|> ProgramTest.simulateHttpOk
"GET"
"url8"
"""{"image": "image8.jpg"}"""
|> ProgramTest.simulateHttpOk
"GET"
"url9"
"""{"image": "image9.jpg"}"""
|> ProgramTest.simulateHttpOk
"GET"
"url10"
"""{"image": "image10.jpg"}"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( "elm-pages"
, [ ( get "https://pokeapi.co/api/v2/pokemon/"
, """[{"url":"url1"},{"url":"url2"},{"url":"url3"},{"url":"url4"},{"url":"url5"},{"url":"url6"},{"url":"url7"},{"url":"url8"},{"url":"url9"},{"url":"url10"}]"""
)
, ( get "url1"
, """{"image":"image1.jpg"}"""
)
, ( get "url2"
, """{"image":"image2.jpg"}"""
)
, ( get "url3"
, """{"image":"image3.jpg"}"""
)
, ( get "url4"
, """{"image":"image4.jpg"}"""
)
, ( get "url5"
, """{"image":"image5.jpg"}"""
)
, ( get "url6"
, """{"image":"image6.jpg"}"""
)
, ( get "url7"
, """{"image":"image7.jpg"}"""
)
, ( get "url8"
, """{"image":"image8.jpg"}"""
)
, ( get "url9"
, """{"image":"image9.jpg"}"""
)
, ( get "url10"
, """{"image":"image10.jpg"}"""
)
]
)
]
, test "port is sent out once all requests are finished" <|
\() ->
start
[ ( [ "elm-pages" ]
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
)
, ( [ "elm-pages-starter" ]
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages-starter") starDecoder
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages-starter"
"""{ "stargazer_count": 22 }"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( "elm-pages"
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":86}"""
)
]
)
2020-03-11 19:03:47 +03:00
, ( "elm-pages-starter"
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages-starter"
, """{"stargazer_count":22}"""
)
]
)
]
, test "reduced JSON is sent out" <|
\() ->
start
[ ( []
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") (Decode.field "stargazer_count" Decode.int)
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86, "unused_field": 123 }"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( ""
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":86}"""
)
]
)
]
, test "you can use elm/json decoders with StaticHttp.unoptimizedRequest" <|
\() ->
start
[ ( []
, DataSource.Http.unoptimizedRequest
(Secrets.succeed
{ url = "https://api.github.com/repos/dillonkearns/elm-pages"
, method = "GET"
, headers = []
2021-04-20 17:31:19 +03:00
, body = DataSource.emptyBody
}
)
(DataSource.Http.expectUnoptimizedJson
(JD.field "stargazer_count" JD.int)
)
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86, "unused_field": 123 }"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( ""
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{ "stargazer_count": 86, "unused_field": 123 }"""
)
]
)
]
, test "plain string" <|
\() ->
start
[ ( []
, DataSource.Http.unoptimizedRequest
(Secrets.succeed
{ url = "https://example.com/file.txt"
, method = "GET"
, headers = []
2021-04-20 17:31:19 +03:00
, body = DataSource.emptyBody
}
)
(DataSource.Http.expectString Ok)
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://example.com/file.txt"
"This is a raw text file."
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( ""
, [ ( get "https://example.com/file.txt"
, "This is a raw text file."
)
]
)
]
, test "Err in String to Result function turns into decode error" <|
\() ->
start
[ ( []
, DataSource.Http.unoptimizedRequest
(Secrets.succeed
{ url = "https://example.com/file.txt"
, method = "GET"
, headers = []
2021-04-20 17:31:19 +03:00
, body = DataSource.emptyBody
}
)
(DataSource.Http.expectString
(\string ->
if String.toUpper string == string then
Ok string
else
Err "String was not uppercased"
)
)
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://example.com/file.txt"
"This is a raw text file."
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
2021-04-16 18:04:15 +03:00
(Codec.decoder ToJsPayload.toJsCodec)
(expectErrorsPort
"""-- STATIC HTTP DECODING ERROR ----------------------------------------------------- elm-pages
2020-03-11 19:03:47 +03:00
String was not uppercased"""
)
2019-11-08 22:34:51 +03:00
, test "POST method works" <|
\() ->
start
[ ( []
, DataSource.Http.request
(Secrets.succeed
{ method = "POST"
, url = "https://api.github.com/repos/dillonkearns/elm-pages"
, headers = []
2021-04-20 17:31:19 +03:00
, body = DataSource.emptyBody
}
)
(Decode.field "stargazer_count" Decode.int)
2019-11-08 22:34:51 +03:00
)
]
|> ProgramTest.simulateHttpOk
"POST"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86, "unused_field": 123 }"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( ""
, [ ( { method = "POST"
, url = "https://api.github.com/repos/dillonkearns/elm-pages"
, headers = []
2021-04-20 17:31:19 +03:00
, body = DataSource.emptyBody
2019-11-08 22:34:51 +03:00
}
, """{"stargazer_count":86}"""
)
2019-11-08 22:34:51 +03:00
]
)
]
, test "json is reduced from andThen chains" <|
\() ->
start
[ ( []
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") (Decode.field "stargazer_count" Decode.int)
2021-04-20 17:31:19 +03:00
|> DataSource.andThen
2021-04-03 00:44:40 +03:00
(\_ ->
DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages-starter") (Decode.field "stargazer_count" Decode.int)
)
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 100, "unused_field": 123 }"""
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages-starter"
"""{ "stargazer_count": 50, "unused_field": 456 }"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( ""
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":100}"""
)
, ( get "https://api.github.com/repos/dillonkearns/elm-pages-starter"
, """{"stargazer_count":50}"""
)
]
)
]
, test "reduced json is preserved by StaticHttp.map2" <|
\() ->
start
[ ( []
2021-04-20 17:31:19 +03:00
, DataSource.map2 (\_ _ -> ())
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") (Decode.field "stargazer_count" Decode.int))
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages-starter") (Decode.field "stargazer_count" Decode.int))
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 100, "unused_field": 123 }"""
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages-starter"
"""{ "stargazer_count": 50, "unused_field": 456 }"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( ""
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":100}"""
)
, ( get "https://api.github.com/repos/dillonkearns/elm-pages-starter"
, """{"stargazer_count":50}"""
)
]
)
]
, test "the port sends out even if there are no http requests" <|
\() ->
start
[ ( []
2021-04-20 17:31:19 +03:00
, DataSource.succeed ()
)
]
2020-03-11 19:03:47 +03:00
|> expectSuccess [ ( "", [] ) ]
, test "the port sends out when there are duplicate http requests for the same page" <|
\() ->
start
[ ( []
2021-04-20 17:31:19 +03:00
, DataSource.map2 (\_ _ -> ())
(DataSource.Http.get (Secrets.succeed "http://example.com") (Decode.succeed ()))
(DataSource.Http.get (Secrets.succeed "http://example.com") (Decode.succeed ()))
)
]
|> ProgramTest.simulateHttpOk
"GET"
"http://example.com"
"""null"""
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( ""
, [ ( get "http://example.com"
, """null"""
)
]
)
]
, test "an error is sent out for decoder failures" <|
\() ->
start
2019-10-28 17:57:21 +03:00
[ ( [ "elm-pages" ]
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") (Decode.fail "The user should get this message from the CLI.")
2019-10-28 17:57:21 +03:00
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
2021-04-16 18:04:15 +03:00
(Codec.decoder ToJsPayload.toJsCodec)
(expectErrorsPort
"""-- STATIC HTTP DECODING ERROR ----------------------------------------------------- elm-pages
2019-10-30 08:33:47 +03:00
I encountered some errors while decoding this JSON:
2019-10-27 02:50:09 +03:00
The user should get this message from the CLI.
{
"stargazer_count": 86
}"""
)
, test "an error is sent for missing secrets from continuation requests" <|
\() ->
start
[ ( [ "elm-pages" ]
, DataSource.Http.get
2019-11-12 04:48:08 +03:00
(Secrets.succeed
2019-11-11 23:40:38 +03:00
(\apiKey ->
"https://api.github.com/repos/dillonkearns/elm-pages?apiKey=" ++ apiKey
)
2019-11-12 04:48:08 +03:00
|> Secrets.with "API_KEY"
)
Decode.string
2021-04-20 17:31:19 +03:00
|> DataSource.andThen
(\url ->
DataSource.Http.get
2019-11-12 04:48:08 +03:00
(Secrets.succeed
2019-11-11 23:40:38 +03:00
(\missingSecret ->
url ++ "?apiKey=" ++ missingSecret
)
2019-11-12 04:48:08 +03:00
|> Secrets.with "MISSING"
)
(Decode.succeed ())
)
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages?apiKey=ABCD1234"
""" "continuation-url" """
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
2021-04-16 18:04:15 +03:00
(Codec.decoder ToJsPayload.toJsCodec)
2019-11-03 00:46:52 +03:00
(expectErrorsPort
"""-- MISSING SECRET ----------------------------------------------------- elm-pages
I expected to find this Secret in your environment variables but didn't find a match:
Secrets.get "MISSING"
^^^^^^^
So maybe MISSING should be API_KEY"""
)
, test "an error is sent for HTTP errors" <|
\() ->
start
[ ( []
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") (Decode.succeed ())
)
]
|> ProgramTest.simulateHttpResponse
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
(Test.Http.httpResponse
{ statusCode = 404
, headers = []
, body = ""
}
)
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
2021-04-16 18:04:15 +03:00
(Codec.decoder ToJsPayload.toJsCodec)
2019-12-07 17:46:45 +03:00
(expectErrorsPort """-- STATIC HTTP ERROR ----------------------------------------------------- elm-pages
I got an error making an HTTP request to this URL: https://api.github.com/repos/dillonkearns/elm-pages
Bad status: 404
Status message: TODO: if you need this, please report to https://github.com/avh4/elm-program-test/issues
Body:
-- STATIC HTTP DECODING ERROR ----------------------------------------------------- elm-pages
2021-06-01 07:51:31 +03:00
Payload sent back invalid JSON
TODO
""")
2019-10-24 18:26:41 +03:00
, test "uses real secrets to perform request and masked secrets to store and lookup response" <|
\() ->
start
[ ( []
, DataSource.Http.request
2019-11-12 04:48:08 +03:00
(Secrets.succeed
2019-11-12 03:56:25 +03:00
(\apiKey bearer ->
{ url = "https://api.github.com/repos/dillonkearns/elm-pages?apiKey=" ++ apiKey
, method = "GET"
, headers = [ ( "Authorization", "Bearer " ++ bearer ) ]
2021-04-20 17:31:19 +03:00
, body = DataSource.emptyBody
2019-11-12 03:56:25 +03:00
}
2019-11-11 23:40:38 +03:00
)
2019-11-12 04:48:08 +03:00
|> Secrets.with "API_KEY"
|> Secrets.with "BEARER"
2019-10-28 17:57:21 +03:00
)
(Decode.succeed ())
2019-10-24 18:26:41 +03:00
)
]
2019-11-12 03:56:25 +03:00
|> ProgramTest.ensureHttpRequest "GET"
"https://api.github.com/repos/dillonkearns/elm-pages?apiKey=ABCD1234"
(\request ->
request.headers
|> Expect.equal [ ( "Authorization", "Bearer XYZ789" ) ]
)
|> ProgramTest.simulateHttpResponse
2019-10-24 18:26:41 +03:00
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages?apiKey=ABCD1234"
2019-11-12 03:56:25 +03:00
(Test.Http.httpResponse
{ statusCode = 200
, headers = []
, body = """{ "stargazer_count": 86 }"""
}
)
|> expectSuccess
2020-03-11 19:03:47 +03:00
[ ( ""
, [ ( { method = "GET"
, url = "https://api.github.com/repos/dillonkearns/elm-pages?apiKey=<API_KEY>"
, headers =
[ ( "Authorization", "Bearer <BEARER>" )
]
2021-04-20 17:31:19 +03:00
, body = DataSource.emptyBody
2019-10-24 18:26:41 +03:00
}
, """{}"""
)
2019-10-24 18:26:41 +03:00
]
)
]
, describe "staticHttpCache"
[ test "it doesn't perform http requests that are provided in the http cache flag" <|
\() ->
2021-06-04 03:14:25 +03:00
startWithHttpCache
[ ( { url = "https://api.github.com/repos/dillonkearns/elm-pages"
, method = "GET"
, headers = []
, body = StaticHttpBody.EmptyBody
}
, """{"stargazer_count":86}"""
)
]
[ ( []
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
)
]
|> expectSuccess
[ ( ""
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":86}"""
)
]
)
]
2020-04-19 20:35:17 +03:00
, test "it ignores unused cache" <|
\() ->
2021-06-04 03:14:25 +03:00
startWithHttpCache
2020-04-19 20:35:17 +03:00
[ ( { url = "https://this-is-never-used.example.com/"
, method = "GET"
, headers = []
, body = StaticHttpBody.EmptyBody
}
, """{"stargazer_count":86}"""
)
]
[ ( []
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
2020-04-19 20:35:17 +03:00
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> expectSuccess
[ ( ""
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":86}"""
)
]
)
]
2021-06-17 01:23:16 +03:00
, test "validate DataSource is not stored for any pages" <|
\() ->
startWithRoutes [ "hello" ]
[ [ "hello" ] ]
[]
[ ( [ "hello" ]
, DataSource.succeed "hello"
|> DataSource.validate identity
(\word ->
DataSource.Http.get (Secrets.succeed ("https://api.spellchecker.com?word=" ++ word))
(Decode.field "isCorrect" Decode.bool
|> Decode.map
(\isCorrect ->
if isCorrect then
Ok ()
else
Err "Spelling error"
)
)
)
|> DataSource.map (\_ -> ())
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.spellchecker.com?word=hello"
"""{ "isCorrect": true }"""
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
(Codec.decoder (ToJsPayload.successCodecNew2 "" ""))
(\actualPorts ->
case actualPorts of
[ ToJsPayload.PageProgress portData ] ->
portData.contentJson
|> Expect.equalDicts Dict.empty
2021-06-17 20:01:48 +03:00
_ ->
Expect.fail <| "Expected exactly 1 port of type PageProgress. Instead, got \n" ++ Debug.toString actualPorts
)
, test "distill stores encoded JSON but not original DataSource" <|
\() ->
startWithRoutes [ "hello" ]
[ [ "hello" ] ]
[]
[ ( [ "hello" ]
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
|> DataSource.distill "abc123" Encode.int (JD.decodeValue JD.int >> Result.mapError JD.errorToString)
|> DataSource.map (\_ -> ())
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
(Codec.decoder (ToJsPayload.successCodecNew2 "" ""))
(\actualPorts ->
case actualPorts of
[ ToJsPayload.PageProgress portData ] ->
portData.contentJson
|> Expect.equalDicts (Dict.fromList [ ( "abc123", "86" ) ])
_ ->
Expect.fail <| "Expected exactly 1 port of type PageProgress. Instead, got \n" ++ Debug.toString actualPorts
)
, test "distill with andThen chains resolves successfully" <|
\() ->
let
andThenExample : DataSource (List ( String, String ))
andThenExample =
Glob.succeed
identity
|> Glob.match (Glob.literal "content/glossary/")
|> Glob.capture Glob.wildcard
|> Glob.match (Glob.literal ".md")
|> Glob.toDataSource
|> DataSource.map
(List.map
(\topic ->
DataSource.File.bodyWithoutFrontmatter ("content/glossary/" ++ topic ++ ".md" |> Debug.log "glossary-file")
|> DataSource.map (Tuple.pair topic)
)
)
|> DataSource.resolve
|> DataSource.map
(\allNotes ->
allNotes
|> List.map
(\note ->
DataSource.succeed note
)
)
|> DataSource.resolve
in
startWithRoutes [ "hello" ]
[ [ "hello" ] ]
[]
[ ( [ "hello" ]
, andThenExample
|> DataSource.map (\_ -> ())
)
]
|> ProgramTest.ensureOutgoingPortValues
"toJsPort"
(Codec.decoder (ToJsPayload.successCodecNew2 "" ""))
(\actualPorts ->
case actualPorts of
[ ToJsPayload.Glob _ ] ->
Expect.pass
_ ->
Expect.fail <|
"Expected a glob, but got\n"
++ (actualPorts
|> List.indexedMap
(\index item -> "(" ++ String.fromInt (index + 1) ++ ") " ++ Debug.toString item)
|> String.join "\n\n"
)
++ "\n\n"
)
|> ProgramTest.simulateIncomingPort "fromJsPort"
(Encode.object
[ ( "tag", Encode.string "GotGlob" )
, ( "data"
, Encode.object
[ ( "pattern", Encode.string "content/glossary/*.md" )
, ( "result", Encode.list Encode.string [ "content/glossary/hello.md" ] )
]
)
]
)
|> ProgramTest.ensureOutgoingPortValues
"toJsPort"
(Codec.decoder (ToJsPayload.successCodecNew2 "" ""))
(\actualPorts ->
case actualPorts of
[ ToJsPayload.ReadFile _ ] ->
Expect.pass
_ ->
Expect.fail <|
"Expected a ReadFile, but got\n"
++ (actualPorts
|> List.indexedMap
(\index item -> "(" ++ String.fromInt (index + 1) ++ ") " ++ Debug.toString item)
|> String.join "\n\n"
)
++ "\n\n"
)
|> ProgramTest.simulateIncomingPort "fromJsPort"
(Encode.object
[ ( "tag", Encode.string "GotFile" )
, ( "data"
, Encode.object
[ ( "filePath", Encode.string "content/glossary/hello.md" )
, ( "withoutFrontmatter", Encode.string "BODY" )
]
)
]
)
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
(Codec.decoder (ToJsPayload.successCodecNew2 "" ""))
(\actualPorts ->
case actualPorts of
[ {- ToJsPayload.Glob _, ToJsPayload.ReadFile _ -} ToJsPayload.PageProgress portData ] ->
portData.contentJson
|> Expect.equalDicts
(Dict.fromList [ ( "{\"method\":\"GET\",\"url\":\"file://content/glossary/hello.md\",\"headers\":[],\"body\":{\"type\":\"empty\"}}", "{\"withoutFrontmatter\":\"BODY\"}" ), ( "{\"method\":\"GET\",\"url\":\"glob://content/glossary/*.md\",\"headers\":[],\"body\":{\"type\":\"empty\"}}", "[\"content/glossary/hello.md\"]" ) ])
_ ->
Expect.fail <|
"Expected exactly 1 port of type PageProgress. Instead, got \n\n"
++ (actualPorts
|> List.indexedMap
(\index item -> "(" ++ String.fromInt (index + 1) ++ ") " ++ Debug.toString item)
|> String.join "\n\n"
)
++ "\n\n"
)
, test "distill successfully merges data sources with same key and same encoded JSON" <|
\() ->
startWithRoutes [ "hello" ]
[ [ "hello" ] ]
[]
[ ( [ "hello" ]
, DataSource.map2 (\_ _ -> ())
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
|> DataSource.distill "abc123" Encode.int (JD.decodeValue JD.int >> Result.mapError JD.errorToString)
)
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
|> DataSource.distill "abc123" Encode.int (JD.decodeValue JD.int >> Result.mapError JD.errorToString)
)
)
]
2021-06-17 20:01:48 +03:00
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
(Codec.decoder (ToJsPayload.successCodecNew2 "" ""))
(\actualPorts ->
case actualPorts of
[ ToJsPayload.PageProgress portData ] ->
portData.contentJson
|> Expect.equalDicts (Dict.fromList [ ( "abc123", "86" ) ])
2021-06-17 01:23:16 +03:00
_ ->
Expect.fail <| "Expected exactly 1 port of type PageProgress. Instead, got \n" ++ Debug.toString actualPorts
)
, test "distill gives an error if there are matching keys with different encoded JSON" <|
\() ->
startWithRoutes [ "hello" ]
[ [ "hello" ] ]
[]
[ ( [ "hello" ]
, DataSource.map2 (\_ _ -> ())
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
|> DataSource.distill "stars" Encode.int (JD.decodeValue JD.int >> Result.mapError JD.errorToString)
)
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-markdown") starDecoder
|> DataSource.distill "stars" Encode.int (JD.decodeValue JD.int >> Result.mapError JD.errorToString)
)
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-markdown"
"""{ "stargazer_count": 123 }"""
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
(Codec.decoder ToJsPayload.toJsCodec)
(expectErrorsPort """-- NON-UNIQUE DISTILL KEYS ----------------------------------------------------- elm-pages
I encountered DataSource.distill with two matching keys that had differing encoded values.
Look for DataSource.distill with the key "stars"
The first encoded value was:
86
-------------------------------
The second encoded value was:
123""")
]
, describe "generateFiles"
[ test "initial requests are sent out" <|
\() ->
startLowLevel
2021-05-06 17:26:21 +03:00
[ ApiRoute.succeed
2021-05-06 17:14:49 +03:00
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
(starDecoder
|> Decode.map
(\starCount ->
{ body = "Star count: " ++ String.fromInt starCount
}
2021-05-06 17:14:49 +03:00
)
)
)
2021-05-06 17:26:21 +03:00
|> ApiRoute.literal "test.txt"
2021-06-24 20:05:16 +03:00
|> ApiRoute.single
2021-05-06 17:14:49 +03:00
]
[]
[]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages"
"""{ "stargazer_count": 86 }"""
|> expectSuccessNew
[]
[ \success ->
success.filesToGenerate
|> Expect.equal
[ { path = [ "test.txt" ]
, content = "Star count: 86"
}
]
]
, test "it sends success port when no HTTP requests are needed because they're all cached" <|
\() ->
startLowLevel
2021-05-06 17:26:21 +03:00
[ ApiRoute.succeed
2021-05-06 17:14:49 +03:00
(DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages-starter")
(starDecoder
|> Decode.map
(\starCount ->
{ body = "Star count: " ++ String.fromInt starCount
}
2021-05-06 17:14:49 +03:00
)
)
)
2021-05-06 17:26:21 +03:00
|> ApiRoute.literal "test.txt"
2021-06-24 20:05:16 +03:00
|> ApiRoute.single
2021-05-06 17:14:49 +03:00
]
[ ( { url = "https://api.github.com/repos/dillonkearns/elm-pages"
, method = "GET"
, headers = []
, body = StaticHttpBody.EmptyBody
}
, """{"stargazer_count":86}"""
)
, ( { url = "https://api.github.com/repos/dillonkearns/elm-pages-starter"
, method = "GET"
, headers = []
, body = StaticHttpBody.EmptyBody
}
, """{"stargazer_count":23}"""
)
]
[ ( []
, DataSource.Http.get (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages") starDecoder
)
]
|> expectSuccessNew
[ ( ""
, [ ( get "https://api.github.com/repos/dillonkearns/elm-pages"
, """{"stargazer_count":86}"""
)
]
)
]
[ \success ->
success.filesToGenerate
|> Expect.equal
[ { path = [ "test.txt" ]
, content = "Star count: 23"
}
]
]
]
]
2021-04-16 18:04:15 +03:00
type Route
= Route String
2021-06-04 03:57:57 +03:00
start : List ( List String, DataSource a ) -> ProgramTest (Model Route) Msg Effect
start pages =
2021-06-04 03:14:25 +03:00
startWithHttpCache [] pages
2020-06-13 22:29:36 +03:00
startWithHttpCache :
2021-06-04 03:14:25 +03:00
List ( Request.Request, String )
2021-06-04 03:57:57 +03:00
-> List ( List String, DataSource a )
2021-04-16 18:04:15 +03:00
-> ProgramTest (Model Route) Msg Effect
startWithHttpCache =
2021-05-06 17:14:49 +03:00
startLowLevel []
startLowLevel :
2021-05-06 17:26:21 +03:00
List (ApiRoute.Done ApiRoute.Response)
-> List ( Request.Request, String )
2021-06-04 03:57:57 +03:00
-> List ( List String, DataSource a )
2021-04-16 18:04:15 +03:00
-> ProgramTest (Model Route) Msg Effect
2021-06-04 03:14:25 +03:00
startLowLevel apiRoutes staticHttpCache pages =
let
2021-06-04 03:57:57 +03:00
contentCache : ContentCache
contentCache =
2021-04-03 07:43:57 +03:00
ContentCache.init Nothing
2021-04-16 18:04:15 +03:00
config : ProgramConfig Msg () Route () () ()
config =
{ toJsPort = toJsPort
, fromJsPort = fromJsPort
2021-05-19 17:58:37 +03:00
, init = \_ _ _ _ _ -> ( (), Cmd.none )
2021-04-03 19:53:42 +03:00
, getStaticRoutes =
2021-04-16 18:26:59 +03:00
--StaticHttp.get (Secrets.succeed "https://my-cms.com/posts")
-- (Decode.field "posts" (Decode.list (Decode.string |> Decode.map Route)))
pages
|> List.map Tuple.first
|> List.map (String.join "/")
|> List.map Route
2021-04-20 17:31:19 +03:00
|> DataSource.succeed
2021-06-09 01:17:56 +03:00
, handleRoute = \_ -> DataSource.succeed Nothing
2021-04-16 18:04:15 +03:00
, urlToRoute = .path >> Route
2021-04-22 21:33:06 +03:00
, update = \_ _ _ _ _ -> ( (), Cmd.none )
2021-04-24 02:24:26 +03:00
, data =
\(Route pageRoute) ->
let
2021-06-04 03:57:57 +03:00
thing : Maybe (DataSource a)
thing =
pages
|> Dict.fromList
|> Dict.get
(pageRoute
|> String.split "/"
|> List.filter (\pathPart -> pathPart /= "")
)
in
case thing of
Just request ->
2021-04-20 17:31:19 +03:00
request |> DataSource.map (\_ -> ())
Nothing ->
Debug.todo <| "Couldn't find page: " ++ pageRoute ++ "\npages: " ++ Debug.toString pages
2021-04-06 03:15:22 +03:00
, site =
2021-04-16 19:32:09 +03:00
\_ ->
2021-04-24 02:24:26 +03:00
{ data = DataSource.succeed ()
, canonicalUrl = "canonical-site-url"
2021-04-16 18:04:15 +03:00
, manifest = \_ -> manifest
, head = \_ -> []
}
, view =
2021-05-24 21:40:36 +03:00
\page _ ->
let
2021-06-04 03:57:57 +03:00
thing : Maybe (DataSource a)
thing =
pages
|> Dict.fromList
|> Dict.get
2021-05-23 20:44:39 +03:00
(page.path |> Path.toSegments)
in
case thing of
2021-04-17 18:18:26 +03:00
Just _ ->
\_ _ -> { view = \_ -> { title = "Title", body = Html.text "" }, head = [] }
Nothing ->
2021-04-03 16:39:07 +03:00
Debug.todo <| "Couldn't find page: " ++ Debug.toString page ++ "\npages: " ++ Debug.toString pages
2020-10-26 21:50:06 +03:00
, subscriptions = \_ _ _ -> Sub.none
2021-04-16 18:04:15 +03:00
, routeToPath = \(Route route) -> route |> String.split "/"
2021-04-24 02:22:23 +03:00
, sharedData = DataSource.succeed ()
2021-04-21 17:52:56 +03:00
, onPageChange = \_ -> Continue
2021-05-15 05:38:10 +03:00
, apiRoutes = \_ -> apiRoutes
2021-06-06 21:11:34 +03:00
, pathPatterns = []
}
2021-06-04 03:57:57 +03:00
encodedFlags : Encode.Value
encodedFlags =
--{"secrets":
-- {"API_KEY": "ABCD1234","BEARER": "XYZ789"}, "mode": "prod", "staticHttpCache": {}
-- }
Encode.object
[ ( "secrets"
, [ ( "API_KEY", "ABCD1234" )
, ( "BEARER", "XYZ789" )
]
|> Dict.fromList
|> Encode.dict identity Encode.string
)
, ( "mode", Encode.string "prod" )
, ( "staticHttpCache", encodedStaticHttpCache )
]
2021-06-04 03:57:57 +03:00
encodedStaticHttpCache : Encode.Value
encodedStaticHttpCache =
staticHttpCache
|> List.map
(\( request, httpResponseString ) ->
( Request.hash request, Encode.string httpResponseString )
)
|> Encode.object
in
{-
(Model -> model)
-> ContentCache.ContentCache metadata view
2021-04-10 20:33:26 +03:00
-> Result (List BuildError) (List ( PagePath, metadata ))
-> Config pathKey userMsg userModel metadata view
-> Decode.Value
-> ( model, Effect pathKey )
-}
ProgramTest.createDocument
2021-04-17 22:35:00 +03:00
{ init = init RenderRequest.FullBuild contentCache config
2021-04-03 07:43:57 +03:00
, update = update contentCache config
2019-10-25 17:00:04 +03:00
, view = \_ -> { title = "", body = [] }
}
|> ProgramTest.withSimulatedEffects simulateEffects
|> ProgramTest.start (flags (Encode.encode 0 encodedFlags))
2019-10-24 18:26:41 +03:00
startWithRoutes :
List String
-> List (List String)
-> List ( Request.Request, String )
-> List ( List String, DataSource a )
-> ProgramTest (Model Route) Msg Effect
startWithRoutes pageToLoad staticRoutes staticHttpCache pages =
let
contentCache : ContentCache
contentCache =
ContentCache.init Nothing
config : ProgramConfig Msg () Route () () ()
config =
{ toJsPort = toJsPort
, fromJsPort = fromJsPort
, init = \_ _ _ _ _ -> ( (), Cmd.none )
, getStaticRoutes =
staticRoutes
|> List.map (String.join "/")
|> List.map Route
|> DataSource.succeed
, handleRoute =
\(Route route) ->
staticRoutes
|> List.map (String.join "/")
2021-06-08 20:36:05 +03:00
|> List.member route
2021-06-09 01:17:56 +03:00
|> (\found ->
if found then
Nothing
else
Just NotFoundReason.NoMatchingRoute
)
|> DataSource.succeed
, urlToRoute = .path >> Route
, update = \_ _ _ _ _ -> ( (), Cmd.none )
, data =
\(Route pageRoute) ->
let
thing : Maybe (DataSource a)
thing =
pages
|> Dict.fromList
|> Dict.get
(pageRoute
|> String.split "/"
|> List.filter (\pathPart -> pathPart /= "")
)
in
case thing of
Just request ->
request |> DataSource.map (\_ -> ())
Nothing ->
DataSource.fail <| "Couldn't find page: " ++ pageRoute ++ "\npages: " ++ Debug.toString pages
, site =
\_ ->
{ data = DataSource.succeed ()
, canonicalUrl = "canonical-site-url"
, manifest = \_ -> manifest
, head = \_ -> []
}
, view =
\page _ ->
let
thing : Maybe (DataSource a)
thing =
pages
|> Dict.fromList
|> Dict.get
(page.path |> Path.toSegments)
in
case thing of
Just _ ->
\_ _ -> { view = \_ -> { title = "Title", body = Html.text "" }, head = [] }
Nothing ->
Debug.todo <| "Couldn't find page: " ++ Debug.toString page ++ "\npages: " ++ Debug.toString pages
, subscriptions = \_ _ _ -> Sub.none
, routeToPath = \(Route route) -> route |> String.split "/"
, sharedData = DataSource.succeed ()
, onPageChange = \_ -> Continue
, apiRoutes = \_ -> []
, pathPatterns = []
}
encodedFlags : Encode.Value
encodedFlags =
--{"secrets":
-- {"API_KEY": "ABCD1234","BEARER": "XYZ789"}, "mode": "prod", "staticHttpCache": {}
-- }
Encode.object
[ ( "secrets"
, [ ( "API_KEY", "ABCD1234" )
, ( "BEARER", "XYZ789" )
]
|> Dict.fromList
|> Encode.dict identity Encode.string
)
, ( "staticHttpCache", encodedStaticHttpCache )
]
encodedStaticHttpCache : Encode.Value
encodedStaticHttpCache =
staticHttpCache
|> List.map
(\( request, httpResponseString ) ->
( Request.hash request, Encode.string httpResponseString )
)
|> Encode.object
in
{-
(Model -> model)
-> ContentCache.ContentCache metadata view
-> Result (List BuildError) (List ( PagePath, metadata ))
-> Config pathKey userMsg userModel metadata view
-> Decode.Value
-> ( model, Effect pathKey )
-}
ProgramTest.createDocument
{ init =
init
(RenderRequest.SinglePage
RenderRequest.OnlyJson
(RenderRequest.Page
{ path = Path.fromString (pageToLoad |> String.join "/")
, frontmatter = Route (pageToLoad |> String.join "/")
}
)
(Encode.object [])
)
contentCache
config
, update = update contentCache config
, view = \_ -> { title = "", body = [] }
}
|> ProgramTest.withSimulatedEffects simulateEffects
|> ProgramTest.withSimulatedSubscriptions simulateSubscriptions
|> ProgramTest.start (flags (Encode.encode 0 encodedFlags))
flags : String -> JD.Value
2019-10-24 18:26:41 +03:00
flags jsonString =
case JD.decodeString JD.value jsonString of
2019-10-24 18:26:41 +03:00
Ok value ->
value
Err _ ->
Debug.todo "Invalid JSON value."
sendToJsPort value =
SimulatedEffect.Ports.send "toJsPort" (value |> Codec.encoder (ToJsPayload.successCodecNew2 "" ""))
2021-04-16 18:04:15 +03:00
simulateEffects : Effect -> ProgramTest.SimulatedEffect Msg
simulateEffects effect =
case effect of
2020-06-12 06:57:19 +03:00
Effect.NoEffect ->
SimulatedEffect.Cmd.none
2020-06-12 06:57:19 +03:00
Effect.SendJsData value ->
2021-04-16 18:04:15 +03:00
SimulatedEffect.Ports.send "toJsPort" (value |> Codec.encoder ToJsPayload.toJsCodec)
-- toJsPort value |> Cmd.map never
2020-06-12 06:57:19 +03:00
Effect.Batch list ->
list
|> List.map simulateEffects
|> SimulatedEffect.Cmd.batch
2021-04-03 00:44:40 +03:00
Effect.FetchHttp ({ unmasked } as requests) ->
let
_ =
Debug.log "Fetching " unmasked.url
in
if unmasked.url |> String.startsWith "file://" then
let
filePath : String
filePath =
String.dropLeft 7 unmasked.url
in
ToJsPayload.ReadFile filePath
|> sendToJsPort
|> SimulatedEffect.Cmd.map never
else if unmasked.url |> String.startsWith "glob://" then
let
globPattern : String
globPattern =
String.dropLeft 7 unmasked.url
in
ToJsPayload.Glob globPattern
|> sendToJsPort
|> SimulatedEffect.Cmd.map never
else if unmasked.url |> String.startsWith "port://" then
let
portName : String
portName =
String.dropLeft 7 unmasked.url
in
ToJsPayload.Port portName
|> sendToJsPort
|> SimulatedEffect.Cmd.map never
else
let
_ =
Debug.log "Fetching" unmasked.url
in
Http.request
{ method = unmasked.method
, url = unmasked.url
, headers = unmasked.headers |> List.map (\( key, value ) -> Http.header key value)
, body =
case unmasked.body of
StaticHttpBody.EmptyBody ->
Http.emptyBody
StaticHttpBody.StringBody contentType string ->
Http.stringBody contentType string
StaticHttpBody.JsonBody value ->
Http.jsonBody value
, expect =
PagesHttp.expectString
(\response ->
GotStaticHttpResponse
{ request = requests
, response = response
}
)
, timeout = Nothing
, tracker = Nothing
}
Effect.SendSinglePage done info ->
2020-10-14 07:02:12 +03:00
SimulatedEffect.Cmd.batch
2020-10-18 04:58:17 +03:00
[ info
2020-10-20 03:41:27 +03:00
|> Codec.encoder (ToJsPayload.successCodecNew2 "" "")
2020-10-18 04:58:17 +03:00
|> SimulatedEffect.Ports.send "toJsPort"
, if done then
SimulatedEffect.Cmd.none
else
SimulatedEffect.Task.succeed ()
|> SimulatedEffect.Task.perform (\_ -> Continue)
2020-10-14 07:02:12 +03:00
]
Effect.Continue ->
2020-10-14 07:02:12 +03:00
SimulatedEffect.Cmd.none
2021-04-03 00:44:40 +03:00
Effect.ReadFile _ ->
2021-04-01 05:55:28 +03:00
SimulatedEffect.Cmd.none
2021-04-03 00:44:40 +03:00
Effect.GetGlob _ ->
2021-04-01 05:55:28 +03:00
SimulatedEffect.Cmd.none
2021-04-16 18:04:15 +03:00
expectErrorsPort : String -> List ToJsPayload -> Expect.Expectation
2019-11-03 00:46:52 +03:00
expectErrorsPort expectedPlainString actualPorts =
case actualPorts of
2020-06-12 06:55:19 +03:00
[ ToJsPayload.Errors actualRichTerminalString ] ->
2020-01-28 02:28:42 +03:00
actualRichTerminalString
|> List.map .title
|> String.join "\n"
2020-01-28 02:28:42 +03:00
|> normalizeErrorExpectEqual expectedPlainString
[] ->
Expect.fail "Expected single error port. Didn't receive any ports."
2020-01-28 02:28:42 +03:00
_ ->
Expect.fail <| "Expected single error port. Got\n" ++ String.join "\n\n" (List.map Debug.toString actualPorts)
normalizeErrorExpectEqual : String -> String -> Expect.Expectation
normalizeErrorExpectEqual expectedPlainString actualRichTerminalString =
actualRichTerminalString
|> Regex.replace
(Regex.fromString "\u{001B}\\[[0-9;]+m"
|> Maybe.withDefault Regex.never
)
(\_ -> "")
|> normalizeNewlines
|> Expect.equal
(expectedPlainString |> normalizeNewlines)
normalizeNewlines : String -> String
normalizeNewlines string =
string
|> Regex.replace
(Regex.fromString "(\n)+" |> Maybe.withDefault Regex.never)
(\_ -> "")
|> Regex.replace
(Regex.fromString "( )+" |> Maybe.withDefault Regex.never)
(\_ -> " ")
2019-11-03 00:46:52 +03:00
2021-06-04 03:59:58 +03:00
toJsPort : a -> Cmd msg
2021-04-03 00:49:18 +03:00
toJsPort _ =
Cmd.none
2021-06-04 03:59:58 +03:00
fromJsPort : Sub msg
fromJsPort =
Sub.none
2021-04-16 18:04:15 +03:00
manifest : Manifest.Config
manifest =
2021-04-23 18:47:11 +03:00
Manifest.init
{ description = "elm-pages - A statically typed site generator."
, name = "elm-pages docs"
2021-05-23 20:53:43 +03:00
, startUrl = Path.join []
2021-04-23 18:47:11 +03:00
, icons = []
}
2020-05-12 02:42:54 +03:00
starDecoder : Decoder Int
starDecoder =
Decode.field "stargazer_count" Decode.int
expectSuccess : List ( String, List ( Request.Request, String ) ) -> ProgramTest model msg effect -> Expect.Expectation
expectSuccess expectedRequests previous =
expectSuccessNew expectedRequests [] previous
2021-04-16 18:04:15 +03:00
expectSuccessNew : List ( String, List ( Request.Request, String ) ) -> List (ToJsPayload.ToJsSuccessPayload -> Expect.Expectation) -> ProgramTest model msg effect -> Expect.Expectation
expectSuccessNew expectedRequests expectations previous =
previous
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
2021-04-16 18:04:15 +03:00
(Codec.decoder ToJsPayload.toJsCodec)
(\value ->
case value of
2021-04-03 00:44:40 +03:00
(ToJsPayload.Success portPayload) :: _ ->
portPayload
|> Expect.all
((\subject ->
subject.pages
|> Expect.equalDicts
(expectedRequests
|> List.map
(\( url, requests ) ->
( url
, requests
|> List.map
(\( request, response ) ->
( Request.hash request, response )
)
|> Dict.fromList
)
)
|> Dict.fromList
)
)
:: expectations
)
[ errorPort ] ->
Expect.fail <| "Expected success port. Got:\n" ++ Debug.toString errorPort
_ ->
Expect.fail ("Expected ports to be called once, but instead there were " ++ String.fromInt (List.length value) ++ " calls.")
)
simulateSubscriptions : a -> ProgramTest.SimulatedSub Msg
simulateSubscriptions _ =
SimulatedEffect.Ports.subscribe "fromJsPort"
(JD.field "tag" JD.string
|> JD.andThen
(\tag ->
case tag of
"GotGlob" ->
JD.field "data"
(JD.map2 Tuple.pair
(JD.field "pattern" JD.string)
(JD.field "result" JD.value)
)
|> JD.map GotGlob
"GotFile" ->
JD.field "data"
(JD.map2 Tuple.pair
(JD.field "filePath" JD.string)
JD.value
)
|> JD.map GotStaticFile
_ ->
JD.fail "Unexpected subscription tag."
)
)
identity
get : String -> Request.Request
get url =
{ method = "GET"
, url = url
, headers = []
2021-04-20 17:31:19 +03:00
, body = DataSource.emptyBody
}