aravind changes
This commit is contained in:
@@ -1,12 +1,20 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/krow/krow-backend/go-api/internal/authctx"
|
||||
"github.com/krow/krow-backend/go-api/internal/domain"
|
||||
)
|
||||
|
||||
// The two callers validation distinguishes. Only the role is read.
|
||||
var (
|
||||
asOperator = authctx.Identity{Role: string(domain.RoleAdmin)}
|
||||
asTalent = authctx.Identity{Role: string(domain.RoleTalent)}
|
||||
)
|
||||
|
||||
// These exercise query parsing and validation without a database, so the
|
||||
// contract's defaults are pinned even when PostgreSQL is not available.
|
||||
|
||||
@@ -139,24 +147,24 @@ func TestReservedParametersAreNotFilters(t *testing.T) {
|
||||
func TestValidateRequiredAndUnknownAndEnum(t *testing.T) {
|
||||
svc := New(resource(t, "job-postings"), nil)
|
||||
|
||||
if _, err := svc.validate(domain.Record{}, true); err == nil {
|
||||
if _, err := svc.validate(asOperator, domain.Record{}, true); err == nil {
|
||||
t.Error("a create with no title was accepted")
|
||||
}
|
||||
if _, err := svc.validate(domain.Record{"title": " "}, true); err == nil {
|
||||
if _, err := svc.validate(asOperator, domain.Record{"title": " "}, true); err == nil {
|
||||
t.Error("a blank title was accepted")
|
||||
}
|
||||
if _, err := svc.validate(domain.Record{"title": "X", "bogus": 1}, true); err == nil {
|
||||
if _, err := svc.validate(asOperator, domain.Record{"title": "X", "bogus": 1}, true); err == nil {
|
||||
t.Error("an unknown field was accepted")
|
||||
}
|
||||
if _, err := svc.validate(domain.Record{"title": "X", "status": "archived"}, true); err == nil {
|
||||
if _, err := svc.validate(asOperator, domain.Record{"title": "X", "status": "archived"}, true); err == nil {
|
||||
t.Error("an invalid enum value was accepted")
|
||||
}
|
||||
if _, err := svc.validate(domain.Record{"title": "X", "status": "active"}, true); err != nil {
|
||||
if _, err := svc.validate(asOperator, domain.Record{"title": "X", "status": "active"}, true); err != nil {
|
||||
t.Errorf("a valid payload was rejected: %v", err)
|
||||
}
|
||||
|
||||
// Server-owned fields are stripped, not rejected.
|
||||
out, err := svc.validate(domain.Record{"title": "X", "id": "abc", "org_id": "def"}, true)
|
||||
out, err := svc.validate(asOperator, domain.Record{"title": "X", "id": "abc", "org_id": "def"}, true)
|
||||
if err != nil {
|
||||
t.Fatalf("server-owned fields caused a rejection: %v", err)
|
||||
}
|
||||
@@ -168,11 +176,62 @@ func TestValidateRequiredAndUnknownAndEnum(t *testing.T) {
|
||||
}
|
||||
|
||||
// An update needs no required fields — it is a partial by definition.
|
||||
if _, err := svc.validate(domain.Record{"location": "Here"}, false); err != nil {
|
||||
if _, err := svc.validate(asOperator, domain.Record{"location": "Here"}, false); err != nil {
|
||||
t.Errorf("a partial update was rejected: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// A talent-only derivation is only server-supplied for a talent caller.
|
||||
//
|
||||
// The column records who the row is ABOUT, and the repository fills it from the
|
||||
// session for talent and for nobody else (repo.derivedValues). Validation has
|
||||
// to agree: an operator filing an application for somebody else must be told
|
||||
// `email` is required, rather than being let through to a not-null violation
|
||||
// from SQL — and a talent caller must not be asked for the value the server is
|
||||
// about to override anyway.
|
||||
func TestValidateHonoursTalentOnlyDerivation(t *testing.T) {
|
||||
apps := New(resource(t, "job-applications"), nil)
|
||||
body := domain.Record{
|
||||
"job_posting_id": "00000000-0000-0000-0000-000000000000",
|
||||
"applicant_name": "Someone",
|
||||
}
|
||||
|
||||
if _, err := apps.validate(asTalent, body, true); err != nil {
|
||||
t.Errorf("a talent create without email was rejected: %v", err)
|
||||
}
|
||||
|
||||
_, err := apps.validate(asOperator, body, true)
|
||||
if err == nil {
|
||||
t.Fatal("an operator create without email was accepted")
|
||||
}
|
||||
var apiErr *domain.Error
|
||||
if !errors.As(err, &apiErr) {
|
||||
t.Fatalf("error is not an API error: %v", err)
|
||||
}
|
||||
if apiErr.Details["email"] != "required" {
|
||||
t.Errorf("details = %v, want email: required", apiErr.Details)
|
||||
}
|
||||
|
||||
// evidence.worker_email is the same shape, and the case the original
|
||||
// comment in serverSupplies was written for.
|
||||
ev := New(resource(t, "evidence"), nil)
|
||||
if _, err := ev.validate(asTalent, domain.Record{"type": "photo_identify"}, true); err != nil {
|
||||
t.Errorf("a talent evidence create without worker_email was rejected: %v", err)
|
||||
}
|
||||
if _, err := ev.validate(asOperator, domain.Record{"type": "photo_identify"}, true); err == nil {
|
||||
t.Error("an operator evidence create without worker_email was accepted")
|
||||
}
|
||||
|
||||
// A derivation that is NOT talent-only stays server-supplied for everyone:
|
||||
// user_activity records who acted, whoever that is.
|
||||
act := New(resource(t, "user-activity"), nil)
|
||||
for name, ident := range map[string]authctx.Identity{"operator": asOperator, "talent": asTalent} {
|
||||
if _, err := act.validate(ident, domain.Record{"event_type": "x"}, true); err != nil {
|
||||
t.Errorf("%s: an activity create was rejected: %v", name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsUUID(t *testing.T) {
|
||||
valid := []string{
|
||||
"00000000-0000-0000-0000-000000000000",
|
||||
|
||||
Reference in New Issue
Block a user