fix(project): duplicating a project should not create two backlog buckets
continuous-integration/drone/push Build is passing Details

Resolves https://community.vikunja.io/t/when-duplicating-a-project-the-resulting-project-has-an-extra-bucket/1524
This commit is contained in:
kolaente 2023-08-23 16:19:42 +02:00
parent acb03c430e
commit 5e8084c194
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
4 changed files with 24 additions and 11 deletions

View File

@ -680,7 +680,7 @@ func checkProjectBeforeUpdateOrDelete(s *xorm.Session, project *Project) (err er
return nil return nil
} }
func CreateProject(s *xorm.Session, project *Project, auth web.Auth) (err error) { func CreateProject(s *xorm.Session, project *Project, auth web.Auth, createBacklogBucket bool) (err error) {
err = project.CheckIsArchived(s) err = project.CheckIsArchived(s)
if err != nil { if err != nil {
return err return err
@ -715,14 +715,16 @@ func CreateProject(s *xorm.Session, project *Project, auth web.Auth) (err error)
} }
} }
// Create a new first bucket for this project if createBacklogBucket {
b := &Bucket{ // Create a new first bucket for this project
ProjectID: project.ID, b := &Bucket{
Title: "Backlog", ProjectID: project.ID,
} Title: "Backlog",
err = b.Create(s, auth) }
if err != nil { err = b.Create(s, auth)
return if err != nil {
return
}
} }
return events.Dispatch(&ProjectCreatedEvent{ return events.Dispatch(&ProjectCreatedEvent{
@ -928,7 +930,7 @@ func updateProjectByTaskID(s *xorm.Session, taskID int64) (err error) {
// @Failure 500 {object} models.Message "Internal error" // @Failure 500 {object} models.Message "Internal error"
// @Router /projects [put] // @Router /projects [put]
func (p *Project) Create(s *xorm.Session, a web.Auth) (err error) { func (p *Project) Create(s *xorm.Session, a web.Auth) (err error) {
err = CreateProject(s, p, a) err = CreateProject(s, p, a, true)
if err != nil { if err != nil {
return return
} }

View File

@ -81,7 +81,7 @@ func (pd *ProjectDuplicate) Create(s *xorm.Session, doer web.Auth) (err error) {
pd.Project.ParentProjectID = pd.ParentProjectID pd.Project.ParentProjectID = pd.ParentProjectID
// Set the owner to the current user // Set the owner to the current user
pd.Project.OwnerID = doer.GetID() pd.Project.OwnerID = doer.GetID()
if err := CreateProject(s, pd.Project, doer); err != nil { if err := CreateProject(s, pd.Project, doer, false); err != nil {
// If there is no available unique project identifier, just reset it. // If there is no available unique project identifier, just reset it.
if IsErrProjectIdentifierIsNotUnique(err) { if IsErrProjectIdentifierIsNotUnique(err) {
pd.Project.Identifier = "" pd.Project.Identifier = ""

View File

@ -44,6 +44,14 @@ func TestProjectDuplicate(t *testing.T) {
assert.True(t, can) assert.True(t, can)
err = l.Create(s, u) err = l.Create(s, u)
assert.NoError(t, err) assert.NoError(t, err)
// assert the new project has the same number of buckets as the old one
numberOfOriginalBuckets, err := s.Where("project_id = ?", l.ProjectID).Count(&Bucket{})
assert.NoError(t, err)
numberOfDuplicatedBuckets, err := s.Where("project_id = ?", l.Project.ID).Count(&Bucket{})
assert.NoError(t, err)
assert.Equal(t, numberOfOriginalBuckets, numberOfDuplicatedBuckets, "duplicated project does not have the same amount of buckets as the original one")
// To make this test 100% useful, it would need to assert a lot more stuff, but it is good enough for now. // To make this test 100% useful, it would need to assert a lot more stuff, but it is good enough for now.
// Also, we're lacking utility functions to do all needed assertions. // Also, we're lacking utility functions to do all needed assertions.
} }

View File

@ -51,6 +51,9 @@ func TestProject_CreateOrUpdate(t *testing.T) {
"description": project.Description, "description": project.Description,
"parent_project_id": 0, "parent_project_id": 0,
}, false) }, false)
db.AssertExists(t, "buckets", map[string]interface{}{
"project_id": project.ID,
}, false)
}) })
t.Run("nonexistant parent project", func(t *testing.T) { t.Run("nonexistant parent project", func(t *testing.T) {
db.LoadAndAssertFixtures(t) db.LoadAndAssertFixtures(t)