@@ -488,6 +488,159 @@ func TestUserEditsMaintenanceFromIntervalToNone(t *testing.T) {
488488 assert .Empty (t , cells [int (maintenanceColEvery )].Value )
489489}
490490
491+ // User creates a maintenance item with a season tag.
492+ func TestUserCreatesMaintenanceWithSeason (t * testing.T ) {
493+ t .Parallel ()
494+ m := newTestModelWithStore (t )
495+ m .active = tabIndex (tabMaintenance )
496+ openAddForm (m )
497+
498+ values , ok := m .fs .formData .(* maintenanceFormData )
499+ require .True (t , ok )
500+ values .Name = "Clean Gutters"
501+ values .Season = data .SeasonSpring
502+ sendKey (m , "ctrl+s" )
503+ sendKey (m , "esc" )
504+
505+ // Verify persisted to DB.
506+ items , err := m .store .ListMaintenance (false )
507+ require .NoError (t , err )
508+ require .Len (t , items , 1 )
509+ assert .Equal (t , data .SeasonSpring , items [0 ].Season )
510+
511+ // Verify table column renders the season.
512+ m .reloadAll ()
513+ require .NoError (t , m .reloadActiveTab ())
514+ tab := m .activeTab ()
515+ require .NotEmpty (t , tab .CellRows )
516+ seasonCell := tab .CellRows [0 ][int (maintenanceColSeason )]
517+ assert .Equal (t , data .SeasonSpring , seasonCell .Value )
518+ assert .Equal (t , cellStatus , seasonCell .Kind )
519+ }
520+
521+ // User edits a maintenance item to change its season.
522+ func TestUserEditsMaintenanceSeason (t * testing.T ) {
523+ t .Parallel ()
524+ m := newTestModelWithStore (t )
525+ m .active = tabIndex (tabMaintenance )
526+
527+ // Create with spring.
528+ openAddForm (m )
529+ values , ok := m .fs .formData .(* maintenanceFormData )
530+ require .True (t , ok )
531+ values .Name = "Service AC"
532+ values .Season = data .SeasonSpring
533+ sendKey (m , "ctrl+s" )
534+ sendKey (m , "esc" )
535+
536+ m .reloadAll ()
537+ require .NoError (t , m .reloadActiveTab ())
538+ tab := m .activeTab ()
539+ require .NotEmpty (t , tab .Rows )
540+ tab .Table .SetCursor (0 )
541+ id := tab .Rows [0 ].ID
542+
543+ // Open full edit form via ID column.
544+ sendKey (m , "i" )
545+ tab .ColCursor = int (maintenanceColID )
546+ sendKey (m , "e" )
547+ require .Equal (t , modeForm , m .mode )
548+
549+ editValues , ok := m .fs .formData .(* maintenanceFormData )
550+ require .True (t , ok )
551+ assert .Equal (t , data .SeasonSpring , editValues .Season ,
552+ "edit form should pre-fill existing season" )
553+
554+ // Change to fall.
555+ editValues .Season = data .SeasonFall
556+ sendKey (m , "ctrl+s" )
557+ sendKey (m , "esc" )
558+
559+ item , err := m .store .GetMaintenance (id )
560+ require .NoError (t , err )
561+ assert .Equal (t , data .SeasonFall , item .Season )
562+ }
563+
564+ // User creates a maintenance item without a season (defaults to none).
565+ func TestUserCreatesMaintenanceWithoutSeason (t * testing.T ) {
566+ t .Parallel ()
567+ m := newTestModelWithStore (t )
568+ m .active = tabIndex (tabMaintenance )
569+ openAddForm (m )
570+
571+ values , ok := m .fs .formData .(* maintenanceFormData )
572+ require .True (t , ok )
573+ values .Name = "General Checkup"
574+ // Season left empty (default).
575+ sendKey (m , "ctrl+s" )
576+ sendKey (m , "esc" )
577+
578+ items , err := m .store .ListMaintenance (false )
579+ require .NoError (t , err )
580+ require .Len (t , items , 1 )
581+ assert .Empty (t , items [0 ].Season )
582+
583+ // Table cell should be null.
584+ m .reloadAll ()
585+ require .NoError (t , m .reloadActiveTab ())
586+ tab := m .activeTab ()
587+ require .NotEmpty (t , tab .CellRows )
588+ seasonCell := tab .CellRows [0 ][int (maintenanceColSeason )]
589+ assert .True (t , seasonCell .Null , "empty season should produce a null cell" )
590+ }
591+
592+ // User inline-edits the Season column on a maintenance item.
593+ func TestUserInlineEditsMaintenanceSeason (t * testing.T ) {
594+ t .Parallel ()
595+ m := newTestModelWithStore (t )
596+ m .active = tabIndex (tabMaintenance )
597+
598+ // Create with spring season.
599+ openAddForm (m )
600+ values , ok := m .fs .formData .(* maintenanceFormData )
601+ require .True (t , ok )
602+ values .Name = "Service AC"
603+ values .Season = data .SeasonSpring
604+ sendKey (m , "ctrl+s" )
605+ sendKey (m , "esc" )
606+
607+ // Reload and position on the maintenance tab.
608+ m .reloadAll ()
609+ require .NoError (t , m .reloadActiveTab ())
610+ tab := m .activeTab ()
611+ require .NotEmpty (t , tab .Rows )
612+ tab .Table .SetCursor (0 )
613+ id := tab .Rows [0 ].ID
614+
615+ // Enter edit mode, position on the Season column, press 'e'.
616+ sendKey (m , "i" )
617+ tab .ColCursor = int (maintenanceColSeason )
618+ sendKey (m , "e" )
619+ require .Equal (t , modeForm , m .mode , "Season inline edit should open form overlay" )
620+
621+ // The form data should reflect the current season.
622+ fd , ok := m .fs .formData .(* maintenanceFormData )
623+ require .True (t , ok )
624+ assert .Equal (t , data .SeasonSpring , fd .Season )
625+
626+ // Change to winter and save.
627+ fd .Season = data .SeasonWinter
628+ sendKey (m , "ctrl+s" )
629+
630+ // Verify DB was updated.
631+ item , err := m .store .GetMaintenance (id )
632+ require .NoError (t , err )
633+ assert .Equal (t , data .SeasonWinter , item .Season )
634+
635+ // Verify table cell updated after reload.
636+ m .reloadAll ()
637+ require .NoError (t , m .reloadActiveTab ())
638+ tab = m .activeTab ()
639+ require .NotEmpty (t , tab .CellRows )
640+ seasonCell := tab .CellRows [0 ][int (maintenanceColSeason )]
641+ assert .Equal (t , data .SeasonWinter , seasonCell .Value )
642+ }
643+
491644// When ScheduleType is "due_date", stale IntervalMonths values are ignored.
492645func TestScheduleTypeDueDateIgnoresStaleInterval (t * testing.T ) {
493646 t .Parallel ()
0 commit comments