package httpserver_test import ( "encoding/json" "net/http" "testing" ) // The exact body the Owliver create-position skill sends, byte for byte as // `runAction('create_position', …)` produces it for the brief's own example. // Generated from the frontend, not retyped: if the two ever drift, this fails. const owliverCreatePositionBody = `{ "title": "Event Staff", "role_category": "Event Staff", "company": "Mac", "headcount": 1, "start_date": null, "duration_months": null, "priority": "normal", "custom_requirements": "", "physical_requirements": "", "leadership_expectations": "", "attendance_expectations": "", "min_experience_years": 3, "english_required": "native", "location": "Bay Area", "pay_range_min": 30, "pay_range_max": 40, "certifications_required": ["Background Check Cleared"], "skill_requirements": [], "vetting_criteria": {"experience":25,"english":20,"reliability":20,"certifications":20,"availability":15}, "status": "active" }` func TestOwliverCreatePositionPayloadIsAccepted(t *testing.T) { a := newAPI(t) var body map[string]any if err := json.Unmarshal([]byte(owliverCreatePositionBody), &body); err != nil { t.Fatalf("the captured payload is not valid JSON: %v", err) } got := a.do("POST", "/api/v1/job-postings", body) if got.code != http.StatusCreated { t.Fatalf("POST /api/v1/job-postings = %d, want 201\nbody: %v", got.code, got.body) } rec, _ := got.body["data"].(map[string]any) if rec == nil { t.Fatalf("no record in the response: %v", got.body) } // Every field the conversation collected must come back as it was sent — // a create that silently drops the pay range or the certification is a // create that looks fine and stores something else. for field, want := range map[string]any{ "title": "Event Staff", "company": "Mac", "location": "Bay Area", "pay_range_min": float64(30), "pay_range_max": float64(40), "min_experience_years": float64(3), "english_required": "native", "status": "active", } { if rec[field] != want { t.Errorf("%s = %#v, want %#v", field, rec[field], want) } } certs, _ := rec["certifications_required"].([]any) if len(certs) != 1 || certs[0] != "Background Check Cleared" { t.Errorf("certifications_required = %#v", rec["certifications_required"]) } id, _ := rec["id"].(string) if id == "" { t.Fatal("the created position has no id") } // And it is in PostgreSQL, not just in the response: read it back through // the list endpoint the Positions page uses. list := a.do("GET", "/api/v1/job-postings?limit=200", nil) if list.code != http.StatusOK { t.Fatalf("GET /api/v1/job-postings = %d", list.code) } rows, _ := list.body["data"].([]any) for _, row := range rows { if r, ok := row.(map[string]any); ok && r["id"] == id { return } } t.Fatalf("the created position is not in GET /api/v1/job-postings (%d rows)", len(rows)) } // The path the brief names does not exist, and never did. The resource is // job-postings; /api/v1/positions is a phantom. func TestThereIsNoPositionsResource(t *testing.T) { a := newAPI(t) for _, m := range []string{"GET", "POST"} { if got := a.do(m, "/api/v1/positions", map[string]any{"title": "x"}); got.code != http.StatusNotFound { t.Errorf("%s /api/v1/positions = %d, want 404", m, got.code) } } }