103 lines
2.8 KiB
Go
103 lines
2.8 KiB
Go
package controllers
|
|
|
|
import (
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
/*
|
|
Batch decisions on stock requests.
|
|
|
|
Approving is not a status write — the service adds the requested quantity to the
|
|
branch's stock — so a batch has to behave like a list of separate actions that
|
|
each really happened, not like one all-or-nothing write. These tests pin the
|
|
parts that would quietly move stock twice or lose a row.
|
|
*/
|
|
|
|
func parseVia(t *testing.T, body string) ([]int, error) {
|
|
t.Helper()
|
|
app := fiber.New()
|
|
var got []int
|
|
var perr error
|
|
app.Post("/", func(c *fiber.Ctx) error {
|
|
reqs, err := parseStockRequests(c)
|
|
perr = err
|
|
for _, r := range reqs {
|
|
got = append(got, r.Productid)
|
|
}
|
|
return nil
|
|
})
|
|
req := httptest.NewRequest("POST", "/", strings.NewReader(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
if _, err := app.Test(req); err != nil {
|
|
t.Fatalf("Test: %v", err)
|
|
}
|
|
return got, perr
|
|
}
|
|
|
|
func TestOneRequestStillWorksUnwrapped(t *testing.T) {
|
|
// The existing caller sends an object, and must keep working untouched.
|
|
got, err := parseVia(t, `{"productid":42,"qty":5}`)
|
|
if err != nil {
|
|
t.Fatalf("single: %v", err)
|
|
}
|
|
if len(got) != 1 || got[0] != 42 {
|
|
t.Errorf("got %v, want [42]", got)
|
|
}
|
|
}
|
|
|
|
func TestAListOfRequestsIsRead(t *testing.T) {
|
|
got, err := parseVia(t, `[{"productid":1,"qty":2},{"productid":2,"qty":3}]`)
|
|
if err != nil {
|
|
t.Fatalf("list: %v", err)
|
|
}
|
|
if len(got) != 2 {
|
|
t.Errorf("got %v, want two requests", got)
|
|
}
|
|
}
|
|
|
|
func TestLeadingWhitespaceDoesNotHideAList(t *testing.T) {
|
|
// A client that pretty-prints its body still sends a list.
|
|
got, err := parseVia(t, " \n\t[{\"productid\":7,\"qty\":1}]")
|
|
if err != nil {
|
|
t.Fatalf("padded list: %v", err)
|
|
}
|
|
if len(got) != 1 || got[0] != 7 {
|
|
t.Errorf("got %v, want [7]", got)
|
|
}
|
|
}
|
|
|
|
func TestTheSameRequestCannotBeApprovedTwiceInOneBatch(t *testing.T) {
|
|
// Approving adds stock. The same id twice would receive one delivery twice.
|
|
got := dedupeIDs([]int{5, 5, 6, 5})
|
|
if len(got) != 2 || got[0] != 5 || got[1] != 6 {
|
|
t.Errorf("got %v, want [5 6]", got)
|
|
}
|
|
}
|
|
|
|
func TestNonPositiveIdsAreDropped(t *testing.T) {
|
|
// 0 is what an unparsed or missing field becomes; it is not a request.
|
|
if got := dedupeIDs([]int{0, -3, 9}); len(got) != 1 || got[0] != 9 {
|
|
t.Errorf("got %v, want [9]", got)
|
|
}
|
|
}
|
|
|
|
func TestOrderIsPreservedSoTheReportMatchesTheScreen(t *testing.T) {
|
|
got := dedupeIDs([]int{3, 1, 2})
|
|
if got[0] != 3 || got[1] != 1 || got[2] != 2 {
|
|
t.Errorf("got %v, want the order sent", got)
|
|
}
|
|
}
|
|
|
|
func TestThePartialOutcomeIsStatedNotHidden(t *testing.T) {
|
|
if msg := stockBatchMessage(8, 2, "approved"); msg != "8 approved, 2 could not be" {
|
|
t.Errorf("got %q", msg)
|
|
}
|
|
if msg := stockBatchMessage(5, 0, "approved"); msg != "5 approved" {
|
|
t.Errorf("got %q", msg)
|
|
}
|
|
}
|