e2e changes
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"nearle/models"
|
||||
@@ -47,6 +48,10 @@ type fakeProductRepo struct {
|
||||
publishedRefs []models.ProductLocationRef
|
||||
created []models.Products
|
||||
categorySet map[int][2]int // productid -> {categoryid, subcategoryid}
|
||||
|
||||
// Set to make the insert fail, for the tests that check a failed create
|
||||
// does not hand back a half-made product.
|
||||
createErr error
|
||||
}
|
||||
|
||||
func newFakeRepo() *fakeProductRepo {
|
||||
@@ -119,6 +124,9 @@ func (f *fakeProductRepo) UpdateProductCategory(productid, categoryid, subcatego
|
||||
// re-import branch, so this only became reachable when publishing did.
|
||||
func (f *fakeProductRepo) CreateProductReturningID(product models.Products) (int, error) {
|
||||
f.calls = append(f.calls, "CreateProductReturningID")
|
||||
if f.createErr != nil {
|
||||
return 0, f.createErr
|
||||
}
|
||||
f.created = append(f.created, product)
|
||||
return 9001, nil
|
||||
}
|
||||
@@ -767,3 +775,72 @@ func TestPricingFilterDoesNotDisturbTheCallersSlice(t *testing.T) {
|
||||
t.Error("the caller's slice was modified")
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Creating a product hands back its id ───────────────────────────────────
|
||||
*
|
||||
* `POST /products/create` answered `productid: 0` for every product it created:
|
||||
* the repository took the struct by value, GORM wrote the generated id onto
|
||||
* that copy, and the copy went out of scope. The endpoint is the only way to
|
||||
* create a product, and a product cannot be priced or stocked without its id,
|
||||
* so every caller had to re-read the tenant's whole catalogue and find its own
|
||||
* row again by SKU — a column nothing enforces, in an importer that creates
|
||||
* duplicates by design.
|
||||
*/
|
||||
|
||||
func TestCreateProductReturnsTheIdTheDatabaseAssigned(t *testing.T) {
|
||||
repo := &fakeProductRepo{}
|
||||
svc := NewProductService(repo, &fakeCatalogueService{})
|
||||
|
||||
created, err := svc.CreateProduct(models.Products{
|
||||
Tenantid: 9001,
|
||||
Productname: "Test Rice 5kg",
|
||||
Productsku: "TM-RICE-5K",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("CreateProduct: %v", err)
|
||||
}
|
||||
|
||||
// 9001 is what the fake's CreateProductReturningID returns. The point is
|
||||
// that it reaches the caller at all — it used to be dropped.
|
||||
if created.Productid != 9001 {
|
||||
t.Errorf("productid = %d, want 9001 — the id was lost on the way out", created.Productid)
|
||||
}
|
||||
|
||||
// The rest of the product survives the round trip, because the response is
|
||||
// what the console shows and what it prices and stocks against.
|
||||
if created.Productsku != "TM-RICE-5K" || created.Productname != "Test Rice 5kg" {
|
||||
t.Errorf("the product came back altered: %+v", created)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateProductGoesThroughTheOneCreatePath(t *testing.T) {
|
||||
// There were two repository methods doing this same INSERT, one of which
|
||||
// discarded the id. Only one remains, and this is what pins that: a second
|
||||
// path would have to be added here to be used at all.
|
||||
repo := &fakeProductRepo{}
|
||||
svc := NewProductService(repo, &fakeCatalogueService{})
|
||||
|
||||
if _, err := svc.CreateProduct(models.Products{Tenantid: 9001}); err != nil {
|
||||
t.Fatalf("CreateProduct: %v", err)
|
||||
}
|
||||
|
||||
if len(repo.calls) != 1 || repo.calls[0] != "CreateProductReturningID" {
|
||||
t.Errorf("want exactly one call to CreateProductReturningID, got %v", repo.calls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAFailedCreateReturnsNoProduct(t *testing.T) {
|
||||
// The caller prices and stocks against what comes back, so a half-made
|
||||
// product with a zero id would be worse than an error — it would send a
|
||||
// price and a stock movement to product 0.
|
||||
repo := &fakeProductRepo{createErr: errors.New("duplicate key")}
|
||||
svc := NewProductService(repo, &fakeCatalogueService{})
|
||||
|
||||
created, err := svc.CreateProduct(models.Products{Tenantid: 9001, Productsku: "DUP"})
|
||||
if err == nil {
|
||||
t.Fatal("a failed insert was reported as a success")
|
||||
}
|
||||
if created.Productid != 0 || created.Productsku != "" {
|
||||
t.Errorf("a product was returned for a failed create: %+v", created)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user