[FEAT] allow setting the update date on issues and comments (squash) apply the 'update_at' value to the cross-ref comments (#1676)
[this is a follow-up to PR #764] When a comment of issue A referencing issue B is added with a forced 'updated_at' date, that date has to be applied to the comment created in issue B. ----- Comment: While trying my 'RoundUp migration script', I found that this case was forgotten in PR #764 - my apologies... I'll try to write a functional test, base on models/issues/issue_xref_test.go Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/1676 Co-authored-by: fluzz <fluzz@freedroid.org> Co-committed-by: fluzz <fluzz@freedroid.org>
This commit is contained in:
parent
25e96cfcb2
commit
ac4f727f63
3 changed files with 115 additions and 8 deletions
|
@ -818,6 +818,9 @@ func CreateComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment,
|
||||||
Invalidated: opts.Invalidated,
|
Invalidated: opts.Invalidated,
|
||||||
}
|
}
|
||||||
if opts.Issue.NoAutoTime {
|
if opts.Issue.NoAutoTime {
|
||||||
|
// Preload the comment with the Issue containing the forced update
|
||||||
|
// date. This is needed to propagate those data in AddCrossReferences()
|
||||||
|
comment.Issue = opts.Issue
|
||||||
comment.CreatedUnix = opts.Issue.UpdatedUnix
|
comment.CreatedUnix = opts.Issue.UpdatedUnix
|
||||||
comment.UpdatedUnix = opts.Issue.UpdatedUnix
|
comment.UpdatedUnix = opts.Issue.UpdatedUnix
|
||||||
e.NoAutoTime()
|
e.NoAutoTime()
|
||||||
|
@ -1101,21 +1104,22 @@ func UpdateComment(ctx context.Context, c *Comment, doer *user_model.User) error
|
||||||
}
|
}
|
||||||
defer committer.Close()
|
defer committer.Close()
|
||||||
|
|
||||||
|
if err := c.LoadIssue(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
sess := db.GetEngine(ctx).ID(c.ID).AllCols()
|
sess := db.GetEngine(ctx).ID(c.ID).AllCols()
|
||||||
if c.Issue.NoAutoTime {
|
if c.Issue.NoAutoTime {
|
||||||
// update the DataBase
|
// update the DataBase
|
||||||
sess = sess.NoAutoTime().SetExpr("updated_unix", c.Issue.UpdatedUnix)
|
sess = sess.NoAutoTime().SetExpr("updated_unix", c.Issue.UpdatedUnix)
|
||||||
// the UpdatedUnix value of the Comment also has to be set,
|
// the UpdatedUnix value of the Comment also has to be set,
|
||||||
// to return the adequate valuè
|
// to return the adequate value
|
||||||
// see https://codeberg.org/forgejo/forgejo/pulls/764#issuecomment-1023801
|
// see https://codeberg.org/forgejo/forgejo/pulls/764#issuecomment-1023801
|
||||||
c.UpdatedUnix = c.Issue.UpdatedUnix
|
c.UpdatedUnix = c.Issue.UpdatedUnix
|
||||||
}
|
}
|
||||||
if _, err := sess.Update(c); err != nil {
|
if _, err := sess.Update(c); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := c.LoadIssue(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := c.AddCrossReferences(ctx, doer, true); err != nil {
|
if err := c.AddCrossReferences(ctx, doer, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,11 +46,15 @@ func neuterCrossReferences(ctx context.Context, issueID, commentID int64) error
|
||||||
for i, c := range active {
|
for i, c := range active {
|
||||||
ids[i] = c.ID
|
ids[i] = c.ID
|
||||||
}
|
}
|
||||||
return neuterCrossReferencesIds(ctx, ids)
|
return neuterCrossReferencesIds(ctx, nil, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
func neuterCrossReferencesIds(ctx context.Context, ids []int64) error {
|
func neuterCrossReferencesIds(stdCtx context.Context, ctx *crossReferencesContext, ids []int64) error {
|
||||||
_, err := db.GetEngine(ctx).In("id", ids).Cols("`ref_action`").Update(&Comment{RefAction: references.XRefActionNeutered})
|
sess := db.GetEngine(stdCtx).In("id", ids).Cols("`ref_action`")
|
||||||
|
if ctx != nil && ctx.OrigIssue.NoAutoTime {
|
||||||
|
sess.SetExpr("updated_unix", ctx.OrigIssue.UpdatedUnix).NoAutoTime()
|
||||||
|
}
|
||||||
|
_, err := sess.Update(&Comment{RefAction: references.XRefActionNeutered})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +104,7 @@ func (issue *Issue) createCrossReferences(stdCtx context.Context, ctx *crossRefe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(ids) > 0 {
|
if len(ids) > 0 {
|
||||||
if err = neuterCrossReferencesIds(stdCtx, ids); err != nil {
|
if err = neuterCrossReferencesIds(stdCtx, ctx, ids); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/references"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/services/convert"
|
"code.gitea.io/gitea/services/convert"
|
||||||
"code.gitea.io/gitea/tests"
|
"code.gitea.io/gitea/tests"
|
||||||
|
@ -163,6 +164,104 @@ func TestAPICreateCommentAutoDate(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPICommentXRefAutoDate(t *testing.T) {
|
||||||
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
|
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
|
||||||
|
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)
|
||||||
|
|
||||||
|
t.Run("WithAutoDate", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
// Create a comment mentioning issue #2 and check that a xref comment was added
|
||||||
|
// in issue #2
|
||||||
|
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments?token=%s",
|
||||||
|
repoOwner.Name, repo.Name, issue.Index, token)
|
||||||
|
|
||||||
|
commentBody := "mention #2"
|
||||||
|
req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueCommentOption{
|
||||||
|
Body: commentBody,
|
||||||
|
})
|
||||||
|
resp := MakeRequest(t, req, http.StatusCreated)
|
||||||
|
var createdComment api.Comment
|
||||||
|
DecodeJSON(t, resp, &createdComment)
|
||||||
|
|
||||||
|
ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: 2, RefIssueID: 1, RefCommentID: createdComment.ID})
|
||||||
|
assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type)
|
||||||
|
assert.Equal(t, references.XRefActionNone, ref.RefAction)
|
||||||
|
// the execution of the API call supposedly lasted less than one minute
|
||||||
|
updatedSince := time.Since(ref.UpdatedUnix.AsTime())
|
||||||
|
assert.LessOrEqual(t, updatedSince, time.Minute)
|
||||||
|
|
||||||
|
// Remove the mention to issue #2 and check that the xref was neutered
|
||||||
|
urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
|
||||||
|
repoOwner.Name, repo.Name, createdComment.ID, token)
|
||||||
|
|
||||||
|
newCommentBody := "no mention"
|
||||||
|
req = NewRequestWithJSON(t, "PATCH", urlStr, &api.EditIssueCommentOption{
|
||||||
|
Body: newCommentBody,
|
||||||
|
})
|
||||||
|
resp = MakeRequest(t, req, http.StatusOK)
|
||||||
|
var updatedComment api.Comment
|
||||||
|
DecodeJSON(t, resp, &updatedComment)
|
||||||
|
|
||||||
|
ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: 2, RefIssueID: 1, RefCommentID: updatedComment.ID})
|
||||||
|
assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type)
|
||||||
|
assert.Equal(t, references.XRefActionNeutered, ref.RefAction)
|
||||||
|
// the execution of the API call supposedly lasted less than one minute
|
||||||
|
updatedSince = time.Since(ref.UpdatedUnix.AsTime())
|
||||||
|
assert.LessOrEqual(t, updatedSince, time.Minute)
|
||||||
|
})
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
// Create a comment mentioning issue #2 and check that a xref comment was added
|
||||||
|
// in issue #2
|
||||||
|
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments?token=%s",
|
||||||
|
repoOwner.Name, repo.Name, issue.Index, token)
|
||||||
|
|
||||||
|
commentBody := "re-mention #2"
|
||||||
|
updatedAt := time.Now().Add(-time.Hour).Truncate(time.Second)
|
||||||
|
req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueCommentOption{
|
||||||
|
Body: commentBody,
|
||||||
|
Updated: &updatedAt,
|
||||||
|
})
|
||||||
|
resp := MakeRequest(t, req, http.StatusCreated)
|
||||||
|
var createdComment api.Comment
|
||||||
|
DecodeJSON(t, resp, &createdComment)
|
||||||
|
|
||||||
|
ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: 2, RefIssueID: 1, RefCommentID: createdComment.ID})
|
||||||
|
assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type)
|
||||||
|
assert.Equal(t, references.XRefActionNone, ref.RefAction)
|
||||||
|
assert.Equal(t, updatedAt.In(utcTZ), ref.UpdatedUnix.AsTimeInLocation(utcTZ))
|
||||||
|
|
||||||
|
// Remove the mention to issue #2 and check that the xref was neutered
|
||||||
|
urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s",
|
||||||
|
repoOwner.Name, repo.Name, createdComment.ID, token)
|
||||||
|
|
||||||
|
newCommentBody := "no mention"
|
||||||
|
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)
|
||||||
|
|
||||||
|
ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: 2, RefIssueID: 1, RefCommentID: updatedComment.ID})
|
||||||
|
assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type)
|
||||||
|
assert.Equal(t, references.XRefActionNeutered, ref.RefAction)
|
||||||
|
assert.Equal(t, updatedAt.In(utcTZ), ref.UpdatedUnix.AsTimeInLocation(utcTZ))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAPIGetComment(t *testing.T) {
|
func TestAPIGetComment(t *testing.T) {
|
||||||
defer tests.PrepareTestEnv(t)()
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue