Skip to content

Commit

Permalink
Merge pull request #1648 from stakwork/feature-add-phases
Browse files Browse the repository at this point in the history
Feature add phases
  • Loading branch information
elraphty authored May 16, 2024
2 parents 5d9a2cc + 0ef119d commit 4df9d02
Show file tree
Hide file tree
Showing 10 changed files with 461 additions and 7 deletions.
116 changes: 116 additions & 0 deletions cypress/e2e/06_phases.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { User, HostName, UserStories, Phases } from '../support/objects/objects';

describe('Create Phases for Feature', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features/phase`,
headers: { 'x-jwt': `${value}` },
body: Phases[i]
}).its('body').then(body => {
expect(body).to.have.property('uuid').and.equal(Phases[i].uuid.trim());
expect(body).to.have.property('feature_uuid').and.equal(Phases[i].feature_uuid.trim());
expect(body).to.have.property('name').and.equal(Phases[i].name.trim());
expect(body).to.have.property('priority').and.equal(Phases[i].priority);
});
}
})
})
})

describe('Modify phases name', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features/phase`,
headers: { 'x-jwt': `${value}` },
body: {
uuid: Phases[i].uuid,
name: Phases[i].name + "_addtext"
}
}).its('body').then(body => {
expect(body).to.have.property('uuid').and.equal(Phases[i].uuid.trim());
expect(body).to.have.property('feature_uuid').and.equal(Phases[i].feature_uuid.trim());
expect(body).to.have.property('name').and.equal(Phases[i].name.trim() + "_addtext");
expect(body).to.have.property('priority').and.equal(Phases[i].priority);
});
}
})
})
})

describe('Get phases for feature', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
cy.request({
method: 'GET',
url: `${HostName}/features/${Phases[0].feature_uuid}/phase`,
headers: { 'x-jwt': `${ value }` },
body: {}
}).then((resp) => {
expect(resp.status).to.eq(200)
for(let i = 0; i <= 2; i++) {
expect(resp.body[i]).to.have.property('uuid').and.equal(Phases[i].uuid.trim());
expect(resp.body[i]).to.have.property('feature_uuid').and.equal(Phases[i].feature_uuid.trim());
expect(resp.body[i]).to.have.property('name').and.equal(Phases[i].name.trim() + "_addtext");
expect(resp.body[i]).to.have.property('priority').and.equal(Phases[i].priority);
}
})
})
})
})

describe('Get phase by uuid', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'GET',
url: `${HostName}/features/${Phases[0].feature_uuid}/phase/${Phases[i].uuid}`,
headers: { 'x-jwt': `${ value }` },
body: {}
}).then((resp) => {
expect(resp.status).to.eq(200)
expect(resp.body[i]).to.have.property('uuid').and.equal(Phases[i].uuid.trim());
expect(resp.body[i]).to.have.property('feature_uuid').and.equal(Phases[i].feature_uuid.trim());
expect(resp.body[i]).to.have.property('name').and.equal(Phases[i].name.trim() + "_addtext");
expect(resp.body[i]).to.have.property('priority').and.equal(Phases[i].priority);
})
}
})
})
})

describe('Delete phase by uuid', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
cy.request({
method: 'DELETE',
url: `${HostName}/features/${Phases[0].feature_uuid}/phase/${Phases[0].uuid}`,
headers: { 'x-jwt': `${ value }` },
body: {}
}).then((resp) => {
expect(resp.status).to.eq(200)
})
})
})
})

describe('Check delete by uuid', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
cy.request({
method: 'GET',
url: `${HostName}/features/${Phases[0].feature_uuid}/phase/${Phases[0].uuid}`,
headers: { 'x-jwt': `${ value }` },
body: {}
}).then((resp) => {
expect(resp.status).to.eq(404);
})
})
})
})
120 changes: 120 additions & 0 deletions cypress/e2e/06_phases.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { User, HostName, UserStories, Phases } from '../support/objects/objects';

