diff --git a/handlers/ticket.go b/handlers/ticket.go index 4cf3d167b..781490df6 100644 --- a/handlers/ticket.go +++ b/handlers/ticket.go @@ -36,6 +36,14 @@ func NewTicketHandler(httpClient HttpClient, database db.Database) *ticketHandle } } +type UpdateTicketRequest struct { + Metadata struct { + Source string `json:"source"` + ID string `json:"id"` + } `json:"metadata"` + Ticket *db.Tickets `json:"ticket"` +} + func (th *ticketHandler) GetTicket(w http.ResponseWriter, r *http.Request) { uuid := chi.URLParam(r, "uuid") if uuid == "" { @@ -93,22 +101,34 @@ func (th *ticketHandler) UpdateTicket(w http.ResponseWriter, r *http.Request) { } defer r.Body.Close() - var ticket db.Tickets - if err := json.Unmarshal(body, &ticket); err != nil { + var updateRequest UpdateTicketRequest + if err := json.Unmarshal(body, &updateRequest); err != nil { + + var ticket db.Tickets + if err := json.Unmarshal(body, &ticket); err != nil { + w.WriteHeader(http.StatusBadRequest) + json.NewEncoder(w).Encode(map[string]string{"error": "Error parsing request body"}) + return + } + + updateRequest.Ticket = &ticket + } + + if updateRequest.Ticket == nil { w.WriteHeader(http.StatusBadRequest) - json.NewEncoder(w).Encode(map[string]string{"error": "Error parsing request body"}) + json.NewEncoder(w).Encode(map[string]string{"error": "Ticket data is required"}) return } - ticket.UUID = ticketUUID + updateRequest.Ticket.UUID = ticketUUID - if ticket.Status != "" && !db.IsValidTicketStatus(ticket.Status) { + if updateRequest.Ticket.Status != "" && !db.IsValidTicketStatus(updateRequest.Ticket.Status) { w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{"error": "Invalid ticket status"}) return } - updatedTicket, err := th.db.CreateOrEditTicket(&ticket) + updatedTicket, err := th.db.CreateOrEditTicket(updateRequest.Ticket) if err != nil { if err.Error() == "feature_uuid, phase_uuid, and name are required" { w.WriteHeader(http.StatusBadRequest) @@ -181,8 +201,8 @@ func (th *ticketHandler) PostTicketDataToStakwork(w http.ResponseWriter, r *http } defer r.Body.Close() - var ticket db.Tickets - if err := json.Unmarshal(body, &ticket); err != nil { + var ticketRequest UpdateTicketRequest + if err := json.Unmarshal(body, &ticketRequest); err != nil { w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(TicketResponse{ Success: false, @@ -192,13 +212,22 @@ func (th *ticketHandler) PostTicketDataToStakwork(w http.ResponseWriter, r *http return } + if ticketRequest.Ticket == nil { + w.WriteHeader(http.StatusBadRequest) + json.NewEncoder(w).Encode(TicketResponse{ + Success: false, + Message: "Validation failed", + Errors: []string{"Ticket data is required"}, + }) + return + } + + ticket := ticketRequest.Ticket var validationErrors []string if ticket.UUID == uuid.Nil { validationErrors = append(validationErrors, "UUID is required") - } else { - if _, err := uuid.Parse(ticket.UUID.String()); err != nil { - validationErrors = append(validationErrors, "Invalid UUID format") - } + } else if _, err := uuid.Parse(ticket.UUID.String()); err != nil { + validationErrors = append(validationErrors, "Invalid UUID format") } if len(validationErrors) > 0 { @@ -275,6 +304,7 @@ func (th *ticketHandler) PostTicketDataToStakwork(w http.ResponseWriter, r *http "productBrief": productBrief, "featureBrief": featureBrief, "examples": "", + "sourceWebsocket": ticketRequest.Metadata.ID, "webhook_url": webhookURL, }, }, diff --git a/handlers/ticket_test.go b/handlers/ticket_test.go index 890a405c0..aa46a554d 100644 --- a/handlers/ticket_test.go +++ b/handlers/ticket_test.go @@ -251,14 +251,24 @@ func TestUpdateTicket(t *testing.T) { rr := httptest.NewRecorder() handler := http.HandlerFunc(tHandler.UpdateTicket) - // Create a ticket with only UUID and some optional fields updateTicket := db.Tickets{ UUID: createdTicket.UUID, Description: "Updated description", // Optional field Status: db.ReadyTicket, // Optional field } - requestBody, _ := json.Marshal(updateTicket) + updateRequest := UpdateTicketRequest{ + Metadata: struct { + Source string `json:"source"` + ID string `json:"id"` + }{ + Source: "test-source", + ID: "test-id", + }, + Ticket: &updateTicket, + } + + requestBody, _ := json.Marshal(updateRequest) rctx := chi.NewRouteContext() rctx.URLParams.Add("uuid", updateTicket.UUID.String()) req, err := http.NewRequest(http.MethodPost, "/tickets/"+updateTicket.UUID.String(), bytes.NewReader(requestBody)) @@ -294,11 +304,22 @@ func TestUpdateTicket(t *testing.T) { updatedTicket.Description = "Updated Description" updatedTicket.Status = db.CompletedTicket - requestBody, _ := json.Marshal(updatedTicket) + updateRequest := UpdateTicketRequest{ + Metadata: struct { + Source string `json:"source"` + ID string `json:"id"` + }{ + Source: "test-source", + ID: "test-id", + }, + Ticket: &updatedTicket, + } + + requestBody, _ := json.Marshal(updateRequest) rctx := chi.NewRouteContext() rctx.URLParams.Add("uuid", createdTicket.UUID.String()) - req, err := http.NewRequest(http.MethodPut, "/tickets/"+createdTicket.UUID.String(), bytes.NewReader(requestBody)) + req, err := http.NewRequest(http.MethodPost, "/tickets/"+createdTicket.UUID.String(), bytes.NewReader(requestBody)) if err != nil { t.Fatal(err) } @@ -319,6 +340,7 @@ func TestUpdateTicket(t *testing.T) { assert.Equal(t, updatedTicket.FeatureUUID, returnedTicket.FeatureUUID) assert.Equal(t, updatedTicket.PhaseUUID, returnedTicket.PhaseUUID) }) + } func TestDeleteTicket(t *testing.T) {