From 961fd13c551b3e50040acb7c914a00ead92de63f Mon Sep 17 00:00:00 2001 From: fluzz Date: Thu, 24 Aug 2023 12:03:59 +0200 Subject: [PATCH] Rewrite the 'AutoDate' tests using subtests Also add a test to check the permissions to set a date, and a test to check update dates on milestones. The tests related to 'AutoDate' are: - TestAPIEditIssueAutoDate - TestAPIAddIssueLabelsAutoDate - TestAPIEditIssueMilestoneAutoDate - TestAPICreateIssueAttachmentAutoDate - TestAPICreateCommentAutoDate - TestAPIEditCommentWithDate - TestAPICreateCommentAttachmentAutoDate --- .../api_comment_attachment_test.go | 106 ++++++------ tests/integration/api_comment_test.go | 153 ++++++++--------- .../integration/api_issue_attachment_test.go | 119 ++++++------- tests/integration/api_issue_label_test.go | 71 ++++---- tests/integration/api_issue_test.go | 160 ++++++++++++++---- 5 files changed, 332 insertions(+), 277 deletions(-) diff --git a/tests/integration/api_comment_attachment_test.go b/tests/integration/api_comment_attachment_test.go index 732e7e8a96..9761e06987 100644 --- a/tests/integration/api_comment_attachment_test.go +++ b/tests/integration/api_comment_attachment_test.go @@ -112,7 +112,7 @@ func TestAPICreateCommentAttachment(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID, CommentID: comment.ID}) } -func TestAPICreateCommentAttachmentWithAutoDate(t *testing.T) { +func TestAPICreateCommentAttachmentAutoDate(t *testing.T) { defer tests.PrepareTestEnv(t)() comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}) @@ -129,73 +129,63 @@ func TestAPICreateCommentAttachmentWithAutoDate(t *testing.T) { buff := generateImg() body := &bytes.Buffer{} - // Setup multi-part - writer := multipart.NewWriter(body) - part, err := writer.CreateFormFile("attachment", filename) - assert.NoError(t, err) - _, err = io.Copy(part, &buff) - assert.NoError(t, err) - err = writer.Close() - assert.NoError(t, err) + t.Run("WithAutoDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "POST", urlStr, body) - req.Header.Add("Content-Type", writer.FormDataContentType()) - resp := session.MakeRequest(t, req, http.StatusCreated) + // Setup multi-part + writer := multipart.NewWriter(body) + part, err := writer.CreateFormFile("attachment", filename) + assert.NoError(t, err) + _, err = io.Copy(part, &buff) + assert.NoError(t, err) + err = writer.Close() + assert.NoError(t, err) - apiAttachment := new(api.Attachment) - DecodeJSON(t, resp, &apiAttachment) + req := NewRequestWithBody(t, "POST", urlStr, body) + req.Header.Add("Content-Type", writer.FormDataContentType()) + resp := session.MakeRequest(t, req, http.StatusCreated) + apiAttachment := new(api.Attachment) + DecodeJSON(t, resp, &apiAttachment) - unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID}) - // the execution of the API call supposedly lasted less than one minute - updatedSince := time.Since(apiAttachment.Created) - assert.LessOrEqual(t, updatedSince, time.Minute) + unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID}) + // the execution of the API call supposedly lasted less than one minute + updatedSince := time.Since(apiAttachment.Created) + assert.LessOrEqual(t, updatedSince, time.Minute) - commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID}) - updatedSince = time.Since(commentAfter.UpdatedUnix.AsTime()) - assert.LessOrEqual(t, updatedSince, time.Minute) -} + commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID}) + updatedSince = time.Since(commentAfter.UpdatedUnix.AsTime()) + assert.LessOrEqual(t, updatedSince, time.Minute) + }) -func TestAPICreateCommentAttachmentWithNoAutoDate(t *testing.T) { - defer tests.PrepareTestEnv(t)() + t.Run("WithUpdateDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() - comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) + urlStr += fmt.Sprintf("&updated_at=%s", updatedAt.UTC().Format(time.RFC3339)) - session := loginUser(t, repoOwner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets?token=%s&updated_at=%s", - repoOwner.Name, repo.Name, comment.ID, token, updatedAt.UTC().Format(time.RFC3339)) + // Setup multi-part + writer := multipart.NewWriter(body) + part, err := writer.CreateFormFile("attachment", filename) + assert.NoError(t, err) + _, err = io.Copy(part, &buff) + assert.NoError(t, err) + err = writer.Close() + assert.NoError(t, err) - filename := "image.png" - buff := generateImg() - body := &bytes.Buffer{} + req := NewRequestWithBody(t, "POST", urlStr, body) + req.Header.Add("Content-Type", writer.FormDataContentType()) + resp := session.MakeRequest(t, req, http.StatusCreated) + apiAttachment := new(api.Attachment) + DecodeJSON(t, resp, &apiAttachment) - // Setup multi-part - writer := multipart.NewWriter(body) - part, err := writer.CreateFormFile("attachment", filename) - assert.NoError(t, err) - _, err = io.Copy(part, &buff) - assert.NoError(t, err) - err = writer.Close() - assert.NoError(t, err) + // dates will be converted into the same tz, in order to compare them + utcTZ, _ := time.LoadLocation("UTC") + unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID}) + assert.Equal(t, updatedAt.In(utcTZ), apiAttachment.Created.In(utcTZ)) - req := NewRequestWithBody(t, "POST", urlStr, body) - req.Header.Add("Content-Type", writer.FormDataContentType()) - resp := session.MakeRequest(t, req, http.StatusCreated) - - apiAttachment := new(api.Attachment) - DecodeJSON(t, resp, &apiAttachment) - - // dates will be converted into the same tz, in order to compare them - utcTZ, _ := time.LoadLocation("UTC") - unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID}) - assert.Equal(t, updatedAt.In(utcTZ), apiAttachment.Created.In(utcTZ)) - - commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID}) - assert.Equal(t, updatedAt.In(utcTZ), commentAfter.UpdatedUnix.AsTime().In(utcTZ)) + commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID}) + assert.Equal(t, updatedAt.In(utcTZ), commentAfter.UpdatedUnix.AsTime().In(utcTZ)) + }) } func TestAPIEditCommentAttachment(t *testing.T) { diff --git a/tests/integration/api_comment_test.go b/tests/integration/api_comment_test.go index b3c249eee0..339ffdbe0e 100644 --- a/tests/integration/api_comment_test.go +++ b/tests/integration/api_comment_test.go @@ -111,61 +111,56 @@ func TestAPICreateComment(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) } -func TestAPICreateCommentWithAutoDate(t *testing.T) { +func TestAPICreateCommentAutoDate(t *testing.T) { defer tests.PrepareTestEnv(t)() - const commentBody = "Comment body" issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments?token=%s", repoOwner.Name, repo.Name, issue.Index, token) - req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ - "body": commentBody, - }) - resp := MakeRequest(t, req, http.StatusCreated) - - var updatedComment api.Comment - DecodeJSON(t, resp, &updatedComment) - - // the execution of the API call supposedly lasted less than one minute - updatedSince := time.Since(updatedComment.Updated) - assert.LessOrEqual(t, updatedSince, time.Minute) - - commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) - updatedSince = time.Since(commentAfter.UpdatedUnix.AsTime()) - assert.LessOrEqual(t, updatedSince, time.Minute) -} - -func TestAPICreateCommentWithNoAutoDate(t *testing.T) { - defer tests.PrepareTestEnv(t)() const commentBody = "Comment body" - updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + t.Run("WithAutoDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() - token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments?token=%s", - repoOwner.Name, repo.Name, issue.Index, token) - req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueCommentOption{ - Body: commentBody, - Updated: &updatedAt, + req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ + "body": commentBody, + }) + resp := MakeRequest(t, req, http.StatusCreated) + var updatedComment api.Comment + DecodeJSON(t, resp, &updatedComment) + + // the execution of the API call supposedly lasted less than one minute + updatedSince := time.Since(updatedComment.Updated) + assert.LessOrEqual(t, updatedSince, time.Minute) + + commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) + updatedSince = time.Since(commentAfter.UpdatedUnix.AsTime()) + assert.LessOrEqual(t, updatedSince, time.Minute) }) - resp := MakeRequest(t, req, http.StatusCreated) + t.Run("WithUpdateDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() - var updatedComment api.Comment - DecodeJSON(t, resp, &updatedComment) + updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) - // dates will be converted into the same tz, in order to compare them - utcTZ, _ := time.LoadLocation("UTC") - assert.Equal(t, updatedAt.In(utcTZ), updatedComment.Updated.In(utcTZ)) - commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) - assert.Equal(t, updatedAt.In(utcTZ), commentAfter.UpdatedUnix.AsTime().In(utcTZ)) + req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueCommentOption{ + Body: commentBody, + Updated: &updatedAt, + }) + resp := MakeRequest(t, req, http.StatusCreated) + var updatedComment api.Comment + DecodeJSON(t, resp, &updatedComment) + + // dates will be converted into the same tz, in order to compare them + utcTZ, _ := time.LoadLocation("UTC") + assert.Equal(t, updatedAt.In(utcTZ), updatedComment.Updated.In(utcTZ)) + commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) + assert.Equal(t, updatedAt.In(utcTZ), commentAfter.UpdatedUnix.AsTime().In(utcTZ)) + }) } func TestAPIGetComment(t *testing.T) { @@ -219,64 +214,58 @@ func TestAPIEditComment(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) } -func TestAPIEditCommentWithAutoDate(t *testing.T) { +func TestAPIEditCommentWithDate(t *testing.T) { defer tests.PrepareTestEnv(t)() - const newCommentBody = "This is the new comment body" comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, unittest.Cond("type = ?", issues_model.CommentTypeComment)) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, token) - req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ - "body": newCommentBody, - }) - resp := MakeRequest(t, req, http.StatusOK) - - var updatedComment api.Comment - DecodeJSON(t, resp, &updatedComment) - - // the execution of the API call supposedly lasted less than one minute - updatedSince := time.Since(updatedComment.Updated) - assert.LessOrEqual(t, updatedSince, time.Minute) - - commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) - updatedSince = time.Since(commentAfter.UpdatedUnix.AsTime()) - assert.LessOrEqual(t, updatedSince, time.Minute) -} - -func TestAPIEditCommentWithNoAutoDate(t *testing.T) { - defer tests.PrepareTestEnv(t)() const newCommentBody = "This is the new comment body" - updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) - comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{}, - unittest.Cond("type = ?", issues_model.CommentTypeComment)) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + t.Run("WithAutoDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() - token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s", - repoOwner.Name, repo.Name, comment.ID, token) - req := NewRequestWithJSON(t, "PATCH", urlStr, &api.EditIssueCommentOption{ - Body: newCommentBody, - Updated: &updatedAt, + req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ + "body": newCommentBody, + }) + resp := MakeRequest(t, req, http.StatusOK) + var updatedComment api.Comment + DecodeJSON(t, resp, &updatedComment) + + // the execution of the API call supposedly lasted less than one minute + updatedSince := time.Since(updatedComment.Updated) + assert.LessOrEqual(t, updatedSince, time.Minute) + + commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) + updatedSince = time.Since(commentAfter.UpdatedUnix.AsTime()) + assert.LessOrEqual(t, updatedSince, time.Minute) }) - resp := MakeRequest(t, req, http.StatusOK) - var updatedComment api.Comment - DecodeJSON(t, resp, &updatedComment) + t.Run("WithUpdateDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() - // dates will be converted into the same tz, in order to compare them - utcTZ, _ := time.LoadLocation("UTC") - assert.Equal(t, updatedAt.In(utcTZ), updatedComment.Updated.In(utcTZ)) - commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) - assert.Equal(t, updatedAt.In(utcTZ), commentAfter.UpdatedUnix.AsTime().In(utcTZ)) + updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) + + req := NewRequestWithJSON(t, "PATCH", urlStr, &api.EditIssueCommentOption{ + Body: newCommentBody, + Updated: &updatedAt, + }) + resp := MakeRequest(t, req, http.StatusOK) + var updatedComment api.Comment + DecodeJSON(t, resp, &updatedComment) + + // dates will be converted into the same tz, in order to compare them + utcTZ, _ := time.LoadLocation("UTC") + assert.Equal(t, updatedAt.In(utcTZ), updatedComment.Updated.In(utcTZ)) + commentAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) + assert.Equal(t, updatedAt.In(utcTZ), commentAfter.UpdatedUnix.AsTime().In(utcTZ)) + }) } func TestAPIDeleteComment(t *testing.T) { diff --git a/tests/integration/api_issue_attachment_test.go b/tests/integration/api_issue_attachment_test.go index ba72df2400..2250646354 100644 --- a/tests/integration/api_issue_attachment_test.go +++ b/tests/integration/api_issue_attachment_test.go @@ -101,7 +101,7 @@ func TestAPICreateIssueAttachment(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID, IssueID: issue.ID}) } -func TestAPICreateIssueAttachmentWithAutoDate(t *testing.T) { +func TestAPICreateIssueAttachmentAutoDate(t *testing.T) { defer tests.PrepareTestEnv(t)() repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) @@ -110,80 +110,71 @@ func TestAPICreateIssueAttachmentWithAutoDate(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - - filename := "image.png" - buff := generateImg() - body := &bytes.Buffer{} - - // Setup multi-part - writer := multipart.NewWriter(body) - part, err := writer.CreateFormFile("attachment", filename) - assert.NoError(t, err) - _, err = io.Copy(part, &buff) - assert.NoError(t, err) - err = writer.Close() - assert.NoError(t, err) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets?token=%s", repoOwner.Name, repo.Name, issue.Index, token) - req := NewRequestWithBody(t, "POST", urlStr, body) - req.Header.Add("Content-Type", writer.FormDataContentType()) - resp := session.MakeRequest(t, req, http.StatusCreated) - - apiAttachment := new(api.Attachment) - DecodeJSON(t, resp, &apiAttachment) - - unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID, IssueID: issue.ID}) - // the execution of the API call supposedly lasted less than one minute - updatedSince := time.Since(apiAttachment.Created) - assert.LessOrEqual(t, updatedSince, time.Minute) - - issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.Index}) - updatedSince = time.Since(issueAfter.UpdatedUnix.AsTime()) - assert.LessOrEqual(t, updatedSince, time.Minute) -} - -func TestAPICreateIssueAttachmentWithNoAutoDate(t *testing.T) { - defer tests.PrepareTestEnv(t)() - - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}) - repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - - session := loginUser(t, repoOwner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - filename := "image.png" buff := generateImg() body := &bytes.Buffer{} - // Setup multi-part - writer := multipart.NewWriter(body) - part, err := writer.CreateFormFile("attachment", filename) - assert.NoError(t, err) - _, err = io.Copy(part, &buff) - assert.NoError(t, err) - err = writer.Close() - assert.NoError(t, err) + t.Run("WithAutoDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() - updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets?token=%s&updated_at=%s", - repoOwner.Name, repo.Name, issue.Index, token, updatedAt.UTC().Format(time.RFC3339)) + // Setup multi-part + writer := multipart.NewWriter(body) + part, err := writer.CreateFormFile("attachment", filename) + assert.NoError(t, err) + _, err = io.Copy(part, &buff) + assert.NoError(t, err) + err = writer.Close() + assert.NoError(t, err) - req := NewRequestWithBody(t, "POST", urlStr, body) - req.Header.Add("Content-Type", writer.FormDataContentType()) - resp := session.MakeRequest(t, req, http.StatusCreated) + req := NewRequestWithBody(t, "POST", urlStr, body) + req.Header.Add("Content-Type", writer.FormDataContentType()) + resp := session.MakeRequest(t, req, http.StatusCreated) - apiAttachment := new(api.Attachment) - DecodeJSON(t, resp, &apiAttachment) + apiAttachment := new(api.Attachment) + DecodeJSON(t, resp, &apiAttachment) - // dates will be converted into the same tz, in order to compare them - utcTZ, _ := time.LoadLocation("UTC") - unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID, IssueID: issue.ID}) - assert.Equal(t, updatedAt.In(utcTZ), apiAttachment.Created.In(utcTZ)) - issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}) - assert.Equal(t, updatedAt.In(utcTZ), issueAfter.UpdatedUnix.AsTime().In(utcTZ)) + unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID, IssueID: issue.ID}) + // the execution of the API call supposedly lasted less than one minute + updatedSince := time.Since(apiAttachment.Created) + assert.LessOrEqual(t, updatedSince, time.Minute) + + issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.Index}) + updatedSince = time.Since(issueAfter.UpdatedUnix.AsTime()) + assert.LessOrEqual(t, updatedSince, time.Minute) + }) + + t.Run("WithUpdateDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) + urlStr += fmt.Sprintf("&updated_at=%s", updatedAt.UTC().Format(time.RFC3339)) + + // Setup multi-part + writer := multipart.NewWriter(body) + part, err := writer.CreateFormFile("attachment", filename) + assert.NoError(t, err) + _, err = io.Copy(part, &buff) + assert.NoError(t, err) + err = writer.Close() + assert.NoError(t, err) + + req := NewRequestWithBody(t, "POST", urlStr, body) + req.Header.Add("Content-Type", writer.FormDataContentType()) + resp := session.MakeRequest(t, req, http.StatusCreated) + + apiAttachment := new(api.Attachment) + DecodeJSON(t, resp, &apiAttachment) + + // dates will be converted into the same tz, in order to compare them + utcTZ, _ := time.LoadLocation("UTC") + unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachment.ID, IssueID: issue.ID}) + assert.Equal(t, updatedAt.In(utcTZ), apiAttachment.Created.In(utcTZ)) + issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}) + assert.Equal(t, updatedAt.In(utcTZ), issueAfter.UpdatedUnix.AsTime().In(utcTZ)) + }) } func TestAPIEditIssueAttachment(t *testing.T) { diff --git a/tests/integration/api_issue_label_test.go b/tests/integration/api_issue_label_test.go index 3c2bed6be0..a29c75727f 100644 --- a/tests/integration/api_issue_label_test.go +++ b/tests/integration/api_issue_label_test.go @@ -16,6 +16,7 @@ import ( "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" ) @@ -112,57 +113,47 @@ func TestAPIAddIssueLabels(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: 2}) } -func TestAPIAddIssueLabelsWithAutoDate(t *testing.T) { - assert.NoError(t, unittest.LoadFixtures()) +func TestAPIAddIssueLabelsAutoDate(t *testing.T) { + defer tests.PrepareTestEnv(t)() - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}) - _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID, ID: 2}) + issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels?token=%s", - repo.OwnerName, repo.Name, issue.Index, token) - req := NewRequestWithJSON(t, "POST", urlStr, &api.IssueLabelsOption{ - Labels: []int64{1, 2}, + owner.Name, repo.Name, issueBefore.Index, token) + + t.Run("WithAutoDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequestWithJSON(t, "POST", urlStr, &api.IssueLabelsOption{ + Labels: []int64{1}, + }) + MakeRequest(t, req, http.StatusOK) + + issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueBefore.ID}) + // the execution of the API call supposedly lasted less than one minute + updatedSince := time.Since(issueAfter.UpdatedUnix.AsTime()) + assert.LessOrEqual(t, updatedSince, time.Minute) }) - resp := MakeRequest(t, req, http.StatusOK) - var apiLabels []*api.Label - DecodeJSON(t, resp, &apiLabels) - issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.Index}) - // the execution of the API call supposedly lasted less than one minute - updatedSince := time.Since(issueAfter.UpdatedUnix.AsTime()) - assert.LessOrEqual(t, updatedSince, time.Minute) -} + t.Run("WithUpdatedDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() -func TestAPIAddIssueLabelsWithNoAutoDate(t *testing.T) { - assert.NoError(t, unittest.LoadFixtures()) + updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) + req := NewRequestWithJSON(t, "POST", urlStr, &api.IssueLabelsOption{ + Labels: []int64{2}, + Updated: &updatedAt, + }) + MakeRequest(t, req, http.StatusOK) - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}) - _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID, ID: 2}) - owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - - session := loginUser(t, owner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) - - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels?token=%s", - repo.OwnerName, repo.Name, issue.Index, token) - req := NewRequestWithJSON(t, "POST", urlStr, &api.IssueLabelsOption{ - Labels: []int64{1, 2}, - Updated: &updatedAt, + // dates will be converted into the same tz, in order to compare them + utcTZ, _ := time.LoadLocation("UTC") + issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueBefore.ID}) + assert.Equal(t, updatedAt.In(utcTZ), issueAfter.UpdatedUnix.AsTime().In(utcTZ)) }) - resp := MakeRequest(t, req, http.StatusOK) - var apiLabels []*api.Label - DecodeJSON(t, resp, &apiLabels) - // dates will be converted into the same tz, in order to compare them - utcTZ, _ := time.LoadLocation("UTC") - issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.Index}) - assert.Equal(t, updatedAt.In(utcTZ), issueAfter.UpdatedUnix.AsTime().In(utcTZ)) } func TestAPIReplaceIssueLabels(t *testing.T) { diff --git a/tests/integration/api_issue_test.go b/tests/integration/api_issue_test.go index ac26caf006..8e81bb3cb6 100644 --- a/tests/integration/api_issue_test.go +++ b/tests/integration/api_issue_test.go @@ -213,61 +213,155 @@ func TestAPIEditIssue(t *testing.T) { assert.Equal(t, title, issueAfter.Title) } -func TestAPIEditIssueWithAutoDate(t *testing.T) { +func TestAPIEditIssueAutoDate(t *testing.T) { defer tests.PrepareTestEnv(t)() - issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}) + issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 13}) repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}) assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext)) - session := loginUser(t, owner.Name) - token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) + t.Run("WithAutoDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() - body := "new content!" - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d?token=%s", owner.Name, repoBefore.Name, issueBefore.Index, token) - req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{ - Body: &body, + // User2 is not owner, but can update the 'public' issue with auto date + session := loginUser(t, "user2") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d?token=%s", owner.Name, repoBefore.Name, issueBefore.Index, token) + + body := "new content!" + req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{ + Body: &body, + }) + resp := MakeRequest(t, req, http.StatusCreated) + var apiIssue api.Issue + DecodeJSON(t, resp, &apiIssue) + + // the execution of the API call supposedly lasted less than one minute + updatedSince := time.Since(apiIssue.Updated) + assert.LessOrEqual(t, updatedSince, time.Minute) + + issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueBefore.ID}) + updatedSince = time.Since(issueAfter.UpdatedUnix.AsTime()) + assert.LessOrEqual(t, updatedSince, time.Minute) }) - resp := MakeRequest(t, req, http.StatusCreated) - var apiIssue api.Issue - DecodeJSON(t, resp, &apiIssue) - // the execution of the API call supposedly lasted less than one minute - updatedSince := time.Since(apiIssue.Updated) - assert.LessOrEqual(t, updatedSince, time.Minute) + t.Run("WithUpdateDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() - issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}) - updatedSince = time.Since(issueAfter.UpdatedUnix.AsTime()) - assert.LessOrEqual(t, updatedSince, time.Minute) + // User1 is admin, and so can update the issue without auto date + session := loginUser(t, "user1") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d?token=%s", owner.Name, repoBefore.Name, issueBefore.Index, token) + + body := "new content, with updated time" + updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) + req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{ + Body: &body, + Updated: &updatedAt, + }) + resp := MakeRequest(t, req, http.StatusCreated) + var apiIssue api.Issue + DecodeJSON(t, resp, &apiIssue) + + // dates are converted into the same tz, in order to compare them + utcTZ, _ := time.LoadLocation("UTC") + assert.Equal(t, updatedAt.In(utcTZ), apiIssue.Updated.In(utcTZ)) + + issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueBefore.ID}) + assert.Equal(t, updatedAt.In(utcTZ), issueAfter.UpdatedUnix.AsTime().In(utcTZ)) + }) + + t.Run("WithoutPermission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + // User2 is not owner nor admin, and so can't update the issue without auto date + session := loginUser(t, "user2") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d?token=%s", owner.Name, repoBefore.Name, issueBefore.Index, token) + + body := "new content, with updated time" + updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) + req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{ + Body: &body, + Updated: &updatedAt, + }) + resp := MakeRequest(t, req, http.StatusForbidden) + var apiError api.APIError + DecodeJSON(t, resp, &apiError) + + assert.Equal(t, "user needs to have admin or owner right", apiError.Message) + }) } -func TestAPIEditIssueWithNoAutoDate(t *testing.T) { +func TestAPIEditIssueMilestoneAutoDate(t *testing.T) { defer tests.PrepareTestEnv(t)() - issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}) + issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}) assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext)) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - - body := "new content, with updated time" - updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d?token=%s", owner.Name, repoBefore.Name, issueBefore.Index, token) - req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{ - Body: &body, - Updated: &updatedAt, + + t.Run("WithAutoDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + milestone := int64(1) + req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{ + Milestone: &milestone, + }) + MakeRequest(t, req, http.StatusCreated) + + // the execution of the API call supposedly lasted less than one minute + milestoneAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: milestone}) + updatedSince := time.Since(milestoneAfter.UpdatedUnix.AsTime()) + assert.LessOrEqual(t, updatedSince, time.Minute) + }) + + t.Run("WithPostUpdateDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + // Note: the updated_unix field of the test Milestones is set to NULL + // Hence, any date is higher than the Milestone's updated date + updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) + milestone := int64(2) + req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{ + Milestone: &milestone, + Updated: &updatedAt, + }) + MakeRequest(t, req, http.StatusCreated) + + // the milestone date should be set to 'updatedAt' + // dates are converted into the same tz, in order to compare them + utcTZ, _ := time.LoadLocation("UTC") + milestoneAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: milestone}) + assert.Equal(t, updatedAt.In(utcTZ), milestoneAfter.UpdatedUnix.AsTime().In(utcTZ)) + }) + + t.Run("WithPastUpdateDate", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + // Note: This Milestone's updated_unix has been set to Now() by the first subtest + milestone := int64(1) + milestoneBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: milestone}) + + updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second) + req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{ + Milestone: &milestone, + Updated: &updatedAt, + }) + MakeRequest(t, req, http.StatusCreated) + + // the milestone date should not change + // dates are converted into the same tz, in order to compare them + utcTZ, _ := time.LoadLocation("UTC") + milestoneAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: milestone}) + assert.Equal(t, milestoneAfter.UpdatedUnix.AsTime().In(utcTZ), milestoneBefore.UpdatedUnix.AsTime().In(utcTZ)) }) - resp := MakeRequest(t, req, http.StatusCreated) - var apiIssue api.Issue - DecodeJSON(t, resp, &apiIssue) - // dates will be converted into the same tz, in order to compare them - utcTZ, _ := time.LoadLocation("UTC") - assert.Equal(t, updatedAt.In(utcTZ), apiIssue.Updated.In(utcTZ)) - issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}) - assert.Equal(t, updatedAt.In(utcTZ), issueAfter.UpdatedUnix.AsTime().In(utcTZ)) } func TestAPISearchIssues(t *testing.T) {