Skip to content

Commit

Permalink
Update development setup
Browse files Browse the repository at this point in the history
* flake.nix: inherit devShells, so that `nix develop` works
* tests: configurable mock server port to avoid conflicts
  • Loading branch information
int-index committed Sep 11, 2024
1 parent ec098b5 commit f96ebee
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 18 deletions.
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@

in
pkgs.lib.lists.foldr pkgs.lib.recursiveUpdate {} [
{ inherit (flake) packages apps; }
{ inherit (flake) packages apps devShells; }
{
legacyPackages = pkgs;

Expand Down
2 changes: 2 additions & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ tests:
generated-other-modules:
- Paths_xrefcheck
dependencies:
- optparse-applicative
- tagged
- case-insensitive
- cmark-gfm
- containers
Expand Down
7 changes: 6 additions & 1 deletion tests/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ module Main
import Universum

import Test.Tasty
import Test.Tasty.Ingredients (Ingredient)
import Test.Xrefcheck.Util (mockServerOptions)
import Tree (tests)

main :: IO ()
main = tests >>= defaultMain
main = tests >>= defaultMainWithIngredients ingredients

ingredients :: [Ingredient]
ingredients = includingOptions mockServerOptions : defaultIngredients
30 changes: 16 additions & 14 deletions tests/Test/Xrefcheck/ConfigSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Control.Exception qualified as E
import Data.List (isInfixOf)
import Data.Yaml (ParseException (..), decodeEither')
import Network.HTTP.Types (Status (..))
import Test.Tasty (TestTree, testGroup)
import Test.Tasty (TestTree, testGroup, askOption)
import Test.Tasty.HUnit (assertFailure, testCase, (@?=))
import Test.Tasty.QuickCheck (ioProperty, testProperty)

Expand All @@ -22,7 +22,7 @@ import Xrefcheck.Core (Flavor (GitHub), allFlavors)
import Xrefcheck.Scan (ecIgnoreExternalRefsToL)
import Xrefcheck.Verify (VerifyError (..), checkExternalResource)

import Test.Xrefcheck.Util (mockServer)
import Test.Xrefcheck.Util (mockServer, mockServerUrl)

test_config :: [TestTree]
test_config =
Expand All @@ -43,28 +43,29 @@ test_config =
, "and verify changes"
]
]
, testGroup "`ignoreAuthFailures` working as expected" $
, askOption $ \mockServerPort ->
testGroup "`ignoreAuthFailures` working as expected" $
let config = defConfig GitHub & cExclusionsL . ecIgnoreExternalRefsToL .~ []

setIgnoreAuthFailures value =
config & cNetworkingL . ncIgnoreAuthFailuresL .~ value
in [ testCase "when True - assume 401 status is valid" $
checkLinkWithServer (setIgnoreAuthFailures True)
"http://127.0.0.1:3000/401" $ Right ()
checkLinkWithServer mockServerPort (setIgnoreAuthFailures True)
"/401" $ Right ()

, testCase "when False - assume 401 status is invalid" $
checkLinkWithServer (setIgnoreAuthFailures False)
"http://127.0.0.1:3000/401" $
checkLinkWithServer mockServerPort (setIgnoreAuthFailures False)
"/401" $
Left $ ExternalHttpResourceUnavailable $
Status { statusCode = 401, statusMessage = "Unauthorized" }

, testCase "when True - assume 403 status is valid" $
checkLinkWithServer (setIgnoreAuthFailures True)
"http://127.0.0.1:3000/403" $ Right ()
checkLinkWithServer mockServerPort (setIgnoreAuthFailures True)
"/403" $ Right ()

, testCase "when False - assume 403 status is invalid" $
checkLinkWithServer (setIgnoreAuthFailures False)
"http://127.0.0.1:3000/403" $
checkLinkWithServer mockServerPort (setIgnoreAuthFailures False)
"/403" $
Left $ ExternalHttpResourceUnavailable $
Status { statusCode = 403, statusMessage = "Forbidden" }
]
Expand All @@ -80,7 +81,8 @@ test_config =
]

where
checkLinkWithServer config link expectation =
E.bracket (forkIO mockServer) killThread $ \_ -> do
result <- runExceptT $ checkExternalResource emptyChain config link
checkLinkWithServer mockServerPort config link expectation =
E.bracket (forkIO (mockServer mockServerPort)) killThread $ \_ -> do
let url = (mockServerUrl mockServerPort link)
result <- runExceptT $ checkExternalResource emptyChain config url
result @?= expectation
30 changes: 28 additions & 2 deletions tests/Test/Xrefcheck/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ module Test.Xrefcheck.Util where

import Universum

import Data.Tagged (Tagged, untag)
import Options.Applicative (help, long, option, auto)
import Network.HTTP.Types (forbidden403, unauthorized401)
import Web.Firefly (ToResponse (..), route, run)
import Test.Tasty.Options as Tasty (IsOption (..), OptionDescription (Option), safeRead)

import Xrefcheck.Core (Flavor)
import Xrefcheck.Scan (ScanAction)
Expand All @@ -18,7 +21,30 @@ parse :: Flavor -> ScanAction
parse fl path =
markdownScanner MarkdownConfig { mcFlavor = fl } path

mockServer :: IO ()
mockServer = run 3000 $ do
mockServerUrl :: MockServerPort -> Text -> Text
mockServerUrl (MockServerPort port) s = toText ("http://127.0.0.1:" <> show port <> s)

mockServer :: MockServerPort -> IO ()
mockServer (MockServerPort port) = run port $ do
route "/401" $ pure $ toResponse ("" :: Text, unauthorized401)
route "/403" $ pure $ toResponse ("" :: Text, forbidden403)

-- | All options needed to configure the mock server.
mockServerOptions :: [OptionDescription]
mockServerOptions =
[ Tasty.Option (Proxy @MockServerPort)
]

-- | Option specifying FTP host.
newtype MockServerPort = MockServerPort Int
deriving stock (Show, Eq)

instance IsOption MockServerPort where
defaultValue = MockServerPort 3000
optionName = "mock-server-port"
optionHelp = "[Test.Xrefcheck.Util] Mock server port"
parseValue v = MockServerPort <$> safeRead v
optionCLParser = MockServerPort <$> option auto
( long (untag (optionName :: Tagged MockServerPort String))
<> help (untag (optionHelp :: Tagged MockServerPort String))
)

0 comments on commit f96ebee

Please sign in to comment.