@@ -198,6 +198,95 @@ func TestMenuItemTitleTransition(t *testing.T) {
198198 _ = ctx // Unused in this test but would be used for real menu operations
199199}
200200
201+ // TestWorkflowStateNewlyPublished tests that PRs with NEWLY_PUBLISHED workflow state get "- NEW!" suffix.
202+ func TestWorkflowStateNewlyPublished (t * testing.T ) {
203+ tests := []struct {
204+ name string
205+ pr PR
206+ expectedTitle string
207+ }{
208+ {
209+ name : "newly_published_with_action" ,
210+ pr : PR {
211+ Repository : "test/repo" ,
212+ Number : 123 ,
213+ ActionKind : "review" ,
214+ WorkflowState : "NEWLY_PUBLISHED" ,
215+ NeedsReview : true ,
216+ UpdatedAt : time .Now (),
217+ },
218+ expectedTitle : "■ test/repo #123 — review - NEW!" ,
219+ },
220+ {
221+ name : "newly_published_without_action" ,
222+ pr : PR {
223+ Repository : "test/repo" ,
224+ Number : 456 ,
225+ WorkflowState : "NEWLY_PUBLISHED" ,
226+ UpdatedAt : time .Now (),
227+ },
228+ expectedTitle : "test/repo #456 - NEW!" ,
229+ },
230+ {
231+ name : "newly_published_with_running_tests" ,
232+ pr : PR {
233+ Repository : "test/repo" ,
234+ Number : 789 ,
235+ TestState : "running" ,
236+ WorkflowState : "NEWLY_PUBLISHED" ,
237+ UpdatedAt : time .Now (),
238+ },
239+ expectedTitle : "test/repo #789 — tests running... - NEW!" ,
240+ },
241+ {
242+ name : "not_newly_published_with_action" ,
243+ pr : PR {
244+ Repository : "test/repo" ,
245+ Number : 999 ,
246+ ActionKind : "merge" ,
247+ WorkflowState : "WAITING_FOR_REVIEW" ,
248+ NeedsReview : true ,
249+ UpdatedAt : time .Now (),
250+ },
251+ expectedTitle : "■ test/repo #999 — merge" ,
252+ },
253+ }
254+
255+ for _ , tt := range tests {
256+ t .Run (tt .name , func (t * testing.T ) {
257+ // Helper function to generate title (mirrors the logic in ui.go)
258+ generateTitle := func (pr PR ) string {
259+ title := fmt .Sprintf ("%s #%d" , pr .Repository , pr .Number )
260+
261+ // Add action code if present, or test state as fallback
262+ if pr .ActionKind != "" {
263+ actionDisplay := strings .ReplaceAll (pr .ActionKind , "_" , " " )
264+ title = fmt .Sprintf ("%s — %s" , title , actionDisplay )
265+ } else if pr .TestState == "running" {
266+ title = fmt .Sprintf ("%s — tests running..." , title )
267+ }
268+
269+ // Add "- NEW!" suffix if workflow state is NEWLY_PUBLISHED
270+ if pr .WorkflowState == "NEWLY_PUBLISHED" {
271+ title = fmt .Sprintf ("%s - NEW!" , title )
272+ }
273+
274+ // Add prefix based on blocked status
275+ if pr .NeedsReview || pr .IsBlocked {
276+ title = fmt .Sprintf ("■ %s" , title )
277+ }
278+
279+ return title
280+ }
281+
282+ actualTitle := generateTitle (tt .pr )
283+ if actualTitle != tt .expectedTitle {
284+ t .Errorf ("Expected title %q, got %q" , tt .expectedTitle , actualTitle )
285+ }
286+ })
287+ }
288+ }
289+
201290// TestTrayIconRestoredAfterNetworkRecovery tests that the tray icon is restored
202291// to normal after network failures are resolved.
203292func TestTrayIconRestoredAfterNetworkRecovery (t * testing.T ) {
0 commit comments