describe('Create Phases for Feature', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features/phase`,
headers: { 'x-jwt': `${value}` },
body: Phases[i]
}).its('body').then(body => {
expect(body).to.have.property('uuid').and.equal(Phases[i].uuid.trim());
expect(body).to.have.property('feature_uuid').and.equal(Phases[i].feature_uuid.trim());
expect(body).to.have.property('name').and.equal(Phases[i].name.trim());
expect(body).to.have.property('priority').and.equal(Phases[i].priority);
});
}
})
})
})

describe('Modify phases name', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features/phase`,
headers: { 'x-jwt': `${value}` },
body: {
uuid: Phases[i].uuid,
name: Phases[i].name + "_addtext"
}
}).its('body').then(body => {
expect(body).to.have.property('uuid').and.equal(Phases[i].uuid.trim());
expect(body).to.have.property('feature_uuid').and.equal(Phases[i].feature_uuid.trim());
expect(body).to.have.property('name').and.equal(Phases[i].name.trim() + " _addtext");
expect(body).to.have.property('priority').and.equal(Phases[i].priority);
});
}
})
})
})

describe('Get phases for feature', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
cy.request({
method: 'GET',
url: `${HostName}/features/${Phases[0].feature_uuid}/phase`,
headers: { 'x-jwt': `${ value }` },
body: {}
}).then((resp) => {
expect(resp.status).to.eq(200)

resp.body.forEach((phase, index) => {
// Directly use index to compare with the expected phase in the same order
const expectedPhase = Phases[index];
expect(phase.uuid).to.equal(expectedPhase.uuid.trim());
expect(phase.feature_uuid).to.equal(expectedPhase.feature_uuid.trim());
expect(phase.name).to.equal(expectedPhase.name.trim() + " _addtext");
expect(phase.priority).to.equal(expectedPhase.priority);
});
})
})
})
})

describe('Get phase by uuid', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
cy.request({
method: 'GET',
url: `${HostName}/features/${Phases[0].feature_uuid}/phase/${Phases[i].uuid}`,
headers: { 'x-jwt': `${ value }` },
body: {}
}).then((resp) => {
expect(resp.status).to.eq(200)
expect(resp.body).to.have.property('uuid').and.equal(Phases[i].uuid.trim());
expect(resp.body).to.have.property('feature_uuid').and.equal(Phases[i].feature_uuid.trim());
expect(resp.body).to.have.property('name').and.equal(Phases[i].name.trim() + " _addtext");
expect(resp.body).to.have.property('priority').and.equal(Phases[i].priority);
})
}
})
})
})

describe('Delete phase by uuid', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
cy.request({
method: 'DELETE',
url: `${HostName}/features/${Phases[0].feature_uuid}/phase/${Phases[0].uuid}`,
headers: { 'x-jwt': `${ value }` },
body: {}
}).then((resp) => {
expect(resp.status).to.eq(200)
})
})
})
})

describe('Check delete by uuid', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
cy.request({
method: 'GET',
url: `${HostName}/features/${Phases[0].feature_uuid}/phase/${Phases[0].uuid}`,
headers: { 'x-jwt': `${ value }` },
body: {},
failOnStatusCode: false
}).then((resp) => {
expect(resp.status).to.eq(404);
})
})
})
})
6 changes: 3 additions & 3 deletions cypress/support/objects/objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export const UserStories = [
];

