package inventory import ( "strings" "testing" "time" ) // **A plan's id is a value, never SQL** (novox/hq issue 561): the id reaches PlanByID from a caller of the // controller's plans verb, so an id holding a quote is read as a plain id — no error from the store, and no // other plan answered for it. func TestAPlanIdHoldingAQuoteIsReadAsAPlainId(t *testing.T) { inv := ForTest(t) ctx := t.Context() p := Plan{ID: "plan-561", Repository: "novox/mesh-controller", Commit: "abc", Created: time.Now().UTC(), State: PlanBuilding, Tiers: [][]string{{"a"}}, Modules: map[string]*PlanModule{"a": {}}} if err := inv.SavePlan(ctx, &p); err != nil { t.Fatal(err) } for _, id := range []string{ "x' or '1'='1", // every plan, when pasted into the query "plan-561' or id like '%", // the plan above, by a pattern "it's", // a quote alone: a syntax error, when pasted } { got, err := inv.PlanByID(ctx, id) if err == nil { t.Fatalf("PlanByID(%q) answered %s, a plan of another id", id, got.ID) } if want := "no plan " + id; err.Error() != want { t.Fatalf("PlanByID(%q) failed with %q, not as a plain id no plan has (%q)", id, err, want) } } // A plan whose id holds a quote is found by it, and by nothing else. quoted := p quoted.ID, quoted.Revision = "plan-'561'", 0 if err := inv.SavePlan(ctx, "ed); err != nil { t.Fatal(err) } if got, err := inv.PlanByID(ctx, quoted.ID); err != nil || got.ID != quoted.ID { t.Fatalf("the plan with a quote in its id was not read back: %v %+v", err, got.ID) } if recent, err := inv.RecentPlans(ctx, 1); err != nil || len(recent) != 1 || !strings.HasPrefix(recent[0].ID, "plan-") { t.Fatalf("RecentPlans with a parameter: %v %+v", err, recent) } }