Files
backend_fiesta/repositories/riderShift_test.go
2026-09-24 15:51:47 +05:30

127 lines
4.4 KiB
Go

package repositories
import (
"strings"
"testing"
"nearle/models"
)
/*
Shift windows, which riders cannot be hired without.
`CreateRider` refuses a rider with no shift — correctly, because `getriders`
joins `ridershifts` and a rider on a shift that does not exist is a rider nobody
can see. But the table could only be READ: no endpoint, no service method, and
no `applocationid` field on the model to write one with. A region that shipped
without shift rows was a region no rider could ever be added to, and the console
said "No shifts set up for this region" with nothing anybody could do about it.
These cover the rules that do not need a database. The two that do — the region
must be configured, and the window must not already exist — are enforced in
CreateRiderShift against real tables.
*/
func TestATimeIsNormalisedSoOneWindowHasOneLabel(t *testing.T) {
// The dropdown labels a shift by concatenating its two columns raw, so
// `9:00-17:00` and `09:00-17:00` are two different labels for one window.
// Rows inserted by hand over the years use every spelling.
for _, tc := range []struct{ in, want string }{
{"9:00", "09:00"},
{"09:00", "09:00"},
{"09:00:00", "09:00"},
{" 9:5 ", "09:05"},
{"23:59", "23:59"},
{"0:00", "00:00"},
} {
got, err := riderShiftClock(tc.in)
if err != nil {
t.Fatalf("%q: %v", tc.in, err)
}
if got != tc.want {
t.Fatalf("%q became %q, want %q", tc.in, got, tc.want)
}
}
}
func TestSomethingThatIsNotATimeIsRefused(t *testing.T) {
for _, bad := range []string{"", " ", "morning", "25:00", "09:60", "9", "9:00:00:00", "-1:00"} {
if _, err := riderShiftClock(bad); err == nil {
t.Fatalf("%q was accepted as a time", bad)
}
}
}
func TestHoursAreWorkedOutRatherThanAskedFor(t *testing.T) {
// `shifthours` feeds rider pay. It is the one field a person gets wrong and
// nothing downstream checks, so it is computed and the request's own number
// is discarded.
shift, err := validateRiderShift(models.Ridershifts{
Applocationid: 2, Starttime: "09:00", Endtime: "17:00",
Shifthours: 4, // wrong, and sent anyway
})
if err != nil {
t.Fatalf("a good shift was refused: %v", err)
}
if shift.Shifthours != 8 {
t.Fatalf("09:00-17:00 came out as %v hours, want 8", shift.Shifthours)
}
}
func TestANightShiftCrossesMidnightRatherThanGoingNegative(t *testing.T) {
// 22:00-06:00 is eight hours. Subtracting the clocks gives minus sixteen,
// which would pay a night rider for a negative shift.
if got := riderShiftHours("22:00", "06:00"); got != 8 {
t.Fatalf("22:00-06:00 came out as %v hours, want 8", got)
}
if got := riderShiftHours("09:30", "17:00"); got != 7.5 {
t.Fatalf("09:30-17:00 came out as %v hours, want 7.5", got)
}
}
func TestAShiftNeedsARegion(t *testing.T) {
// Region 0 arrives from a form field nobody filled in. A shift there would
// be offered to nobody and joined to nothing.
_, err := validateRiderShift(models.Ridershifts{Starttime: "09:00", Endtime: "17:00"})
if err == nil || !strings.Contains(err.Error(), "region") {
t.Fatalf("a shift with no region was accepted: %v", err)
}
}
func TestAShiftCannotStartAndEndAtTheSameTime(t *testing.T) {
// Would compute as a 24-hour window under the midnight rule, which is not
// what anybody who typed the same time twice meant.
_, err := validateRiderShift(models.Ridershifts{
Applocationid: 2, Starttime: "09:00", Endtime: "9:00",
})
if err == nil {
t.Fatal("a zero-length window was accepted")
}
}
func TestPayCannotBeNegative(t *testing.T) {
for _, shift := range []models.Ridershifts{
{Applocationid: 2, Starttime: "09:00", Endtime: "17:00", Basefare: -1},
{Applocationid: 2, Starttime: "09:00", Endtime: "17:00", Additionalcharges: -5},
{Applocationid: 2, Starttime: "09:00", Endtime: "17:00", Fuelcharge: -0.5},
} {
if _, err := validateRiderShift(shift); err == nil {
t.Fatalf("negative pay was accepted: %+v", shift)
}
}
}
func TestTheNormalisedTimesComeBackOnTheShift(t *testing.T) {
// The caller inserts what validation returned, not what it was handed —
// otherwise the normalising is computed and then thrown away.
shift, err := validateRiderShift(models.Ridershifts{
Applocationid: 2, Starttime: "9:0", Endtime: "17:00:00",
})
if err != nil {
t.Fatalf("refused: %v", err)
}
if shift.Starttime != "09:00" || shift.Endtime != "17:00" {
t.Fatalf("times were not normalised on the way out: %q-%q", shift.Starttime, shift.Endtime)
}
}