⋯ 28 hidden lines@@ -42,22 +43,51 @@ func TestWebInboxEndToEnd(t *testing.T) { 42 assert.Contains(t, empty.body, "no open merge requests." ) 43 assert.Contains(t, empty.body, "no open merge requests." ) 43 assert.Contains(t, empty.body, "no open issues." ) 44 assert.Contains(t, empty.body, "no open issues." ) 44 45 46 + // A queued run is visible and its run-level events refresh the owner stream. 47 + draft, err := r.forge.store.CI().CreateRun(r.ctx, r.name("proj" ), ".github/workflows/build.yml" , func (id, number int64) ports.CIRunDraft { 48 + return ports.CIRunDraft{Run: domain.CIRun{Repo: r.name("proj" ), ID: id, Number: number, Attempt: 1, WorkflowName: "Inbox build" , Status: domain.CIQueued, Ref: "refs/heads/main" , Event: "push" , CreatedAt: time.Now()}} 49 + }) 50 + require.NoError(t, err) 51 + runs := b.get("/-/inbox" , as(token)) 52 + assert.Contains(t, runs.body, "Inbox build" ) 53 + assert.Contains(t, runs.body, "<strong>1</strong> running" ) 54 + assert.Contains(t, runs.body, `data-inbox href="/-/inbox"` ) 55 + 45 // The owner stream sees both repositories. 56 // The owner stream sees both repositories. 46 stream := ownerStream(t, r.harness, token) 57 stream := ownerStream(t, r.harness, token) 47 58 59 + r.forge.Bus.Publish(r.ctx, domain.RunUpdated{Run: draft.Run, At: time.Now(), Visibility: domain.VisibilityPublic, CreatedAt: time.Now()}) 60 + var runFragments strings.Builder 61 + for range 6 { 62 + runFragments.WriteString(nextFragment(t, stream).data) 63 + } 64 + assert.Contains(t, runFragments.String(), "Inbox build" ) 65 + // Completion removes the row and updates the total in the same live fragments. 66 + draft.Run.Status, draft.Run.Conclusion = domain.CICompleted, domain.CISuccess 67 + _, err = r.forge.store.CI().Apply(r.ctx, ports.CIWrite{Runs: []domain.CIRun{draft.Run}}) 68 + require.NoError(t, err) 69 + r.forge.Bus.Publish(r.ctx, domain.RunUpdated{Run: draft.Run, At: time.Now(), Visibility: domain.VisibilityPublic, CreatedAt: time.Now()}) 70 + runFragments.Reset() 71 + for range 6 { 72 + runFragments.WriteString(nextFragment(t, stream).data) 73 + } 74 + assert.NotContains(t, runFragments.String(), "Inbox build" ) 75 + assert.Contains(t, runFragments.String(), "no runs in progress." ) 76 + assert.Contains(t, runFragments.String(), "<strong>0</strong> running" ) 77 + 48 root := domain.Root() 78 root := domain.Root() 49 _, err = r.forge.MergeRequests.Create(r.ctx, root, r.name("proj" ), ports.CreateMergeRequestParams{Title: "add search" , Source: "feat/search" , Target: "main" }) 79 _, err = r.forge.MergeRequests.Create(r.ctx, root, r.name("proj" ), ports.CreateMergeRequestParams{Title: "add search" , Source: "feat/search" , Target: "main" }) 50 require.NoError(t, err) 80 require.NoError(t, err) 51 ev := nextFragment(t, stream) 81 ev := nextFragment(t, stream) 52 assert.Equal(t, "inbox" , ev.name) 82 assert.Equal(t, "inbox" , ev.name) 53 assert.Contains(t, ev.data, `id="inbox-counts"` ) 83 assert.Contains(t, ev.data, `id="inbox-counts"` ) 54 - for range 4 { // the other fragments of this event 84 + for range 5 { // the other fragments of this event 55 nextFragment(t, stream) 85 nextFragment(t, stream) 56 } 86 } 57 _, err = r.forge.Issues.Create(r.ctx, root, r.name("other" ), ports.CreateIssueParams{Title: "search is slow" }) 87 _, err = r.forge.Issues.Create(r.ctx, root, r.name("other" ), ports.CreateIssueParams{Title: "search is slow" }) 58 require.NoError(t, err) 88 require.NoError(t, err) 59 var seen strings.Builder 89 var seen strings.Builder 60 - for range 5 { // the five fragments of this event 90 + for range 6 { // the six fragments of this event 61 seen.WriteString(nextFragment(t, stream).data) 91 seen.WriteString(nextFragment(t, stream).data) 62 } 92 } 63 assert.Contains(t, seen.String(), "search is slow" , "an event of the second repository" ) 93 assert.Contains(t, seen.String(), "search is slow" , "an event of the second repository" )