gitea/tests/integration/api_repo_project_test.go

596 lines
21 KiB
Go

// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"fmt"
"net/http"
"testing"
auth_model "code.gitea.io/gitea/models/auth"
issues_model "code.gitea.io/gitea/models/issues"
project_model "code.gitea.io/gitea/models/project"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
)
func TestAPIListProjects(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeReadIssue)
// Test listing all projects
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects", owner.Name, repo.Name).
AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var projects []*api.Project
DecodeJSON(t, resp, &projects)
// Test state filter - open
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects?state=open", owner.Name, repo.Name).
AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &projects)
for _, project := range projects {
assert.False(t, project.IsClosed, "Project should be open")
}
// Test state filter - all
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects?state=all", owner.Name, repo.Name).
AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &projects)
// Test pagination
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects?page=1&limit=5", owner.Name, repo.Name).
AddTokenAuth(token)
MakeRequest(t, req, http.StatusOK)
}
func TestAPIGetProject(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// Create a test project
project := &project_model.Project{
Title: "Test Project for API",
RepoID: repo.ID,
Type: project_model.TypeRepository,
CreatorID: owner.ID,
TemplateType: project_model.TemplateTypeNone,
}
err := project_model.NewProject(t.Context(), project)
assert.NoError(t, err)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), project.ID)
}()
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeReadIssue)
// Test getting the project
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID).
AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var apiProject api.Project
DecodeJSON(t, resp, &apiProject)
assert.Equal(t, project.Title, apiProject.Title)
assert.Equal(t, project.ID, apiProject.ID)
assert.Equal(t, repo.ID, apiProject.RepoID)
assert.NotEmpty(t, apiProject.URL)
// Test getting non-existent project
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects/99999", owner.Name, repo.Name).
AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}
func TestAPICreateProject(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
// Test creating a project
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects", owner.Name, repo.Name), &api.CreateProjectOption{
Title: "API Created Project",
Description: "This is a test project created via API",
TemplateType: 1, // basic_kanban
CardType: 1, // images_and_text
}).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusCreated)
var project api.Project
DecodeJSON(t, resp, &project)
assert.Equal(t, "API Created Project", project.Title)
assert.Equal(t, "This is a test project created via API", project.Description)
assert.Equal(t, 1, project.TemplateType)
assert.Equal(t, 1, project.CardType)
assert.False(t, project.IsClosed)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), project.ID)
}()
// Test creating with minimal data
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects", owner.Name, repo.Name), &api.CreateProjectOption{
Title: "Minimal Project",
}).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusCreated)
var minimalProject api.Project
DecodeJSON(t, resp, &minimalProject)
assert.Equal(t, "Minimal Project", minimalProject.Title)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), minimalProject.ID)
}()
// Test creating without authentication
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects", owner.Name, repo.Name), &api.CreateProjectOption{
Title: "Unauthorized Project",
})
MakeRequest(t, req, http.StatusUnauthorized)
// Test creating with invalid data (empty title)
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects", owner.Name, repo.Name), &api.CreateProjectOption{
Title: "",
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusUnprocessableEntity)
}
func TestAPIUpdateProject(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// Create a test project
project := &project_model.Project{
Title: "Project to Update",
Description: "Original description",
RepoID: repo.ID,
Type: project_model.TypeRepository,
CreatorID: owner.ID,
TemplateType: project_model.TemplateTypeNone,
}
err := project_model.NewProject(t.Context(), project)
assert.NoError(t, err)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), project.ID)
}()
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
// Test updating project title and description
newTitle := "Updated Project Title"
newDesc := "Updated description"
req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID), &api.EditProjectOption{
Title: &newTitle,
Description: &newDesc,
}).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var updatedProject api.Project
DecodeJSON(t, resp, &updatedProject)
assert.Equal(t, newTitle, updatedProject.Title)
assert.Equal(t, newDesc, updatedProject.Description)
// Test closing project
isClosed := true
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID), &api.EditProjectOption{
IsClosed: &isClosed,
}).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &updatedProject)
assert.True(t, updatedProject.IsClosed)
assert.NotNil(t, updatedProject.ClosedDate)
// Test reopening project
isClosed = false
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID), &api.EditProjectOption{
IsClosed: &isClosed,
}).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &updatedProject)
assert.False(t, updatedProject.IsClosed)
// Test updating non-existent project
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/projects/99999", owner.Name, repo.Name), &api.EditProjectOption{
Title: &newTitle,
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}
func TestAPIDeleteProject(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// Create a test project
project := &project_model.Project{
Title: "Project to Delete",
RepoID: repo.ID,
Type: project_model.TypeRepository,
CreatorID: owner.ID,
TemplateType: project_model.TemplateTypeNone,
}
err := project_model.NewProject(t.Context(), project)
assert.NoError(t, err)
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
// Test deleting the project
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID).
AddTokenAuth(token)
MakeRequest(t, req, http.StatusNoContent)
// Test deleting non-existent project (including the one we just deleted)
req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID).
AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}
func TestAPIListProjectColumns(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// Create a test project
project := &project_model.Project{
Title: "Project for Columns Test",
RepoID: repo.ID,
Type: project_model.TypeRepository,
CreatorID: owner.ID,
TemplateType: project_model.TemplateTypeNone,
}
err := project_model.NewProject(t.Context(), project)
assert.NoError(t, err)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), project.ID)
}()
// Create test columns
for i := 1; i <= 3; i++ {
column := &project_model.Column{
Title: fmt.Sprintf("Column %d", i),
ProjectID: project.ID,
CreatorID: owner.ID,
}
err = project_model.NewColumn(t.Context(), column)
assert.NoError(t, err)
}
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeReadIssue)
// Test listing columns
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects/%d/columns", owner.Name, repo.Name, project.ID).
AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var columns []*api.ProjectColumn
DecodeJSON(t, resp, &columns)
assert.Len(t, columns, 3)
assert.Equal(t, "Column 1", columns[0].Title)
assert.Equal(t, "Column 2", columns[1].Title)
assert.Equal(t, "Column 3", columns[2].Title)
// Test pagination
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects/%d/columns?page=1&limit=2", owner.Name, repo.Name, project.ID).
AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &columns)
assert.Len(t, columns, 2)
// Test listing columns for non-existent project
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects/99999/columns", owner.Name, repo.Name).
AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}
func TestAPICreateProjectColumn(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// Create a test project
project := &project_model.Project{
Title: "Project for Column Creation",
RepoID: repo.ID,
Type: project_model.TypeRepository,
CreatorID: owner.ID,
TemplateType: project_model.TemplateTypeNone,
}
err := project_model.NewProject(t.Context(), project)
assert.NoError(t, err)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), project.ID)
}()
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
// Test creating a column with color
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects/%d/columns", owner.Name, repo.Name, project.ID), &api.CreateProjectColumnOption{
Title: "New Column",
Color: "#FF5733",
}).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusCreated)
var column api.ProjectColumn
DecodeJSON(t, resp, &column)
assert.Equal(t, "New Column", column.Title)
assert.Equal(t, "#FF5733", column.Color)
assert.Equal(t, project.ID, column.ProjectID)
// Test creating a column without color
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects/%d/columns", owner.Name, repo.Name, project.ID), &api.CreateProjectColumnOption{
Title: "Simple Column",
}).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusCreated)
DecodeJSON(t, resp, &column)
assert.Equal(t, "Simple Column", column.Title)
// Test creating with empty title
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects/%d/columns", owner.Name, repo.Name, project.ID), &api.CreateProjectColumnOption{
Title: "",
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusUnprocessableEntity)
// Test creating for non-existent project
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects/99999/columns", owner.Name, repo.Name), &api.CreateProjectColumnOption{
Title: "Orphan Column",
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}
func TestAPIUpdateProjectColumn(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// Create a test project and column
project := &project_model.Project{
Title: "Project for Column Update",
RepoID: repo.ID,
Type: project_model.TypeRepository,
CreatorID: owner.ID,
TemplateType: project_model.TemplateTypeNone,
}
err := project_model.NewProject(t.Context(), project)
assert.NoError(t, err)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), project.ID)
}()
column := &project_model.Column{
Title: "Original Column",
ProjectID: project.ID,
CreatorID: owner.ID,
Color: "#000000",
}
err = project_model.NewColumn(t.Context(), column)
assert.NoError(t, err)
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
// Test updating column title
newTitle := "Updated Column"
req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/projects/columns/%d", owner.Name, repo.Name, column.ID), &api.EditProjectColumnOption{
Title: &newTitle,
}).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var updatedColumn api.ProjectColumn
DecodeJSON(t, resp, &updatedColumn)
assert.Equal(t, newTitle, updatedColumn.Title)
// Test updating column color
newColor := "#FF0000"
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/projects/columns/%d", owner.Name, repo.Name, column.ID), &api.EditProjectColumnOption{
Color: &newColor,
}).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &updatedColumn)
assert.Equal(t, newColor, updatedColumn.Color)
// Test updating non-existent column
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/projects/columns/99999", owner.Name, repo.Name), &api.EditProjectColumnOption{
Title: &newTitle,
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}
func TestAPIDeleteProjectColumn(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// Create a test project and column
project := &project_model.Project{
Title: "Project for Column Deletion",
RepoID: repo.ID,
Type: project_model.TypeRepository,
CreatorID: owner.ID,
TemplateType: project_model.TemplateTypeNone,
}
err := project_model.NewProject(t.Context(), project)
assert.NoError(t, err)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), project.ID)
}()
column := &project_model.Column{
Title: "Column to Delete",
ProjectID: project.ID,
CreatorID: owner.ID,
}
err = project_model.NewColumn(t.Context(), column)
assert.NoError(t, err)
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
// Test deleting the column
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/projects/columns/%d", owner.Name, repo.Name, column.ID).
AddTokenAuth(token)
MakeRequest(t, req, http.StatusNoContent)
// Test deleting non-existent column (including the one we just deleted)
req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/projects/columns/%d", owner.Name, repo.Name, column.ID).
AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}
func TestAPIAddIssueToProjectColumn(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID})
// Create a test project and column
project := &project_model.Project{
Title: "Project for Issue Assignment",
RepoID: repo.ID,
Type: project_model.TypeRepository,
CreatorID: owner.ID,
TemplateType: project_model.TemplateTypeNone,
}
err := project_model.NewProject(t.Context(), project)
assert.NoError(t, err)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), project.ID)
}()
column1 := &project_model.Column{
Title: "Column 1",
ProjectID: project.ID,
CreatorID: owner.ID,
}
err = project_model.NewColumn(t.Context(), column1)
assert.NoError(t, err)
column2 := &project_model.Column{
Title: "Column 2",
ProjectID: project.ID,
CreatorID: owner.ID,
}
err = project_model.NewColumn(t.Context(), column2)
assert.NoError(t, err)
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
// Test adding issue to column
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects/columns/%d/issues", owner.Name, repo.Name, column1.ID), &api.AddIssueToProjectColumnOption{
IssueID: issue.ID,
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusCreated)
// Verify issue is in the column
projectIssue := unittest.AssertExistsAndLoadBean(t, &project_model.ProjectIssue{
ProjectID: project.ID,
IssueID: issue.ID,
})
assert.Equal(t, column1.ID, projectIssue.ProjectColumnID)
// Test moving issue to another column
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects/columns/%d/issues", owner.Name, repo.Name, column2.ID), &api.AddIssueToProjectColumnOption{
IssueID: issue.ID,
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusCreated)
// Verify issue moved to new column
projectIssue = unittest.AssertExistsAndLoadBean(t, &project_model.ProjectIssue{
ProjectID: project.ID,
IssueID: issue.ID,
})
assert.Equal(t, column2.ID, projectIssue.ProjectColumnID)
// Test adding same issue to same column (should be idempotent)
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects/columns/%d/issues", owner.Name, repo.Name, column2.ID), &api.AddIssueToProjectColumnOption{
IssueID: issue.ID,
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusCreated)
// Test adding non-existent issue
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects/columns/%d/issues", owner.Name, repo.Name, column1.ID), &api.AddIssueToProjectColumnOption{
IssueID: 99999,
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusUnprocessableEntity)
// Test adding to non-existent column
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/projects/columns/99999/issues", owner.Name, repo.Name), &api.AddIssueToProjectColumnOption{
IssueID: issue.ID,
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
}
func TestAPIProjectPermissions(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
nonCollaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user5"})
// Create a test project
project := &project_model.Project{
Title: "Permission Test Project",
RepoID: repo.ID,
Type: project_model.TypeRepository,
CreatorID: owner.ID,
TemplateType: project_model.TemplateTypeNone,
}
err := project_model.NewProject(t.Context(), project)
assert.NoError(t, err)
defer func() {
_ = project_model.DeleteProjectByID(t.Context(), project.ID)
}()
ownerToken := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
nonCollaboratorToken := getUserToken(t, nonCollaborator.Name, auth_model.AccessTokenScopeWriteIssue)
// Owner should be able to read
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID).
AddTokenAuth(ownerToken)
MakeRequest(t, req, http.StatusOK)
// Owner should be able to update
newTitle := "Updated by Owner"
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID), &api.EditProjectOption{
Title: &newTitle,
}).AddTokenAuth(ownerToken)
MakeRequest(t, req, http.StatusOK)
// Non-collaborator should not be able to update
anotherTitle := "Updated by Non-collaborator"
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID), &api.EditProjectOption{
Title: &anotherTitle,
}).AddTokenAuth(nonCollaboratorToken)
MakeRequest(t, req, http.StatusForbidden)
// Non-collaborator should not be able to delete
req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/projects/%d", owner.Name, repo.Name, project.ID).
AddTokenAuth(nonCollaboratorToken)
MakeRequest(t, req, http.StatusForbidden)
}