+1
-1
@@ -640,7 +640,7 @@ stripTrailingCr bs
|
|||||||
foldLines :: Maybe Text -> [BS.ByteString] -> [BS.ByteString] -> (Maybe Text, [BS.ByteString], [PushEvent])
|
foldLines :: Maybe Text -> [BS.ByteString] -> [BS.ByteString] -> (Maybe Text, [BS.ByteString], [PushEvent])
|
||||||
foldLines evtType0 dLines0 sseLines =
|
foldLines evtType0 dLines0 sseLines =
|
||||||
let (evt, dl, evts) = foldl' step (evtType0, dLines0, []) sseLines
|
let (evt, dl, evts) = foldl' step (evtType0, dLines0, []) sseLines
|
||||||
in (evt, dl, reverse evts)
|
in (evt, dl, reverse evts)
|
||||||
where
|
where
|
||||||
step (evt, dl, events) line
|
step (evt, dl, events) line
|
||||||
| BS.null line =
|
| BS.null line =
|
||||||
|
|||||||
+78
-75
@@ -1,18 +1,18 @@
|
|||||||
module RelaySpec (spec) where
|
module RelaySpec (spec) where
|
||||||
|
|
||||||
import Converge
|
import Converge (
|
||||||
( PushEvent (..),
|
PushEvent (..),
|
||||||
RepoConfig (..),
|
RepoConfig (..),
|
||||||
extractLines,
|
extractLines,
|
||||||
foldLines,
|
foldLines,
|
||||||
handleSSEEvent,
|
handleSSEEvent,
|
||||||
parseEvent,
|
parseEvent,
|
||||||
)
|
)
|
||||||
import qualified Data.ByteString.Char8 as BSC
|
import qualified Data.ByteString.Char8 as BSC
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import System.FilePath ((</>))
|
import System.FilePath ((</>))
|
||||||
import TestHelper (commitCount, runGitIn, testLogger, withTempGitRepoWithRemote)
|
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
import TestHelper (commitCount, runGitIn, testLogger, withTempGitRepoWithRemote)
|
||||||
|
|
||||||
spec :: Spec
|
spec :: Spec
|
||||||
spec = do
|
spec = do
|
||||||
@@ -65,29 +65,29 @@ foldLinesSpec :: Spec
|
|||||||
foldLinesSpec = describe "foldLines" $ do
|
foldLinesSpec = describe "foldLines" $ do
|
||||||
it "parses a single push event" $ do
|
it "parses a single push event" $ do
|
||||||
let lines' =
|
let lines' =
|
||||||
[ bsc "event: push",
|
[ bsc "event: push"
|
||||||
bsc "data: {\"full_name\":\"myorg/myrepo\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}",
|
, bsc "data: {\"full_name\":\"myorg/myrepo\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}"
|
||||||
bsc ""
|
, bsc ""
|
||||||
]
|
]
|
||||||
(finalEvtType, finalDLines, events) = foldLines Nothing [] lines'
|
(finalEvtType, finalDLines, events) = foldLines Nothing [] lines'
|
||||||
events `shouldBe`
|
events
|
||||||
[ PushEvent
|
`shouldBe` [ PushEvent
|
||||||
{ peFullName = "myorg/myrepo",
|
{ peFullName = "myorg/myrepo"
|
||||||
peBranch = "main",
|
, peBranch = "main"
|
||||||
peRef = "refs/heads/main"
|
, peRef = "refs/heads/main"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
finalEvtType `shouldBe` Nothing
|
finalEvtType `shouldBe` Nothing
|
||||||
finalDLines `shouldBe` []
|
finalDLines `shouldBe` []
|
||||||
|
|
||||||
it "parses two push events" $ do
|
it "parses two push events" $ do
|
||||||
let lines' =
|
let lines' =
|
||||||
[ bsc "event: push",
|
[ bsc "event: push"
|
||||||
bsc "data: {\"full_name\":\"a/b\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}",
|
, bsc "data: {\"full_name\":\"a/b\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}"
|
||||||
bsc "",
|
, bsc ""
|
||||||
bsc "event: push",
|
, bsc "event: push"
|
||||||
bsc "data: {\"full_name\":\"c/d\",\"branch\":\"dev\",\"ref\":\"refs/heads/dev\"}",
|
, bsc "data: {\"full_name\":\"c/d\",\"branch\":\"dev\",\"ref\":\"refs/heads/dev\"}"
|
||||||
bsc ""
|
, bsc ""
|
||||||
]
|
]
|
||||||
(_, _, events) = foldLines Nothing [] lines'
|
(_, _, events) = foldLines Nothing [] lines'
|
||||||
length events `shouldBe` 2
|
length events `shouldBe` 2
|
||||||
@@ -96,28 +96,28 @@ foldLinesSpec = describe "foldLines" $ do
|
|||||||
|
|
||||||
it "ignores non-push events" $ do
|
it "ignores non-push events" $ do
|
||||||
let lines' =
|
let lines' =
|
||||||
[ bsc "event: ping",
|
[ bsc "event: ping"
|
||||||
bsc "data: hello",
|
, bsc "data: hello"
|
||||||
bsc ""
|
, bsc ""
|
||||||
]
|
]
|
||||||
(_, _, events) = foldLines Nothing [] lines'
|
(_, _, events) = foldLines Nothing [] lines'
|
||||||
events `shouldBe` []
|
events `shouldBe` []
|
||||||
|
|
||||||
it "ignores comment lines (starting with colon)" $ do
|
it "ignores comment lines (starting with colon)" $ do
|
||||||
let lines' =
|
let lines' =
|
||||||
[ bsc ": this is a comment",
|
[ bsc ": this is a comment"
|
||||||
bsc "event: push",
|
, bsc "event: push"
|
||||||
bsc "data: {\"full_name\":\"a/b\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}",
|
, bsc "data: {\"full_name\":\"a/b\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}"
|
||||||
bsc ""
|
, bsc ""
|
||||||
]
|
]
|
||||||
(_, _, events) = foldLines Nothing [] lines'
|
(_, _, events) = foldLines Nothing [] lines'
|
||||||
length events `shouldBe` 1
|
length events `shouldBe` 1
|
||||||
|
|
||||||
it "handles event: without space after colon" $ do
|
it "handles event: without space after colon" $ do
|
||||||
let lines' =
|
let lines' =
|
||||||
[ bsc "event:push",
|
[ bsc "event:push"
|
||||||
bsc "data:{\"full_name\":\"a/b\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}",
|
, bsc "data:{\"full_name\":\"a/b\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}"
|
||||||
bsc ""
|
, bsc ""
|
||||||
]
|
]
|
||||||
(_, _, events) = foldLines Nothing [] lines'
|
(_, _, events) = foldLines Nothing [] lines'
|
||||||
length events `shouldBe` 1
|
length events `shouldBe` 1
|
||||||
@@ -143,12 +143,13 @@ parseEventSpec :: Spec
|
|||||||
parseEventSpec = describe "parseEvent" $ do
|
parseEventSpec = describe "parseEvent" $ do
|
||||||
it "parses a valid push event" $ do
|
it "parses a valid push event" $ do
|
||||||
let evt = parseEvent (Just "push") [bsc "{\"full_name\":\"org/repo\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}"]
|
let evt = parseEvent (Just "push") [bsc "{\"full_name\":\"org/repo\",\"branch\":\"main\",\"ref\":\"refs/heads/main\"}"]
|
||||||
evt `shouldBe` Just
|
evt
|
||||||
PushEvent
|
`shouldBe` Just
|
||||||
{ peFullName = "org/repo",
|
PushEvent
|
||||||
peBranch = "main",
|
{ peFullName = "org/repo"
|
||||||
peRef = "refs/heads/main"
|
, peBranch = "main"
|
||||||
}
|
, peRef = "refs/heads/main"
|
||||||
|
}
|
||||||
|
|
||||||
it "returns Nothing for non-push event type" $ do
|
it "returns Nothing for non-push event type" $ do
|
||||||
let evt = parseEvent (Just "ping") [bsc "{}"]
|
let evt = parseEvent (Just "ping") [bsc "{}"]
|
||||||
@@ -159,17 +160,20 @@ parseEventSpec = describe "parseEvent" $ do
|
|||||||
evt `shouldBe` Nothing
|
evt `shouldBe` Nothing
|
||||||
|
|
||||||
it "handles multiple data lines joined" $ do
|
it "handles multiple data lines joined" $ do
|
||||||
let evt = parseEvent (Just "push")
|
let evt =
|
||||||
[ bsc "{\"full_name\":\"x\"",
|
parseEvent
|
||||||
bsc ",\"branch\":\"y\"",
|
(Just "push")
|
||||||
bsc ",\"ref\":\"z\"}"
|
[ bsc "{\"full_name\":\"x\""
|
||||||
]
|
, bsc ",\"branch\":\"y\""
|
||||||
evt `shouldBe` Just
|
, bsc ",\"ref\":\"z\"}"
|
||||||
PushEvent
|
]
|
||||||
{ peFullName = "x",
|
evt
|
||||||
peBranch = "y",
|
`shouldBe` Just
|
||||||
peRef = "z"
|
PushEvent
|
||||||
}
|
{ peFullName = "x"
|
||||||
|
, peBranch = "y"
|
||||||
|
, peRef = "z"
|
||||||
|
}
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
-- handleSSEEvent (integration — uses real git repos)
|
-- handleSSEEvent (integration — uses real git repos)
|
||||||
@@ -206,9 +210,9 @@ handleSSEEventSpec = describe "handleSSEEvent" $ do
|
|||||||
-- Send a matching push event
|
-- Send a matching push event
|
||||||
let evt =
|
let evt =
|
||||||
PushEvent
|
PushEvent
|
||||||
{ peFullName = "test-org/test-repo",
|
{ peFullName = "test-org/test-repo"
|
||||||
peBranch = "main",
|
, peBranch = "main"
|
||||||
peRef = "refs/heads/main"
|
, peRef = "refs/heads/main"
|
||||||
}
|
}
|
||||||
handleSSEEvent logger [repoCfg] evt
|
handleSSEEvent logger [repoCfg] evt
|
||||||
|
|
||||||
@@ -225,33 +229,32 @@ handleSSEEventSpec = describe "handleSSEEvent" $ do
|
|||||||
}
|
}
|
||||||
let evt =
|
let evt =
|
||||||
PushEvent
|
PushEvent
|
||||||
{ peFullName = "other-org/other-repo",
|
{ peFullName = "other-org/other-repo"
|
||||||
peBranch = "main",
|
, peBranch = "main"
|
||||||
peRef = "refs/heads/main"
|
, peRef = "refs/heads/main"
|
||||||
}
|
}
|
||||||
-- This should not crash or pull — it just ignores
|
-- This should not crash or pull — it just ignores
|
||||||
handleSSEEvent logger [repoCfg] evt
|
handleSSEEvent logger [repoCfg] evt
|
||||||
-- Test passes if no exception is thrown
|
-- Test passes if no exception is thrown
|
||||||
|
|
||||||
it "ignores events for repos with non-matching branch" $
|
it "ignores events for repos with non-matching branch" $
|
||||||
withTempGitRepoWithRemote $ \localRepo -> do
|
withTempGitRepoWithRemote $ \localRepo -> do
|
||||||
logger <- testLogger
|
logger <- testLogger
|
||||||
let repoCfg =
|
let repoCfg =
|
||||||
(defaultRepoCfg localRepo)
|
(defaultRepoCfg localRepo)
|
||||||
{ rcGiteaRepo = Just "test-org/test-repo",
|
{ rcGiteaRepo = Just "test-org/test-repo"
|
||||||
rcBranch = "main"
|
, rcBranch = "main"
|
||||||
}
|
}
|
||||||
let evt =
|
let evt =
|
||||||
PushEvent
|
PushEvent
|
||||||
{ peFullName = "test-org/test-repo",
|
{ peFullName = "test-org/test-repo"
|
||||||
peBranch = "dev",
|
, peBranch = "dev"
|
||||||
peRef = "refs/heads/dev"
|
, peRef = "refs/heads/dev"
|
||||||
}
|
}
|
||||||
commitsBefore <- commitCount localRepo
|
commitsBefore <- commitCount localRepo
|
||||||
handleSSEEvent logger [repoCfg] evt
|
handleSSEEvent logger [repoCfg] evt
|
||||||
commitsAfter <- commitCount localRepo
|
commitsAfter <- commitCount localRepo
|
||||||
commitsAfter `shouldBe` commitsBefore -- no pull should have happened
|
commitsAfter `shouldBe` commitsBefore -- no pull should have happened
|
||||||
|
|
||||||
it "skips pull when an operation is in progress" $
|
it "skips pull when an operation is in progress" $
|
||||||
withTempGitRepoWithRemote $ \localRepo -> do
|
withTempGitRepoWithRemote $ \localRepo -> do
|
||||||
logger <- testLogger
|
logger <- testLogger
|
||||||
@@ -275,14 +278,14 @@ handleSSEEventSpec = describe "handleSSEEvent" $ do
|
|||||||
}
|
}
|
||||||
let evt =
|
let evt =
|
||||||
PushEvent
|
PushEvent
|
||||||
{ peFullName = "test-org/test-repo",
|
{ peFullName = "test-org/test-repo"
|
||||||
peBranch = "main",
|
, peBranch = "main"
|
||||||
peRef = "refs/heads/main"
|
, peRef = "refs/heads/main"
|
||||||
}
|
}
|
||||||
handleSSEEvent logger [repoCfg] evt
|
handleSSEEvent logger [repoCfg] evt
|
||||||
|
|
||||||
commitsAfter <- commitCount localRepo
|
commitsAfter <- commitCount localRepo
|
||||||
commitsAfter `shouldBe` commitsBefore -- pull should be skipped
|
commitsAfter `shouldBe` commitsBefore -- pull should be skipped
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
-- Helpers
|
-- Helpers
|
||||||
@@ -296,9 +299,9 @@ bsc = BSC.pack
|
|||||||
defaultRepoCfg :: FilePath -> RepoConfig
|
defaultRepoCfg :: FilePath -> RepoConfig
|
||||||
defaultRepoCfg path =
|
defaultRepoCfg path =
|
||||||
RepoConfig
|
RepoConfig
|
||||||
{ rcPath = path,
|
{ rcPath = path
|
||||||
rcRemote = "origin",
|
, rcRemote = "origin"
|
||||||
rcBranch = "main",
|
, rcBranch = "main"
|
||||||
rcNotifyOnPull = False,
|
, rcNotifyOnPull = False
|
||||||
rcGiteaRepo = Nothing
|
, rcGiteaRepo = Nothing
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user