Skip to content

Commit 7ca9979

Browse files
authored
Fixes 3577: creation prevented on previously deleted item (#573)
* Fixes 3577: Template creation prevented on previously deleted item * Fix latest migration key
1 parent 94fbe5a commit 7ca9979

5 files changed

+65
-2
lines changed

db/migrations.latest

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20240202124553
1+
20240212140239
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
BEGIN;
2+
3+
DROP INDEX name_org_id_not_deleted_unique;
4+
ALTER TABLE templates
5+
ADD CONSTRAINT name_org_id_unique UNIQUE (name, org_id);
6+
7+
COMMIT;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
BEGIN;
2+
3+
ALTER TABLE templates
4+
DROP CONSTRAINT name_org_id_unique;
5+
6+
CREATE UNIQUE INDEX IF NOT EXISTS name_org_id_not_deleted_unique
7+
ON templates(name, org_id)
8+
WHERE deleted_at IS NULL;
9+
10+
COMMIT;

pkg/dao/templates.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func (t templateDaoImpl) DBToApiError(e error) *ce.DaoError {
2727
if ok {
2828
if pgError.Code == "23505" {
2929
switch pgError.ConstraintName {
30-
case "name_org_id_unique":
30+
case "name_org_id_not_deleted_unique":
3131
dupKeyName = "name"
3232
}
3333
return &ce.DaoError{BadValidation: true, Message: "Template with this " + dupKeyName + " already belongs to organization"}

pkg/dao/templates_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,52 @@ func (s *TemplateSuite) TestCreate() {
5858
assert.Len(s.T(), reqTemplate.RepositoryUUIDS, 2)
5959
}
6060

61+
func (s *TemplateSuite) TestCreateDeleteCreateSameName() {
62+
templateDao := templateDaoImpl{db: s.tx}
63+
64+
orgID := orgIDTest
65+
err := seeds.SeedRepositoryConfigurations(s.tx, 2, seeds.SeedOptions{OrgID: orgID})
66+
assert.NoError(s.T(), err)
67+
68+
var repoConfigs []models.RepositoryConfiguration
69+
err = s.tx.Where("org_id = ?", orgID).Find(&repoConfigs).Error
70+
assert.NoError(s.T(), err)
71+
72+
timeNow := time.Now()
73+
reqTemplate := api.TemplateRequest{
74+
Name: pointy.String("template test"),
75+
Description: pointy.String("template test description"),
76+
RepositoryUUIDS: []string{repoConfigs[0].UUID, repoConfigs[1].UUID},
77+
Arch: pointy.String(config.AARCH64),
78+
Version: pointy.String(config.El8),
79+
Date: &timeNow,
80+
OrgID: &orgID,
81+
}
82+
83+
respTemplate, err := templateDao.Create(reqTemplate)
84+
assert.NoError(s.T(), err)
85+
assert.Equal(s.T(), orgID, respTemplate.OrgID)
86+
assert.Len(s.T(), reqTemplate.RepositoryUUIDS, 2)
87+
88+
// As a template with this name exists, we expect this to error.
89+
_, expectedErr := templateDao.Create(reqTemplate)
90+
assert.Error(s.T(), expectedErr, "Template with this name already belongs to organization")
91+
92+
// Delete the template
93+
err = templateDao.SoftDelete(respTemplate.OrgID, respTemplate.UUID)
94+
assert.NoError(s.T(), err)
95+
96+
// We should now be able to recreate the template with the same name without issue
97+
respTemplate, err = templateDao.Create(reqTemplate)
98+
assert.NoError(s.T(), err)
99+
assert.Equal(s.T(), orgID, respTemplate.OrgID)
100+
assert.Equal(s.T(), *reqTemplate.Description, respTemplate.Description)
101+
assert.Equal(s.T(), timeNow.Round(time.Millisecond), respTemplate.Date.Round(time.Millisecond))
102+
assert.Equal(s.T(), *reqTemplate.Arch, respTemplate.Arch)
103+
assert.Equal(s.T(), *reqTemplate.Version, respTemplate.Version)
104+
assert.Len(s.T(), reqTemplate.RepositoryUUIDS, 2)
105+
}
106+
61107
func (s *TemplateSuite) TestFetch() {
62108
templateDao := templateDaoImpl{db: s.tx}
63109

0 commit comments

Comments
 (0)