142 lines
5.6 KiB
Go
142 lines
5.6 KiB
Go
package complaint
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestComplaintStatus(t *testing.T) {
|
|
now := time.Now()
|
|
cases := []struct {
|
|
name string
|
|
row *Complaint
|
|
want string
|
|
}{
|
|
{name: "nil complaint", row: nil, want: StatusActiveNonMEL},
|
|
{name: "unclassified is pending", row: &Complaint{}, want: StatusPendingMEL},
|
|
{name: "classified non-mel", row: &Complaint{MELSeverity: MELSeverityNonMEL, MELClassifiedAt: &now}, want: StatusActiveNonMEL},
|
|
{name: "classified mel A", row: &Complaint{MELSeverity: MELSeverityA, MELClassifiedAt: &now}, want: StatusActiveMEL},
|
|
{name: "fixed overrides mel", row: &Complaint{MELSeverity: MELSeverityA, MELClassifiedAt: &now, FixedAt: &now}, want: StatusServiced},
|
|
{name: "fixed overrides default", row: &Complaint{FixedAt: &now}, want: StatusServiced},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if got := tc.row.Status(); got != tc.want {
|
|
t.Fatalf("Status() = %q, want %q", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComplaintMELDeadline(t *testing.T) {
|
|
base := time.Date(2026, 6, 17, 8, 0, 0, 0, time.UTC)
|
|
cases := []struct {
|
|
name string
|
|
row *Complaint
|
|
wantNil bool
|
|
wantTime time.Time
|
|
}{
|
|
{name: "non-mel", row: &Complaint{MELSeverity: MELSeverityNonMEL, ReportedAt: base}, wantNil: true},
|
|
// Grace is counted in days: A=1, D=120.
|
|
{name: "mel A", row: &Complaint{MELSeverity: MELSeverityA, ReportedAt: base}, wantTime: base.Add(24 * time.Hour)},
|
|
{name: "mel D", row: &Complaint{MELSeverity: MELSeverityD, ReportedAt: base}, wantTime: base.Add(120 * 24 * time.Hour)},
|
|
{name: "zero reported_at", row: &Complaint{MELSeverity: MELSeverityA}, wantNil: true},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
got := tc.row.MELDeadline()
|
|
if tc.wantNil {
|
|
if got != nil {
|
|
t.Fatalf("MELDeadline() = %v, want nil", got)
|
|
}
|
|
return
|
|
}
|
|
if got == nil || !got.Equal(tc.wantTime) {
|
|
t.Fatalf("MELDeadline() = %v, want %v", got, tc.wantTime)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComplaintIsGrounding(t *testing.T) {
|
|
base := time.Date(2026, 6, 17, 8, 0, 0, 0, time.UTC)
|
|
fixed := base
|
|
classified := base
|
|
cases := []struct {
|
|
name string
|
|
row *Complaint
|
|
now time.Time
|
|
want bool
|
|
}{
|
|
{name: "nsr never grounds", row: &Complaint{MELSeverity: MELSeverityNonMEL, ReportedAt: base, MELClassifiedAt: &classified, IsNSR: true}, now: base, want: false},
|
|
{name: "fixed never grounds", row: &Complaint{MELSeverity: MELSeverityNonMEL, ReportedAt: base, MELClassifiedAt: &classified, FixedAt: &fixed}, now: base, want: false},
|
|
{name: "pending (unclassified) does not ground", row: &Complaint{MELSeverity: MELSeverityNonMEL, ReportedAt: base}, now: base, want: false},
|
|
{name: "action taken alone does not lift grounding (needs EASA release)", row: &Complaint{MELSeverity: MELSeverityNonMEL, ReportedAt: base, MELClassifiedAt: &classified, ActionTaken: ptr("tightened")}, now: base, want: true},
|
|
{name: "action taken with EASA fix lifts grounding", row: &Complaint{MELSeverity: MELSeverityNonMEL, ReportedAt: base, MELClassifiedAt: &classified, ActionTaken: ptr("tightened"), FixedAt: &fixed}, now: base, want: false},
|
|
{name: "non-mel grounds immediately", row: &Complaint{MELSeverity: MELSeverityNonMEL, ReportedAt: base, MELClassifiedAt: &classified}, now: base, want: true},
|
|
{name: "mel within grace not grounding", row: &Complaint{MELSeverity: MELSeverityA, ReportedAt: base, MELClassifiedAt: &classified}, now: base.Add(12 * time.Hour), want: false},
|
|
{name: "mel past grace grounds", row: &Complaint{MELSeverity: MELSeverityA, ReportedAt: base, MELClassifiedAt: &classified}, now: base.Add(2 * 24 * time.Hour), want: true},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if got := tc.row.IsGrounding(tc.now); got != tc.want {
|
|
t.Fatalf("IsGrounding() = %v, want %v", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComplaintIsMELAOG(t *testing.T) {
|
|
base := time.Date(2026, 6, 17, 8, 0, 0, 0, time.UTC)
|
|
cases := []struct {
|
|
name string
|
|
row *Complaint
|
|
now time.Time
|
|
want bool
|
|
}{
|
|
{name: "nsr", row: &Complaint{MELSeverity: MELSeverityA, ReportedAt: base, IsNSR: true}, now: base.Add(time.Hour), want: false},
|
|
{name: "non-mel has no deadline", row: &Complaint{MELSeverity: MELSeverityNonMEL, ReportedAt: base}, now: base.Add(time.Hour), want: false},
|
|
{name: "before deadline", row: &Complaint{MELSeverity: MELSeverityA, ReportedAt: base}, now: base, want: false},
|
|
{name: "at deadline", row: &Complaint{MELSeverity: MELSeverityA, ReportedAt: base}, now: base.Add(24 * time.Hour), want: true},
|
|
{name: "after deadline", row: &Complaint{MELSeverity: MELSeverityA, ReportedAt: base}, now: base.Add(5 * 24 * time.Hour), want: true},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
if got := tc.row.IsMELAOG(tc.now); got != tc.want {
|
|
t.Fatalf("IsMELAOG() = %v, want %v", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func ptr(s string) *string { return &s }
|
|
|
|
func TestComplaintTableNameAndBeforeCreate(t *testing.T) {
|
|
if (Complaint{}).TableName() != "complaints" {
|
|
t.Fatalf("unexpected table name")
|
|
}
|
|
c := &Complaint{}
|
|
if err := c.BeforeCreate(nil); err != nil {
|
|
t.Fatalf("BeforeCreate err: %v", err)
|
|
}
|
|
if len(c.ID) == 0 {
|
|
t.Fatal("BeforeCreate should set ID")
|
|
}
|
|
prev := string(c.ID)
|
|
if err := c.BeforeCreate(nil); err != nil {
|
|
t.Fatalf("BeforeCreate err: %v", err)
|
|
}
|
|
if string(c.ID) != prev {
|
|
t.Fatal("BeforeCreate must not overwrite an existing ID")
|
|
}
|
|
}
|
|
|
|
func TestMELGraceDays(t *testing.T) {
|
|
if MELGraceDays(MELSeverityA) != 1 || MELGraceDays(MELSeverityD) != 120 {
|
|
t.Fatal("unexpected grace days")
|
|
}
|
|
if MELGraceDays(MELSeverityNonMEL) != 0 {
|
|
t.Fatal("non-mel has no grace")
|
|
}
|
|
}
|