mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-15 22:29:04 +02:00
fix(issue): inherit parent project for sub-issues
This commit is contained in:
@@ -302,6 +302,73 @@ func TestCreateIssueExplicitBacklogPreserved(t *testing.T) {
|
||||
testHandler.DeleteIssue(httptest.NewRecorder(), cleanupReq)
|
||||
}
|
||||
|
||||
func TestCreateSubIssueInheritsParentProject(t *testing.T) {
|
||||
var projectID, parentID, childID string
|
||||
defer func() {
|
||||
for _, issueID := range []string{childID, parentID} {
|
||||
if issueID == "" {
|
||||
continue
|
||||
}
|
||||
req := newRequest("DELETE", "/api/issues/"+issueID, nil)
|
||||
req = withURLParam(req, "id", issueID)
|
||||
testHandler.DeleteIssue(httptest.NewRecorder(), req)
|
||||
}
|
||||
if projectID != "" {
|
||||
req := newRequest("DELETE", "/api/projects/"+projectID, nil)
|
||||
req = withURLParam(req, "id", projectID)
|
||||
testHandler.DeleteProject(httptest.NewRecorder(), req)
|
||||
}
|
||||
}()
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req := newRequest("POST", "/api/projects?workspace_id="+testWorkspaceID, map[string]any{
|
||||
"title": "Sub-issue inheritance project",
|
||||
})
|
||||
testHandler.CreateProject(w, req)
|
||||
if w.Code != http.StatusCreated {
|
||||
t.Fatalf("CreateProject: expected 201, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
var project ProjectResponse
|
||||
json.NewDecoder(w.Body).Decode(&project)
|
||||
projectID = project.ID
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req = newRequest("POST", "/api/issues?workspace_id="+testWorkspaceID, map[string]any{
|
||||
"title": "Parent with project",
|
||||
"project_id": projectID,
|
||||
})
|
||||
testHandler.CreateIssue(w, req)
|
||||
if w.Code != http.StatusCreated {
|
||||
t.Fatalf("CreateIssue parent: expected 201, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
var parent IssueResponse
|
||||
json.NewDecoder(w.Body).Decode(&parent)
|
||||
parentID = parent.ID
|
||||
if parent.ProjectID == nil || *parent.ProjectID != projectID {
|
||||
t.Fatalf("CreateIssue parent: expected project_id %q, got %v", projectID, parent.ProjectID)
|
||||
}
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req = newRequest("POST", "/api/issues?workspace_id="+testWorkspaceID, map[string]any{
|
||||
"title": "Child without explicit project",
|
||||
"parent_issue_id": parentID,
|
||||
})
|
||||
testHandler.CreateIssue(w, req)
|
||||
if w.Code != http.StatusCreated {
|
||||
t.Fatalf("CreateIssue child: expected 201, got %d: %s", w.Code, w.Body.String())
|
||||
}
|
||||
var child IssueResponse
|
||||
json.NewDecoder(w.Body).Decode(&child)
|
||||
childID = child.ID
|
||||
|
||||
if child.ParentIssueID == nil || *child.ParentIssueID != parentID {
|
||||
t.Fatalf("CreateIssue child: expected parent_issue_id %q, got %v", parentID, child.ParentIssueID)
|
||||
}
|
||||
if child.ProjectID == nil || *child.ProjectID != projectID {
|
||||
t.Fatalf("CreateIssue child: expected inherited project_id %q, got %v", projectID, child.ProjectID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommentCRUD(t *testing.T) {
|
||||
// Create an issue first
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
@@ -815,6 +815,10 @@ func (h *Handler) CreateIssue(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
var parentIssueID pgtype.UUID
|
||||
var projectID pgtype.UUID
|
||||
if req.ProjectID != nil {
|
||||
projectID = parseUUID(*req.ProjectID)
|
||||
}
|
||||
if req.ParentIssueID != nil {
|
||||
parentIssueID = parseUUID(*req.ParentIssueID)
|
||||
// Validate parent exists in the same workspace.
|
||||
@@ -826,6 +830,9 @@ func (h *Handler) CreateIssue(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, http.StatusBadRequest, "parent issue not found in this workspace")
|
||||
return
|
||||
}
|
||||
if req.ProjectID == nil {
|
||||
projectID = parent.ProjectID
|
||||
}
|
||||
}
|
||||
|
||||
var dueDate pgtype.Timestamptz
|
||||
@@ -872,7 +879,7 @@ func (h *Handler) CreateIssue(w http.ResponseWriter, r *http.Request) {
|
||||
Position: 0,
|
||||
DueDate: dueDate,
|
||||
Number: issueNumber,
|
||||
ProjectID: func() pgtype.UUID { if req.ProjectID != nil { return parseUUID(*req.ProjectID) }; return pgtype.UUID{} }(),
|
||||
ProjectID: projectID,
|
||||
})
|
||||
if err != nil {
|
||||
slog.Warn("create issue failed", append(logger.RequestAttrs(r), "error", err, "workspace_id", workspaceID)...)
|
||||
|
||||
Reference in New Issue
Block a user