- gitoevents: Gito 이벤트 클라이언트 및 이벤트 모델 구현 - gitosync: 브리지, 러너, 스캐너 구현으로 브랜치 이벤트 및 작업 항목 동기화 - config: 새 설정 항목 추가 및 테스트 - roadmapsync: plane projection 수정 및 테스트 - agent-task: G07 관련 계획 및 코드 리뷰 로그 추가 - roadmap: PHASE 및 마일스톤 업데이트 - contracts: Flutter core API 후보 노트 업데이트
171 lines
5.4 KiB
Go
171 lines
5.4 KiB
Go
package gitoevents
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/nomadcode/nomadcode-core/internal/protosocket"
|
|
)
|
|
|
|
// branchUpdatedEnvelope builds a contract-shaped broadcast envelope fixture.
|
|
func branchUpdatedEnvelope() protosocket.Envelope {
|
|
return protosocket.Envelope{
|
|
ProtocolVersion: protosocket.ProtocolVersion,
|
|
ID: "event-id",
|
|
Type: "event",
|
|
Channel: EventChannel,
|
|
Action: BranchUpdatedAction,
|
|
Payload: map[string]any{
|
|
"id": "event-id",
|
|
"type": "branch.updated",
|
|
"provider": "forgejo",
|
|
"delivery_id": "delivery-id",
|
|
"repo_id": "nomadcode",
|
|
"branch": "develop",
|
|
"before": "old-sha",
|
|
"after": "new-sha",
|
|
"changed_files": []any{
|
|
map[string]any{
|
|
"path": "agent-roadmap/phase/example/milestones/example.md",
|
|
"change_type": "modified",
|
|
},
|
|
map[string]any{
|
|
"path": "README.md",
|
|
"change_type": "modified",
|
|
},
|
|
},
|
|
"observed_at": "2026-06-13T00:00:00Z",
|
|
"created_at": "2026-06-13T00:00:00Z",
|
|
},
|
|
}
|
|
}
|
|
|
|
func TestBuildSubscribeEnvelopeMatchesContract(t *testing.T) {
|
|
env := BuildSubscribeEnvelope("msg-1", "nomadcode", "develop")
|
|
|
|
if env.ProtocolVersion != protosocket.ProtocolVersion {
|
|
t.Fatalf("protocol_version: got %q", env.ProtocolVersion)
|
|
}
|
|
if env.ID != "msg-1" {
|
|
t.Fatalf("id: got %q", env.ID)
|
|
}
|
|
if env.Type != "request" {
|
|
t.Fatalf("type: got %q, want request", env.Type)
|
|
}
|
|
if env.Channel != EventChannel {
|
|
t.Fatalf("channel: got %q, want %q", env.Channel, EventChannel)
|
|
}
|
|
if env.Action != SubscribeAction {
|
|
t.Fatalf("action: got %q, want %q", env.Action, SubscribeAction)
|
|
}
|
|
if got := env.Payload["repo_id"]; got != "nomadcode" {
|
|
t.Fatalf("payload.repo_id: got %v", got)
|
|
}
|
|
if got := env.Payload["branch"]; got != "develop" {
|
|
t.Fatalf("payload.branch: got %v", got)
|
|
}
|
|
events, ok := env.Payload["events"].([]any)
|
|
if !ok || len(events) != 1 || events[0] != BranchUpdatedAction {
|
|
t.Fatalf("payload.events: got %v", env.Payload["events"])
|
|
}
|
|
}
|
|
|
|
func TestBuildSubscribeEnvelopeDefaultsBranch(t *testing.T) {
|
|
env := BuildSubscribeEnvelope("msg-1", "nomadcode", "")
|
|
if got := env.Payload["branch"]; got != DefaultBranch {
|
|
t.Fatalf("payload.branch default: got %v, want %q", got, DefaultBranch)
|
|
}
|
|
}
|
|
|
|
func TestDecodeBranchUpdatedEnvelope(t *testing.T) {
|
|
ev, err := DecodeBranchUpdatedEnvelope(branchUpdatedEnvelope())
|
|
if err != nil {
|
|
t.Fatalf("decode: unexpected error: %v", err)
|
|
}
|
|
if ev.RepoID != "nomadcode" || ev.Branch != "develop" {
|
|
t.Fatalf("repo/branch: got %q/%q", ev.RepoID, ev.Branch)
|
|
}
|
|
if ev.Before != "old-sha" || ev.After != "new-sha" {
|
|
t.Fatalf("before/after: got %q/%q", ev.Before, ev.After)
|
|
}
|
|
if ev.DeliveryID != "delivery-id" || ev.Provider != "forgejo" {
|
|
t.Fatalf("delivery/provider: got %q/%q", ev.DeliveryID, ev.Provider)
|
|
}
|
|
if len(ev.ChangedFiles) != 2 {
|
|
t.Fatalf("changed_files: got %d, want 2", len(ev.ChangedFiles))
|
|
}
|
|
if ev.ChangedFiles[0].Path != "agent-roadmap/phase/example/milestones/example.md" {
|
|
t.Fatalf("changed_files[0].path: got %q", ev.ChangedFiles[0].Path)
|
|
}
|
|
}
|
|
|
|
func TestDecodeBranchUpdatedEnvelopeRejectsWrongAction(t *testing.T) {
|
|
env := branchUpdatedEnvelope()
|
|
env.Action = "task.status.changed"
|
|
if _, err := DecodeBranchUpdatedEnvelope(env); err == nil {
|
|
t.Fatal("expected error for wrong action")
|
|
}
|
|
}
|
|
|
|
func TestDecodeBranchUpdatedEnvelopeRejectsWrongChannel(t *testing.T) {
|
|
env := branchUpdatedEnvelope()
|
|
env.Channel = "task"
|
|
if _, err := DecodeBranchUpdatedEnvelope(env); err == nil {
|
|
t.Fatal("expected error for wrong channel")
|
|
}
|
|
}
|
|
|
|
func TestDecodeBranchUpdatedEnvelopeRejectsMalformedChangedFiles(t *testing.T) {
|
|
env := branchUpdatedEnvelope()
|
|
env.Payload["changed_files"] = "not-a-list"
|
|
if _, err := DecodeBranchUpdatedEnvelope(env); err == nil {
|
|
t.Fatal("expected error for malformed changed_files")
|
|
}
|
|
}
|
|
|
|
func TestDecodeBranchUpdatedEnvelopeRejectsMissingRepoID(t *testing.T) {
|
|
env := branchUpdatedEnvelope()
|
|
delete(env.Payload, "repo_id")
|
|
if _, err := DecodeBranchUpdatedEnvelope(env); err == nil {
|
|
t.Fatal("expected error for missing repo_id")
|
|
}
|
|
}
|
|
|
|
func TestIsTarget(t *testing.T) {
|
|
ev := BranchUpdatedEvent{RepoID: "nomadcode", Branch: "develop"}
|
|
|
|
if !ev.IsTarget("nomadcode", "develop") {
|
|
t.Fatal("expected match for same repo/branch")
|
|
}
|
|
if ev.IsTarget("other-repo", "develop") {
|
|
t.Fatal("expected no match for different repo")
|
|
}
|
|
if ev.IsTarget("nomadcode", "main") {
|
|
t.Fatal("expected no match for different branch")
|
|
}
|
|
if !ev.IsTarget("nomadcode", "") {
|
|
t.Fatal("expected empty branch to default to develop and match")
|
|
}
|
|
}
|
|
|
|
func TestMilestoneChangedFiles(t *testing.T) {
|
|
ev := BranchUpdatedEvent{
|
|
ChangedFiles: []ChangedFile{
|
|
{Path: "agent-roadmap/phase/example/milestones/example.md", ChangeType: "modified"},
|
|
{Path: "./agent-roadmap/phase/p/milestones/m.md", ChangeType: "added"},
|
|
{Path: "README.md", ChangeType: "modified"},
|
|
{Path: "agent-roadmap/phase/example/PHASE.md", ChangeType: "modified"},
|
|
{Path: "agent-roadmap/phase/example/milestones/notes.txt", ChangeType: "modified"},
|
|
},
|
|
}
|
|
|
|
got := ev.MilestoneChangedFiles()
|
|
if len(got) != 2 {
|
|
t.Fatalf("milestone changed files: got %d, want 2 (%+v)", len(got), got)
|
|
}
|
|
if got[0].Path != "agent-roadmap/phase/example/milestones/example.md" {
|
|
t.Fatalf("milestone[0]: got %q", got[0].Path)
|
|
}
|
|
if got[1].Path != "./agent-roadmap/phase/p/milestones/m.md" {
|
|
t.Fatalf("milestone[1]: got %q", got[1].Path)
|
|
}
|
|
}
|