diff --git a/cypress/e2e/02_repositories.cy.ts b/cypress/e2e/02_repositories.cy.ts new file mode 100644 index 000000000..dba204270 --- /dev/null +++ b/cypress/e2e/02_repositories.cy.ts @@ -0,0 +1,40 @@ +import { User, HostName, Workspaces, Repositories } from '../support/objects/objects'; + + +describe('Create Repositories for Workspace', () => { + it('passes', () => { + cy.upsertlogin(User).then(value => { + for(let i = 0; i <= 1; i++) { + cy.request({ + method: 'POST', + url: `${HostName}/workspaces/repositories`, + headers: { 'x-jwt': `${value}` }, + body: Repositories[i] + }).its('body').then(body => { + expect(body).to.have.property('name').and.equal(Repositories[i].name.trim()); + expect(body).to.have.property('url').and.equal(Repositories[i].url.trim()); + }); + } + }) + }) +}) + + +describe('Check Repositories Values', () => { + it('passes', () => { + cy.upsertlogin(User).then(value => { + cy.request({ + method: 'GET', + url: `${HostName}/workspaces/repositories/` + Repositories[0].workspace_uuid, + headers: { 'x-jwt': `${ value }` }, + body: {} + }).then((resp) => { + expect(resp.status).to.eq(200) + expect(resp.body[0]).to.have.property('name', Repositories[0].name.trim()) + expect(resp.body[0]).to.have.property('url', Repositories[0].url.trim()) + expect(resp.body[1]).to.have.property('name', Repositories[1].name.trim()) + expect(resp.body[1]).to.have.property('url', Repositories[1].url.trim()) + }) + }) + }) +}) diff --git a/cypress/e2e/04_user_stories.cy.ts b/cypress/e2e/04_user_stories.cy.ts index 537a6764d..1321ce441 100644 --- a/cypress/e2e/04_user_stories.cy.ts +++ b/cypress/e2e/04_user_stories.cy.ts @@ -35,7 +35,7 @@ describe('Modify user story description', () => { }).its('body').then(body => { expect(body).to.have.property('uuid').and.equal(UserStories[i].uuid.trim()); expect(body).to.have.property('feature_uuid').and.equal(UserStories[i].feature_uuid.trim()); - expect(body).to.have.property('description').and.equal(UserStories[i].description.trim() + "_addtext"); + expect(body).to.have.property('description').and.equal(UserStories[i].description.trim() + " _addtext"); expect(body).to.have.property('priority').and.equal(UserStories[i].priority); }); } @@ -56,7 +56,7 @@ describe('Get user stories for feature', () => { for(let i = 0; i <= 5; i++) { expect(resp.body[i]).to.have.property('uuid').and.equal(UserStories[i].uuid.trim()); expect(resp.body[i]).to.have.property('feature_uuid').and.equal(UserStories[i].feature_uuid.trim()); - expect(resp.body[i]).to.have.property('description').and.equal(UserStories[i].description.trim() + "_addtext"); + expect(resp.body[i]).to.have.property('description').and.equal(UserStories[i].description.trim() + " _addtext"); expect(resp.body[i]).to.have.property('priority').and.equal(UserStories[i].priority); } }) @@ -71,19 +71,19 @@ describe('Get story by uuid', () => { cy.request({ method: 'GET', url: `${HostName}/features/${UserStories[0].feature_uuid}/story/${UserStories[i].uuid}`, - headers: { 'x-jwt': `${ value }` }, - body: {} + headers: { 'x-jwt': `${value}` }, + body: {} }).then((resp) => { - expect(resp.status).to.eq(200) - expect(resp.body[i]).to.have.property('uuid').and.equal(UserStories[i].uuid.trim()); - expect(resp.body[i]).to.have.property('feature_uuid').and.equal(UserStories[i].feature_uuid.trim()); - expect(resp.body[i]).to.have.property('description').and.equal(UserStories[i].description.trim() + "_addtext"); - expect(resp.body[i]).to.have.property('priority').and.equal(UserStories[i].priority); - }) + expect(resp.status).to.eq(200); + expect(resp.body).to.have.property('uuid').and.equal(UserStories[i].uuid.trim()); + expect(resp.body).to.have.property('feature_uuid').and.equal(UserStories[i].feature_uuid.trim()); + expect(resp.body).to.have.property('description').and.equal(UserStories[i].description.trim() + " _addtext"); + expect(resp.body).to.have.property('priority').and.equal(UserStories[i].priority); + }); } - }) - }) -}) + }); + }); +}); describe('Delete story by uuid', () => { it('passes', () => { @@ -104,10 +104,11 @@ describe('Check delete by uuid', () => { it('passes', () => { cy.upsertlogin(User).then(value => { cy.request({ - method: 'GET', + method: 'DELETE', url: `${HostName}/features/${UserStories[0].feature_uuid}/story/${UserStories[0].uuid}`, headers: { 'x-jwt': `${ value }` }, - body: {} + body: {}, + failOnStatusCode: false }).then((resp) => { expect(resp.status).to.eq(404); }) diff --git a/cypress/support/objects/objects.ts b/cypress/support/objects/objects.ts index ac5880304..453e055d8 100644 --- a/cypress/support/objects/objects.ts +++ b/cypress/support/objects/objects.ts @@ -63,7 +63,7 @@ export const Repositories = [ url: ' https://github.com/stakwork/sphinx-tribes-frontend ' }, { - uuid: 'com1t3gn1e4a4qu3tnlg', + uuid: 'com1t3gn1e4a4qu3thss', workspace_uuid: 'cohob00n1e4808utqel0', name: ' backend ', url: ' https://github.com/stakwork/sphinx-tribes ' diff --git a/db/config.go b/db/config.go index 5496e4b8f..bcd30286f 100644 --- a/db/config.go +++ b/db/config.go @@ -67,7 +67,9 @@ func InitDB() { db.AutoMigrate(&ConnectionCodes{}) db.AutoMigrate(&BountyRoles{}) db.AutoMigrate(&UserInvoiceData{}) + db.AutoMigrate(&WorkspaceRepositories{}) db.AutoMigrate(&WorkspaceFeatures{}) + db.AutoMigrate(&FeatureStory{}) DB.MigrateTablesWithOrgUuid() DB.MigrateOrganizationToWorkspace() diff --git a/db/features.go b/db/features.go index c978124be..aa7134d75 100644 --- a/db/features.go +++ b/db/features.go @@ -1,18 +1,50 @@ package db import ( + "errors" + "fmt" + "net/http" "strings" "time" + + "github.com/stakwork/sphinx-tribes/utils" ) -func (db database) GetFeaturesByWorkspaceUuid(uuid string) []WorkspaceFeatures { +func (db database) GetFeaturesByWorkspaceUuid(uuid string, r *http.Request) []WorkspaceFeatures { + offset, limit, sortBy, direction, _ := utils.GetPaginationParams(r) + + orderQuery := "" + limitQuery := "" + ms := []WorkspaceFeatures{} - db.db.Model(&WorkspaceFeatures{}).Where("workspace_uuid = ?", uuid).Order("Created").Find(&ms) + if sortBy != "" && direction != "" { + orderQuery = "ORDER BY " + sortBy + " " + direction + } else { + orderQuery = "ORDER BY created DESC" + } + + if limit > 1 { + limitQuery = fmt.Sprintf("LIMIT %d OFFSET %d", limit, offset) + } + + query := `SELECT * FROM public.workspace_features WHERE workspace_uuid = '` + uuid + `'` + + allQuery := query + " " + orderQuery + " " + limitQuery + + theQuery := db.db.Raw(allQuery) + + theQuery.Scan(&ms) return ms } +func (db database) GetWorkspaceFeaturesCount(uuid string) int64 { + var count int64 + db.db.Model(&WorkspaceFeatures{}).Where("workspace_uuid = ?", uuid).Count(&count) + return count +} + func (db database) GetFeatureByUuid(uuid string) WorkspaceFeatures { ms := WorkspaceFeatures{} @@ -35,7 +67,58 @@ func (db database) CreateOrEditFeature(m WorkspaceFeatures) (WorkspaceFeatures, db.db.Create(&m) } - db.db.Model(&WorkspaceFeatures{}).Where("uuid = ?", m.Uuid).Find(&m) - return m, nil } + +func (db database) CreateOrEditFeatureStory(story FeatureStory) (FeatureStory, error) { + story.Description = strings.TrimSpace(story.Description) + + now := time.Now() + story.Updated = &now + + existingStory := FeatureStory{} + result := db.db.Model(&FeatureStory{}).Where("uuid = ?", story.Uuid).First(&existingStory) + + if result.RowsAffected == 0 { + + story.Created = &now + db.db.Create(&story) + } else { + + db.db.Model(&FeatureStory{}).Where("uuid = ?", story.Uuid).Updates(story) + } + + db.db.Model(&FeatureStory{}).Where("uuid = ?", story.Uuid).Find(&story) + + return story, nil +} + +func (db database) GetFeatureStoriesByFeatureUuid(featureUuid string) ([]FeatureStory, error) { + var stories []FeatureStory + result := db.db.Where("feature_uuid = ?", featureUuid).Find(&stories) + if result.Error != nil { + return nil, result.Error + } + + for i := range stories { + stories[i].Description = strings.TrimSpace(stories[i].Description) + } + return stories, nil +} + +func (db database) GetFeatureStoryByUuid(featureUuid, storyUuid string) (FeatureStory, error) { + story := FeatureStory{} + result := db.db.Model(&FeatureStory{}).Where("feature_uuid = ? AND uuid = ?", featureUuid, storyUuid).First(&story) + if result.RowsAffected == 0 { + return story, errors.New("no story found") + } + return story, nil +} + +func (db database) DeleteFeatureStoryByUuid(featureUuid, storyUuid string) error { + result := db.db.Where("feature_uuid = ? AND uuid = ?", featureUuid, storyUuid).Delete(&FeatureStory{}) + if result.RowsAffected == 0 { + return errors.New("no story found to delete") + } + return nil +} diff --git a/db/interface.go b/db/interface.go index ff3a4479e..3e8f0da72 100644 --- a/db/interface.go +++ b/db/interface.go @@ -140,7 +140,14 @@ type Database interface { PersonUniqueNameFromName(name string) (string, error) ProcessAlerts(p Person) UserHasAccess(pubKeyFromAuth string, uuid string, role string) bool + CreateWorkspaceRepository(m WorkspaceRepositories) (WorkspaceRepositories, error) + GetWorkspaceRepositorByWorkspaceUuid(uuid string) []WorkspaceRepositories CreateOrEditFeature(m WorkspaceFeatures) (WorkspaceFeatures, error) - GetFeaturesByWorkspaceUuid(uuid string) []WorkspaceFeatures + GetFeaturesByWorkspaceUuid(uuid string, r *http.Request) []WorkspaceFeatures + GetWorkspaceFeaturesCount(uuid string) int64 GetFeatureByUuid(uuid string) WorkspaceFeatures + CreateOrEditFeatureStory(story FeatureStory) (FeatureStory, error) + GetFeatureStoriesByFeatureUuid(featureUuid string) ([]FeatureStory, error) + GetFeatureStoryByUuid(featureUuid, storyUuid string) (FeatureStory, error) + DeleteFeatureStoryByUuid(featureUuid, storyUuid string) error } diff --git a/db/structs.go b/db/structs.go index ddae676fc..82d69a569 100644 --- a/db/structs.go +++ b/db/structs.go @@ -551,11 +551,23 @@ type WorkspaceUsersData struct { Person } +type WorkspaceRepositories struct { + ID uint `json:"id"` + Uuid string `gorm:"not null" json:"uuid"` + WorkspaceUuid string `gorm:"not null" json:"workspace_uuid"` + Name string `gorm:"not null" json:"name"` + Url string `json:"url"` + Created *time.Time `json:"created"` + Updated *time.Time `json:"updated"` + CreatedBy string `json:"created_by"` + UpdatedBy string `json:"updated_by"` +} + type WorkspaceFeatures struct { ID uint `json:"id"` - Uuid string `json:"uuid"` - WorkspaceUuid string `json:"workspace_uuid"` - Name string `json:"name"` + Uuid string `gorm:"not null" json:"uuid"` + WorkspaceUuid string `gorm:"not null" json:"workspace_uuid"` + Name string `gorm:"not null" json:"name"` Brief string `json:"brief"` Requirements string `json:"requirements"` Architecture string `json:"architecture"` @@ -656,6 +668,18 @@ type BudgetHistory struct { PaymentType PaymentType `json:"payment_type"` } +type FeatureStory struct { + ID uint `json:"id"` + Uuid string `json:"uuid"` + FeatureUuid string `json:"feature_uuid"` + Description string `json:"description"` + Priority int `json:"priority"` + Created *time.Time `json:"created"` + Updated *time.Time `json:"updated"` + CreatedBy string `json:"created_by"` + UpdatedBy string `json:"updated_by"` +} + type BudgetHistoryData struct { BudgetHistory SenderName string `json:"sender_name"` diff --git a/db/workspaces.go b/db/workspaces.go index 5a7799af3..f11c298c8 100644 --- a/db/workspaces.go +++ b/db/workspaces.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "net/http" + "strings" "time" "github.com/stakwork/sphinx-tribes/utils" @@ -57,6 +58,29 @@ func (db database) CreateOrEditWorkspace(m Workspace) (Workspace, error) { return m, nil } +func (db database) CreateWorkspaceRepository(m WorkspaceRepositories) (WorkspaceRepositories, error) { + m.Name = strings.TrimSpace(m.Name) + m.Url = strings.TrimSpace(m.Url) + + now := time.Now() + m.Updated = &now + + if db.db.Model(&m).Where("uuid = ?", m.Uuid).Updates(&m).RowsAffected == 0 { + m.Created = &now + db.db.Create(&m) + } + + return m, nil +} + +func (db database) GetWorkspaceRepositorByWorkspaceUuid(uuid string) []WorkspaceRepositories { + ms := []WorkspaceRepositories{} + + db.db.Model(&WorkspaceRepositories{}).Where("workspace_uuid = ?", uuid).Order("Created").Find(&ms) + + return ms +} + func (db database) GetWorkspaceUsers(uuid string) ([]WorkspaceUsersData, error) { ms := []WorkspaceUsersData{} diff --git a/handlers/features.go b/handlers/features.go index 9c4f9cd68..c798d476c 100644 --- a/handlers/features.go +++ b/handlers/features.go @@ -3,12 +3,12 @@ package handlers import ( "encoding/json" "fmt" - "io" - "net/http" - "github.com/go-chi/chi" + "github.com/rs/xid" "github.com/stakwork/sphinx-tribes/auth" "github.com/stakwork/sphinx-tribes/db" + "io" + "net/http" ) type featureHandler struct { @@ -43,6 +43,12 @@ func (oh *featureHandler) CreateOrEditFeatures(w http.ResponseWriter, r *http.Re features.CreatedBy = pubKeyFromAuth + if features.Uuid == "" { + features.Uuid = xid.New().String() + } else { + features.UpdatedBy = pubKeyFromAuth + } + // Validate struct data err = db.Validate.Struct(features) if err != nil { @@ -72,7 +78,23 @@ func (oh *featureHandler) GetFeaturesByWorkspaceUuid(w http.ResponseWriter, r *h } uuid := chi.URLParam(r, "uuid") - workspaceFeatures := oh.db.GetFeaturesByWorkspaceUuid(uuid) + workspaceFeatures := oh.db.GetFeaturesByWorkspaceUuid(uuid, r) + + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(workspaceFeatures) +} + +func (oh *featureHandler) GetWorkspaceFeaturesCount(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + pubKeyFromAuth, _ := ctx.Value(auth.ContextKey).(string) + if pubKeyFromAuth == "" { + fmt.Println("no pubkey from auth") + w.WriteHeader(http.StatusUnauthorized) + return + } + + uuid := chi.URLParam(r, "uuid") + workspaceFeatures := oh.db.GetWorkspaceFeaturesCount(uuid) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(workspaceFeatures) @@ -93,3 +115,84 @@ func (oh *featureHandler) GetFeatureByUuid(w http.ResponseWriter, r *http.Reques w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(workspaceFeature) } + +func (oh *featureHandler) CreateOrEditStory(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + pubKeyFromAuth, _ := ctx.Value(auth.ContextKey).(string) + if pubKeyFromAuth == "" { + fmt.Println("no pubkey from auth") + w.WriteHeader(http.StatusUnauthorized) + return + } + + newStory := db.FeatureStory{} + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(&newStory) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + fmt.Fprintf(w, "Error decoding request body: %v", err) + return + } + + if newStory.Uuid == "" { + newStory.Uuid = xid.New().String() + } + + existingStory, _ := oh.db.GetFeatureStoryByUuid(newStory.FeatureUuid, newStory.Uuid) + + if existingStory.CreatedBy == "" { + newStory.CreatedBy = pubKeyFromAuth + } + + newStory.UpdatedBy = pubKeyFromAuth + + story, err := oh.db.CreateOrEditFeatureStory(newStory) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Error creating feature story: %v", err) + return + } + + w.WriteHeader(http.StatusCreated) + json.NewEncoder(w).Encode(story) +} + +func (oh *featureHandler) GetStoriesByFeatureUuid(w http.ResponseWriter, r *http.Request) { + featureUuid := chi.URLParam(r, "feature_uuid") + stories, err := oh.db.GetFeatureStoriesByFeatureUuid(featureUuid) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(stories) +} + +func (oh *featureHandler) GetStoryByUuid(w http.ResponseWriter, r *http.Request) { + featureUuid := chi.URLParam(r, "feature_uuid") + storyUuid := chi.URLParam(r, "story_uuid") + + story, err := oh.db.GetFeatureStoryByUuid(featureUuid, storyUuid) + if err != nil { + w.WriteHeader(http.StatusNotFound) + return + } + + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(story) +} +func (oh *featureHandler) DeleteStory(w http.ResponseWriter, r *http.Request) { + featureUuid := chi.URLParam(r, "feature_uuid") + storyUuid := chi.URLParam(r, "story_uuid") + + err := oh.db.DeleteFeatureStoryByUuid(featureUuid, storyUuid) + if err != nil { + w.WriteHeader(http.StatusNotFound) + json.NewEncoder(w).Encode(map[string]string{"error": err.Error()}) + return + } + + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(map[string]string{"message": "Story deleted successfully"}) +} diff --git a/handlers/workspaces.go b/handlers/workspaces.go index bcd365154..5ed2f09e6 100644 --- a/handlers/workspaces.go +++ b/handlers/workspaces.go @@ -126,19 +126,6 @@ func (oh *workspaceHandler) CreateOrEditWorkspace(w http.ResponseWriter, r *http } workspace.Name = name } - } else { - // if workspace.ID == 0 { - // // can't create that already exists - // fmt.Println("can't create existing organization") - // w.WriteHeader(http.StatusUnauthorized) - // return - // } - - // if workspace.ID != existing.ID { // can't edit someone else's - // fmt.Println("cant edit another organization") - // w.WriteHeader(http.StatusUnauthorized) - // return - // } } p, err := oh.db.CreateOrEditWorkspace(workspace) @@ -795,3 +782,66 @@ func (oh *workspaceHandler) UpdateWorkspace(w http.ResponseWriter, r *http.Reque w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(p) } + +func (oh *workspaceHandler) CreateWorkspaceRepository(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + pubKeyFromAuth, _ := ctx.Value(auth.ContextKey).(string) + if pubKeyFromAuth == "" { + fmt.Println("no pubkey from auth") + w.WriteHeader(http.StatusUnauthorized) + return + } + + workspaceRepo := db.WorkspaceRepositories{} + body, _ := io.ReadAll(r.Body) + r.Body.Close() + err := json.Unmarshal(body, &workspaceRepo) + + if err != nil { + fmt.Println(err) + w.WriteHeader(http.StatusNotAcceptable) + return + } + + workspaceRepo.CreatedBy = pubKeyFromAuth + + if workspaceRepo.Uuid == "" { + workspaceRepo.Uuid = xid.New().String() + } else { + workspaceRepo.UpdatedBy = pubKeyFromAuth + } + + // Validate struct data + err = db.Validate.Struct(workspaceRepo) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + msg := fmt.Sprintf("Error: did not pass validation test : %s", err) + json.NewEncoder(w).Encode(msg) + return + } + + p, err := oh.db.CreateWorkspaceRepository(workspaceRepo) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(p) +} + +func (oh *workspaceHandler) GetWorkspaceRepositorByWorkspaceUuid(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + pubKeyFromAuth, _ := ctx.Value(auth.ContextKey).(string) + if pubKeyFromAuth == "" { + fmt.Println("no pubkey from auth") + w.WriteHeader(http.StatusUnauthorized) + return + } + + uuid := chi.URLParam(r, "uuid") + workspaceFeatures := oh.db.GetWorkspaceRepositorByWorkspaceUuid(uuid) + + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(workspaceFeatures) +} diff --git a/mocks/Database.go b/mocks/Database.go index f3a3587d7..b85f21c74 100644 --- a/mocks/Database.go +++ b/mocks/Database.go @@ -1250,6 +1250,62 @@ func (_c *Database_CreateWorkspaceBudget_Call) RunAndReturn(run func(db.NewBount return _c } +// CreateWorkspaceRepository provides a mock function with given fields: m +func (_m *Database) CreateWorkspaceRepository(m db.WorkspaceRepositories) (db.WorkspaceRepositories, error) { + ret := _m.Called(m) + + if len(ret) == 0 { + panic("no return value specified for CreateWorkspaceRepository") + } + + var r0 db.WorkspaceRepositories + var r1 error + if rf, ok := ret.Get(0).(func(db.WorkspaceRepositories) (db.WorkspaceRepositories, error)); ok { + return rf(m) + } + if rf, ok := ret.Get(0).(func(db.WorkspaceRepositories) db.WorkspaceRepositories); ok { + r0 = rf(m) + } else { + r0 = ret.Get(0).(db.WorkspaceRepositories) + } + + if rf, ok := ret.Get(1).(func(db.WorkspaceRepositories) error); ok { + r1 = rf(m) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Database_CreateWorkspaceRepository_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateWorkspaceRepository' +type Database_CreateWorkspaceRepository_Call struct { + *mock.Call +} + +// CreateWorkspaceRepository is a helper method to define mock.On call +// - m db.WorkspaceRepositories +func (_e *Database_Expecter) CreateWorkspaceRepository(m interface{}) *Database_CreateWorkspaceRepository_Call { + return &Database_CreateWorkspaceRepository_Call{Call: _e.mock.On("CreateWorkspaceRepository", m)} +} + +func (_c *Database_CreateWorkspaceRepository_Call) Run(run func(m db.WorkspaceRepositories)) *Database_CreateWorkspaceRepository_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(db.WorkspaceRepositories)) + }) + return _c +} + +func (_c *Database_CreateWorkspaceRepository_Call) Return(_a0 db.WorkspaceRepositories, _a1 error) *Database_CreateWorkspaceRepository_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Database_CreateWorkspaceRepository_Call) RunAndReturn(run func(db.WorkspaceRepositories) (db.WorkspaceRepositories, error)) *Database_CreateWorkspaceRepository_Call { + _c.Call.Return(run) + return _c +} + // CreateWorkspaceUser provides a mock function with given fields: orgUser func (_m *Database) CreateWorkspaceUser(orgUser db.WorkspaceUsers) db.WorkspaceUsers { ret := _m.Called(orgUser) @@ -2625,17 +2681,17 @@ func (_c *Database_GetFeatureByUuid_Call) RunAndReturn(run func(string) db.Works return _c } -// GetFeaturesByWorkspaceUuid provides a mock function with given fields: uuid -func (_m *Database) GetFeaturesByWorkspaceUuid(uuid string) []db.WorkspaceFeatures { - ret := _m.Called(uuid) +// GetFeaturesByWorkspaceUuid provides a mock function with given fields: uuid, r +func (_m *Database) GetFeaturesByWorkspaceUuid(uuid string, r *http.Request) []db.WorkspaceFeatures { + ret := _m.Called(uuid, r) if len(ret) == 0 { panic("no return value specified for GetFeaturesByWorkspaceUuid") } var r0 []db.WorkspaceFeatures - if rf, ok := ret.Get(0).(func(string) []db.WorkspaceFeatures); ok { - r0 = rf(uuid) + if rf, ok := ret.Get(0).(func(string, *http.Request) []db.WorkspaceFeatures); ok { + r0 = rf(uuid, r) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]db.WorkspaceFeatures) @@ -2652,13 +2708,14 @@ type Database_GetFeaturesByWorkspaceUuid_Call struct { // GetFeaturesByWorkspaceUuid is a helper method to define mock.On call // - uuid string -func (_e *Database_Expecter) GetFeaturesByWorkspaceUuid(uuid interface{}) *Database_GetFeaturesByWorkspaceUuid_Call { - return &Database_GetFeaturesByWorkspaceUuid_Call{Call: _e.mock.On("GetFeaturesByWorkspaceUuid", uuid)} +// - r *http.Request +func (_e *Database_Expecter) GetFeaturesByWorkspaceUuid(uuid interface{}, r interface{}) *Database_GetFeaturesByWorkspaceUuid_Call { + return &Database_GetFeaturesByWorkspaceUuid_Call{Call: _e.mock.On("GetFeaturesByWorkspaceUuid", uuid, r)} } -func (_c *Database_GetFeaturesByWorkspaceUuid_Call) Run(run func(uuid string)) *Database_GetFeaturesByWorkspaceUuid_Call { +func (_c *Database_GetFeaturesByWorkspaceUuid_Call) Run(run func(uuid string, r *http.Request)) *Database_GetFeaturesByWorkspaceUuid_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(string), args[1].(*http.Request)) }) return _c } @@ -2668,7 +2725,7 @@ func (_c *Database_GetFeaturesByWorkspaceUuid_Call) Return(_a0 []db.WorkspaceFea return _c } -func (_c *Database_GetFeaturesByWorkspaceUuid_Call) RunAndReturn(run func(string) []db.WorkspaceFeatures) *Database_GetFeaturesByWorkspaceUuid_Call { +func (_c *Database_GetFeaturesByWorkspaceUuid_Call) RunAndReturn(run func(string, *http.Request) []db.WorkspaceFeatures) *Database_GetFeaturesByWorkspaceUuid_Call { _c.Call.Return(run) return _c } @@ -4804,6 +4861,52 @@ func (_c *Database_GetWorkspaceByUuid_Call) RunAndReturn(run func(string) db.Wor return _c } +// GetWorkspaceFeaturesCount provides a mock function with given fields: uuid +func (_m *Database) GetWorkspaceFeaturesCount(uuid string) int64 { + ret := _m.Called(uuid) + + if len(ret) == 0 { + panic("no return value specified for GetWorkspaceFeaturesCount") + } + + var r0 int64 + if rf, ok := ret.Get(0).(func(string) int64); ok { + r0 = rf(uuid) + } else { + r0 = ret.Get(0).(int64) + } + + return r0 +} + +// Database_GetWorkspaceFeaturesCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetWorkspaceFeaturesCount' +type Database_GetWorkspaceFeaturesCount_Call struct { + *mock.Call +} + +// GetWorkspaceFeaturesCount is a helper method to define mock.On call +// - uuid string +func (_e *Database_Expecter) GetWorkspaceFeaturesCount(uuid interface{}) *Database_GetWorkspaceFeaturesCount_Call { + return &Database_GetWorkspaceFeaturesCount_Call{Call: _e.mock.On("GetWorkspaceFeaturesCount", uuid)} +} + +func (_c *Database_GetWorkspaceFeaturesCount_Call) Run(run func(uuid string)) *Database_GetWorkspaceFeaturesCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *Database_GetWorkspaceFeaturesCount_Call) Return(_a0 int64) *Database_GetWorkspaceFeaturesCount_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Database_GetWorkspaceFeaturesCount_Call) RunAndReturn(run func(string) int64) *Database_GetWorkspaceFeaturesCount_Call { + _c.Call.Return(run) + return _c +} + // GetWorkspaceInvoices provides a mock function with given fields: workspace_uuid func (_m *Database) GetWorkspaceInvoices(workspace_uuid string) []db.NewInvoiceList { ret := _m.Called(workspace_uuid) @@ -4898,6 +5001,54 @@ func (_c *Database_GetWorkspaceInvoicesCount_Call) RunAndReturn(run func(string) return _c } +// GetWorkspaceRepositorByWorkspaceUuid provides a mock function with given fields: uuid +func (_m *Database) GetWorkspaceRepositorByWorkspaceUuid(uuid string) []db.WorkspaceRepositories { + ret := _m.Called(uuid) + + if len(ret) == 0 { + panic("no return value specified for GetWorkspaceRepositorByWorkspaceUuid") + } + + var r0 []db.WorkspaceRepositories + if rf, ok := ret.Get(0).(func(string) []db.WorkspaceRepositories); ok { + r0 = rf(uuid) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]db.WorkspaceRepositories) + } + } + + return r0 +} + +// Database_GetWorkspaceRepositorByWorkspaceUuid_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetWorkspaceRepositorByWorkspaceUuid' +type Database_GetWorkspaceRepositorByWorkspaceUuid_Call struct { + *mock.Call +} + +// GetWorkspaceRepositorByWorkspaceUuid is a helper method to define mock.On call +// - uuid string +func (_e *Database_Expecter) GetWorkspaceRepositorByWorkspaceUuid(uuid interface{}) *Database_GetWorkspaceRepositorByWorkspaceUuid_Call { + return &Database_GetWorkspaceRepositorByWorkspaceUuid_Call{Call: _e.mock.On("GetWorkspaceRepositorByWorkspaceUuid", uuid)} +} + +func (_c *Database_GetWorkspaceRepositorByWorkspaceUuid_Call) Run(run func(uuid string)) *Database_GetWorkspaceRepositorByWorkspaceUuid_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *Database_GetWorkspaceRepositorByWorkspaceUuid_Call) Return(_a0 []db.WorkspaceRepositories) *Database_GetWorkspaceRepositorByWorkspaceUuid_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Database_GetWorkspaceRepositorByWorkspaceUuid_Call) RunAndReturn(run func(string) []db.WorkspaceRepositories) *Database_GetWorkspaceRepositorByWorkspaceUuid_Call { + _c.Call.Return(run) + return _c +} + // GetWorkspaceStatusBudget provides a mock function with given fields: workspace_uuid func (_m *Database) GetWorkspaceStatusBudget(workspace_uuid string) db.StatusBudget { ret := _m.Called(workspace_uuid) @@ -6660,3 +6811,78 @@ func NewDatabase(t interface { return mock } + +func (_m *Database) CreateOrEditFeatureStory(story db.FeatureStory) (db.FeatureStory, error) { + ret := _m.Called(story) + + var r0 db.FeatureStory + var r1 error + if rf, ok := ret.Get(0).(func(db.FeatureStory) db.FeatureStory); ok { + r0 = rf(story) + } else { + r0 = ret.Get(0).(db.FeatureStory) + } + + if rf, ok := ret.Get(1).(func(db.FeatureStory) error); ok { + r1 = rf(story) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +func (_m *Database) GetFeatureStoriesByFeatureUuid(featureUuid string) ([]db.FeatureStory, error) { + ret := _m.Called(featureUuid) + + var r0 []db.FeatureStory + var r1 error + if rf, ok := ret.Get(0).(func(string) []db.FeatureStory); ok { + r0 = rf(featureUuid) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]db.FeatureStory) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(featureUuid) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +func (_m *Database) GetFeatureStoryByUuid(featureUuid, storyUuid string) (db.FeatureStory, error) { + ret := _m.Called(featureUuid, storyUuid) + + var r0 db.FeatureStory + var r1 error + if rf, ok := ret.Get(0).(func(string, string) db.FeatureStory); ok { + r0 = rf(featureUuid, storyUuid) + } else { + r0 = ret.Get(0).(db.FeatureStory) + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(featureUuid, storyUuid) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +func (_m *Database) DeleteFeatureStoryByUuid(featureUuid string, storyUuid string) error { + ret := _m.Called(featureUuid, storyUuid) + + var r0 error + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(featureUuid, storyUuid) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/routes/features.go b/routes/features.go index 0b2449399..2ee9adf8e 100644 --- a/routes/features.go +++ b/routes/features.go @@ -16,6 +16,11 @@ func FeatureRoutes() chi.Router { r.Post("/", featureHandlers.CreateOrEditFeatures) r.Get("/forworkspace/{uuid}", featureHandlers.GetFeaturesByWorkspaceUuid) r.Get("/{uuid}", featureHandlers.GetFeatureByUuid) + r.Get("/workspace/count/{uuid}", featureHandlers.GetWorkspaceFeaturesCount) + r.Post("/story", featureHandlers.CreateOrEditStory) + r.Get("/{feature_uuid}/story", featureHandlers.GetStoriesByFeatureUuid) + r.Get("/{feature_uuid}/story/{story_uuid}", featureHandlers.GetStoryByUuid) + r.Delete("/{feature_uuid}/story/{story_uuid}", featureHandlers.DeleteStory) }) return r } diff --git a/routes/workspaces.go b/routes/workspaces.go index d79a457bd..d02c6e956 100644 --- a/routes/workspaces.go +++ b/routes/workspaces.go @@ -42,6 +42,9 @@ func WorkspaceRoutes() chi.Router { r.Post("/mission", workspaceHandlers.UpdateWorkspace) r.Post("/tactics", workspaceHandlers.UpdateWorkspace) r.Post("/schematicurl", workspaceHandlers.UpdateWorkspace) + + r.Post("/repositories", workspaceHandlers.CreateWorkspaceRepository) + r.Get("/repositories/{uuid}", workspaceHandlers.GetWorkspaceRepositorByWorkspaceUuid) }) return r }