127 lines
4.4 KiB
Go
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)
|
|
}
|
|
}
|