0

If you want beautiful URLs in an IHP app you need to write your own CanRoute instance and parse the route string.

-- Web.Routes.hs

module Web.Routes where

import Generated.Types
import IHP.RouterPrelude
import Web.Types

instance CanRoute Co2ProducersController where
  parseRoute' = do
    string "/producers/"
    let co2ProducerById = do
          id <- parseId
          endOfInput
          pure ShowCo2ProducerAction {co2ProducerId = Just id, slug = Nothing}

        co2ProducerBySlug = do
          slug <- parseText
          pure ShowCo2ProducerAction {co2ProducerId = Nothing, slug = Just slug}

    co2ProducerBySlug <|> co2ProducerById

How would I go about testing this? I saw an example that seams to setup a whole test application here: https://github.com/digitallyinduced/ihp/blob/2422bbdfa6165231e89b44c2e7d1c68b65f6b3b4/Test/RouterSupportSpec.hs

But I only want to test if I parse the routes correctly and not send a request and test the response.

What would be a simple way to test the above code?

1 Answers1

4

The parseRoute' function of the CanRoute we define for custom routes is basically just returning an attoparsec parser.

We can use attoparsecs parseOnly to run the parser with a provided input string. Here's an example:

module Test.Web.RoutesSpec where

import Test.Hspec
import IHP.ControllerPrelude
import IHP.Test.Mocking
import qualified Data.Attoparsec.ByteString as Attoparsec
import Web.Types
import Web.FrontController

tests = beforeAll (mockContextNoDatabase WebApplication (pure ())) do
    describe "Web.Routes" do
        describe "DocumentationController" do
            it "should be available at /docs" $ withContext do
                "/docs/api-reference/0bca60db-571e-4cdd-b02a-8d5b9e7e6295" `shouldRouteTo` DocumentationAction { projectId = "0bca60db-571e-4cdd-b02a-8d5b9e7e6295" }

shouldRouteTo path action = (Attoparsec.parseOnly parseRoute' path) `shouldBe` (Right action)
Marc Scholten
  • 1,351
  • 3
  • 5