diff --git a/db/structs.go b/db/structs.go index 300758092..4a2b2bb3d 100644 --- a/db/structs.go +++ b/db/structs.go @@ -7,7 +7,6 @@ import ( "errors" "time" - "github.com/google/uuid" "github.com/gorilla/websocket" "github.com/lib/pq" "gorm.io/gorm" @@ -953,7 +952,7 @@ const ( ) type Tickets struct { - UUID uuid.UUID `gorm:"primaryKey;type:uuid;default:gen_random_uuid()"` + UUID string `gorm:"primaryKey;type:uuid;default:gen_random_uuid()"` FeatureUUID string `gorm:"type:uuid;not null;index:composite_index" json:"feature_uuid" validate:"required"` Features WorkspaceFeatures `gorm:"foreignKey:FeatureUUID;references:Uuid"` PhaseUUID string `gorm:"type:uuid;not null;index:phase_index" json:"phase_uuid" validate:"required"` diff --git a/db/tickets.go b/db/tickets.go new file mode 100644 index 000000000..d5e97b838 --- /dev/null +++ b/db/tickets.go @@ -0,0 +1,50 @@ +package db + +import ( + "errors" + "fmt" + "time" +) + +func (db database) CreateOrEditTicket(ticket *Tickets) (Tickets, error) { + + if ticket.UUID == "" || ticket.FeatureUUID == "" || ticket.PhaseUUID == "" || ticket.Name == "" { + return Tickets{}, errors.New("required fields are missing") + } + + // check if ticket exists and update it + if db.db.Model(&Tickets{}).Where("uuid = ?", ticket.UUID).First(&ticket).RowsAffected != 0 { + now := time.Now() + ticket.UpdatedAt = now + + // update ticket + if db.db.Model(&ticket).Where("uuid = ?", ticket.UUID).Updates(&ticket).RowsAffected == 0 { + return Tickets{}, errors.New("failed to update ticket") + } + + return *ticket, nil + } + + // create ticket and return error if it fails + if db.db.Create(&ticket).Error != nil { + return Tickets{}, db.db.Create(&ticket).Error + } + + return *ticket, nil +} + +func (db database) GetTicket(uuid string) (Tickets, error) { + ticket := Tickets{} + + results := db.db.Model(&Tickets{}).Where("uuid = ?", uuid).Find(&ticket) + + if results.Error != nil { + return Tickets{}, fmt.Errorf("failed to get ticket: %w", results.Error) + } + + if results.RowsAffected == 0 { + return Tickets{}, fmt.Errorf("failed to get ticket: %w", results.Error) + } + + return ticket, nil +} diff --git a/db/tickets_test.go b/db/tickets_test.go new file mode 100644 index 000000000..30e912b93 --- /dev/null +++ b/db/tickets_test.go @@ -0,0 +1,225 @@ +package db + +import ( + "testing" + "time" + + "github.com/google/uuid" +) + +func TestCreateOrEditTicket(t *testing.T) { + // test create or edit tickers + InitTestDB() + + // create person + now := time.Now() + + person := Person{ + Uuid: uuid.New().String(), + OwnerPubKey: "testfeaturepubkey", + OwnerAlias: "testfeaturealias", + Description: "testfeaturedescription", + Created: &now, + Updated: &now, + Deleted: false, + } + + workspace := Workspace{ + Uuid: uuid.New().String(), + Name: "Test tickets space", + Created: &now, + Updated: &now, + } + + workspaceFeatures := WorkspaceFeatures{ + Uuid: uuid.New().String(), + WorkspaceUuid: workspace.Uuid, + Name: "test", + Brief: "test brief", + Requirements: "Test requirements", + Architecture: "Test architecture", + Url: "Test url", + Priority: 1, + Created: &now, + Updated: &now, + CreatedBy: "test", + UpdatedBy: "test", + } + + featurePhase := FeaturePhase{ + Uuid: uuid.New().String(), + FeatureUuid: workspaceFeatures.Uuid, + Name: "test feature phase", + Priority: 1, + Created: &now, + Updated: &now, + } + + ticket := Tickets{ + UUID: uuid.New().String(), + FeatureUUID: workspaceFeatures.Uuid, + PhaseUUID: featurePhase.Uuid, + Name: "test ticket", + CreatedAt: now, + UpdatedAt: now, + } + + // create person + TestDB.CreateOrEditPerson(person) + + // create workspace + TestDB.CreateOrEditWorkspace(workspace) + + // create WorkspaceFeatures + TestDB.CreateOrEditFeature(workspaceFeatures) + + // create FeaturePhase + TestDB.CreateOrEditFeaturePhase(featurePhase) + + // test that an error is returned if the required fields are missing + t.Run("test that an error is returned if the required fields are missing", func(t *testing.T) { + ticket := Tickets{ + UUID: uuid.New().String(), + FeatureUUID: "", + PhaseUUID: "", + Name: "test ticket", + CreatedAt: now, + UpdatedAt: now, + } + + _, err := TestDB.CreateOrEditTicket(&ticket) + if err == nil { + t.Errorf("expected an error but got nil") + } + }) + + // test that an error is thrown if the FeatureUUID, and PhaseUUID does not exists + t.Run("test that an error is returned if the required fields are missing", func(t *testing.T) { + ticket := Tickets{ + UUID: uuid.New().String(), + FeatureUUID: "testfeatureuuid", + PhaseUUID: "testphaseuuid", + Name: "test ticket", + CreatedAt: now, + UpdatedAt: now, + } + + _, err := TestDB.CreateOrEditTicket(&ticket) + if err == nil { + t.Errorf("expected an error but got nil") + } + }) + + // shpuld create a ticket if all fields are provided + t.Run("should create a ticket if all fields are provided", func(t *testing.T) { + + _, err := TestDB.CreateOrEditTicket(&ticket) + if err != nil { + t.Errorf("expected no error but got %v", err) + } + }) +} + +func TestGetTicket(t *testing.T) { + InitTestDB() + + // create person + now := time.Now() + + person := Person{ + Uuid: uuid.New().String(), + OwnerPubKey: "testfeaturepubkey", + OwnerAlias: "testfeaturealias", + Description: "testfeaturedescription", + Created: &now, + Updated: &now, + Deleted: false, + } + + // create person + TestDB.CreateOrEditPerson(person) + + workspace := Workspace{ + Uuid: uuid.New().String(), + Name: "Test tickets space", + Created: &now, + Updated: &now, + } + + // create workspace + TestDB.CreateOrEditWorkspace(workspace) + + workspaceFeatures := WorkspaceFeatures{ + Uuid: uuid.New().String(), + WorkspaceUuid: workspace.Uuid, + Name: "test", + Brief: "test get brief", + Requirements: "Test get requirements", + Architecture: "Test get architecture", + Url: "Test get url", + Priority: 1, + Created: &now, + Updated: &now, + CreatedBy: "test", + UpdatedBy: "test", + } + + // create WorkspaceFeatures + TestDB.CreateOrEditFeature(workspaceFeatures) + + featurePhase := FeaturePhase{ + Uuid: uuid.New().String(), + FeatureUuid: workspaceFeatures.Uuid, + Name: "test get feature phase", + Priority: 1, + Created: &now, + Updated: &now, + } + + // create FeaturePhase + TestDB.CreateOrEditFeaturePhase(featurePhase) + + ticket := Tickets{ + UUID: uuid.New().String(), + FeatureUUID: workspaceFeatures.Uuid, + PhaseUUID: featurePhase.Uuid, + Name: "test get ticket", + CreatedAt: now, + UpdatedAt: now, + } + + // create ticket + TestDB.CreateOrEditTicket(&ticket) + + // test that an error is returned if the ticket does not exist + t.Run("test that an error is returned if the ticket does not exist", func(t *testing.T) { + _, err := TestDB.GetTicket(uuid.New().String()) + if err == nil { + t.Errorf("expected an error but got nil") + } + }) + + // should return a ticket if it exists + t.Run("should return a ticket if it exists", func(t *testing.T) { + result, err := TestDB.GetTicket(ticket.UUID) + if err != nil { + t.Errorf("expected no error but got %v", err) + } + + if result.UUID != ticket.UUID { + t.Errorf("expected %v but got %v", ticket.UUID, result.UUID) + } + + if result.FeatureUUID != ticket.FeatureUUID { + t.Errorf("expected %v but got %v", ticket.FeatureUUID, result.FeatureUUID) + } + + if result.PhaseUUID != ticket.PhaseUUID { + t.Errorf("expected %v but got %v", ticket.PhaseUUID, result.PhaseUUID) + } + + if result.Name != ticket.Name { + t.Errorf("expected %v but got %v", ticket.Name, result.Name) + } + }) +}