export const Phases = [
{ uuid: 'com1msgn1e4a0ts5kls0', feature_uuid: 'com1kson1e49th88dbg0', name: ' MVP ' },
{ uuid: 'com1mvgn1e4a1879uiv0', feature_uuid: 'com1kson1e49th88dbg0', name: ' Phase 2 ' },
{ uuid: 'com1n2gn1e4a1i8p60p0', feature_uuid: 'com1kson1e49th88dbg0', name: ' Phase 3 ' },
{ uuid: 'com1msgn1e4a0ts5kls0', feature_uuid: 'com1kson1e49th88dbg0', name: ' MVP ', priority: 0 },
{ uuid: 'com1mvgn1e4a1879uiv0', feature_uuid: 'com1kson1e49th88dbg0', name: ' Phase 2 ', priority: 1 },
{ uuid: 'com1n2gn1e4a1i8p60p0', feature_uuid: 'com1kson1e49th88dbg0', name: ' Phase 3 ', priority: 2 },
];
1 change: 1 addition & 0 deletions db/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func InitDB() {
db.AutoMigrate(&UserInvoiceData{})
db.AutoMigrate(&WorkspaceRepositories{})
db.AutoMigrate(&WorkspaceFeatures{})
db.AutoMigrate(&FeaturePhase{})

DB.MigrateTablesWithOrgUuid()
DB.MigrateOrganizationToWorkspace()
Expand Down
47 changes: 47 additions & 0 deletions db/features.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package db

import (
"errors"
"fmt"
"net/http"
"strings"
Expand Down Expand Up @@ -68,3 +69,49 @@ func (db database) CreateOrEditFeature(m WorkspaceFeatures) (WorkspaceFeatures,

return m, nil
}

func (db database) CreateOrEditFeaturePhase(phase FeaturePhase) (FeaturePhase, error) {
phase.Name = strings.TrimSpace(phase.Name)

now := time.Now()
phase.Updated = &now

existingPhase := FeaturePhase{}
result := db.db.Model(&FeaturePhase{}).Where("uuid = ?", phase.Uuid).First(&existingPhase)

if result.RowsAffected == 0 {

phase.Created = &now
db.db.Create(&phase)
} else {

db.db.Model(&FeaturePhase{}).Where("uuid = ?", phase.Uuid).Updates(phase)
}

db.db.Model(&FeaturePhase{}).Where("uuid = ?", phase.Uuid).Find(&phase)

return phase, nil
}

func (db database) GetPhasesByFeatureUuid(featureUuid string) []FeaturePhase {
phases := []FeaturePhase{}
db.db.Model(&FeaturePhase{}).Where("feature_uuid = ?", featureUuid).Order("Created ASC").Find(&phases)
return phases
}

func (db database) GetFeaturePhaseByUuid(featureUuid, phaseUuid string) (FeaturePhase, error) {
phase := FeaturePhase{}
result := db.db.Model(&FeaturePhase{}).Where("feature_uuid = ? AND uuid = ?", featureUuid, phaseUuid).First(&phase)
if result.RowsAffected == 0 {
return phase, errors.New("no phase found")
}
return phase, nil
}

func (db database) DeleteFeaturePhase(featureUuid, phaseUuid string) error {
result := db.db.Where("feature_uuid = ? AND uuid = ?", featureUuid, phaseUuid).Delete(&FeaturePhase{})
if result.RowsAffected == 0 {
return errors.New("no phase found to delete")
}
return nil
}
4 changes: 4 additions & 0 deletions db/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,8 @@ type Database interface {
GetFeaturesByWorkspaceUuid(uuid string, r *http.Request) []WorkspaceFeatures
GetWorkspaceFeaturesCount(uuid string) int64
GetFeatureByUuid(uuid string) WorkspaceFeatures
CreateOrEditFeaturePhase(phase FeaturePhase) (FeaturePhase, error)
GetPhasesByFeatureUuid(featureUuid string) []FeaturePhase
GetFeaturePhaseByUuid(featureUuid, phaseUuid string) (FeaturePhase, error)
DeleteFeaturePhase(featureUuid, phaseUuid string) error
}
11 changes: 11 additions & 0 deletions db/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,17 @@ type WorkspaceFeatures struct {
UpdatedBy string `json:"updated_by"`
}

type FeaturePhase struct {
Uuid string `json:"uuid" gorm:"primary_key"`
FeatureUuid string `json:"feature_uuid"`
Name string `json:"name"`
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 BountyRoles struct {
Name string `json:"name"`
}
Expand Down
Loading

0 comments on commit 4df9d02

Please sign in to comment.