packages feed

yesod-core-1.7.0.0: test/YesodCoreTest/ParamNestedNoFallthroughRuntime.hs

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -Wno-orphans #-}

-- | Exercises the *delegated* (nested-instance) no-fallthrough dispatch path
-- for a 'ResourceParent' child.
--
-- "YesodCoreTest.ParamNoFallthroughRuntime" is two levels deep (parent ->
-- leaf), so the parent's generated @YesodDispatchNested@ instance only ever
-- dispatches to leaf children. This module goes three levels deep
-- (grandparent -> parent -> leaf) under nested discovery (the site carries a
-- type parameter), so the grandparent's nested instance dispatches to the
-- *inner parent* via 'genNestedDispatchClauses' @ResourceParent@ arm — the arm
-- that, with fallthrough disabled, must convert an inner @Nothing@ into a 404
-- commit rather than returning the raw @Maybe@ (which under an outer
-- fallthrough caller would leak through to sibling routes).
module YesodCoreTest.ParamNestedNoFallthroughRuntime
    ( specs
    ) where

import Test.Hspec
import Data.ByteString.Lazy (ByteString)
import Data.Text (Text)
import Yesod.Core

import YesodCoreTest.RuntimeHarness (assertGet)

data PNNApp a = PNNApp a

-- Three-level nesting, generated WITHOUT setNestedRouteFallthrough. A request
-- that matches the grandparent and inner-parent prefixes but no leaf must
-- commit to a 404 (the inner parent is delegated to via its own nested
-- dispatch instance), never fall through.
mkYesodOpts
    (setParameterizedSubroute True defaultOpts)
    "PNNApp a"
    [parseRoutesNoCheck|
/grand   GrandR:
    /inner  InnerR:
        /leaf   LeafR
        /also   AlsoR
|]

instance Yesod (PNNApp a) where
    messageLoggerSource = mempty

handleLeafR :: HandlerFor app String
handleLeafR = pure "LeafR"

handleAlsoR :: HandlerFor app String
handleAlsoR = pure "AlsoR"

testRequestIO :: HasCallStack => Int -> [Text] -> Maybe ByteString -> IO ()
testRequestIO = assertGet (PNNApp ())

specs :: Spec
specs = describe "parameterized site, deep nesting, fallthrough DISABLED" $ do
    it "matches a leaf under the inner parent (/grand/inner/leaf)" $
        testRequestIO 200 ["grand", "inner", "leaf"] (Just "LeafR")
    it "matches the inner parent's other leaf (/grand/inner/also)" $
        testRequestIO 200 ["grand", "inner", "also"] (Just "AlsoR")
    it "404s when the grandparent+parent prefix match but no leaf does (/grand/inner/nope)" $
        -- Drives the delegated ResourceParent no-fallthrough arm: GrandR's
        -- nested instance dispatches to InnerR's nested instance, which returns
        -- Nothing for "nope"; that must become a committed 404.
        testRequestIO 404 ["grand", "inner", "nope"] Nothing
    it "404s when only the grandparent prefix matches (/grand/nope)" $
        testRequestIO 404 ["grand", "nope"] Nothing