Skip to content

Commit

Permalink
Merge pull request #1665 from Vayras/feature-add-bounty-to-phase
Browse files Browse the repository at this point in the history
Feature add bounty to phase
  • Loading branch information
elraphty authored May 24, 2024
2 parents d357644 + a1c2c8d commit 3478027
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 73 deletions.
27 changes: 15 additions & 12 deletions cypress/e2e/05_phases.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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++) {
for(let i = 0; i < Phases.length; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features/phase`,
Expand All @@ -23,19 +23,19 @@ describe('Create Phases for Feature', () => {
describe('Modify phases name', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
for(let i = 0; i <= 2; i++) {
for(let i = 0; i < Phases.length; i++) {
cy.request({
method: 'POST',
url: `${HostName}/features/phase`,
headers: { 'x-jwt': `${value}` },
body: {
uuid: Phases[i].uuid,
name: Phases[i].name + "_addtext"
name: Phases[i].name.trim() + "_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('name').and.equal(Phases[i].name.trim() + "_addtext");
expect(body).to.have.property('priority').and.equal(Phases[i].priority);
});
}
Expand All @@ -54,13 +54,16 @@ describe('Get phases for feature', () => {
}).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);
resp.body.forEach((phase) => {
// Find the corresponding phase in the Phases array by uuid
const expectedPhase = Phases.find(p => p.uuid.trim() === phase.uuid);

if (expectedPhase) {
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);
}
});
})
})
Expand All @@ -80,7 +83,7 @@ describe('Get phase by uuid', () => {
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('name').and.equal(Phases[i].name.trim() + "_addtext");
expect(resp.body).to.have.property('priority').and.equal(Phases[i].priority);
})
}
Expand Down
44 changes: 27 additions & 17 deletions cypress/e2e/07_add_bounty_to_phase.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,35 +92,45 @@ describe('Get All Bounties - check phase_uuid', () => {
describe('Get Bounties for Phase', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
cy.request({
method: 'GET',
url: `${HostName}/features/${Phases[0].feature_uuid}/phase/${Phases[0].uuid}/bounty`,
headers: { 'x-jwt': `${value}` },
//body: Bounties[i],
failOnStatusCode: false
}).then((resp) => {
expect(resp.status).to.eq(200);
JSON.parse(resp.body).forEach((bounty) => {
cy.request({
method: 'GET',
url: `${HostName}/features/${Phases[1].feature_uuid}/phase/${Phases[1].uuid}/bounty`,
headers: { 'x-jwt': `${value}` },
failOnStatusCode: false
}).then((resp) => {
expect(resp.status).to.eq(200);
console.log(resp.body);
const responseBody = typeof resp.body === 'string' ? JSON.parse(resp.body) : resp.body;
console.log(responseBody);
if (Array.isArray(responseBody)) {
responseBody.forEach((bounty) => {
expect(bounty).to.have.property('bounty').to.have.property('phase_uuid');
expect(bounty).to.have.property('bounty').to.have.property('phase_priority');
})
})
})
})
});
} else {
console.error('Expected an array but got:', responseBody);
}
});
});
});
});

//This test initially does not pass! It asserts that the endpoint should not receive a phase_uuid that doesn't exist
describe('Create Bounties with wrong phase_uuid', () => {

//This test passes! It asserts that the endpoint should receive a valid phase_uuid
describe('Create Bounties with valid phase_uuid', () => {
it('passes', () => {
cy.upsertlogin(User).then(value => {
cy.request({
method: 'POST',
url: `${HostName}/gobounties/`,
headers: { 'x-jwt': `${value}` },
body: {...Bounties[0], phase_uuid: 'cp68lagn1e462l489mu0'}, //phase_uuid does not exist
body: {...Bounties[0], phase_uuid: Phases[0].uuid},
failOnStatusCode: false
}).then((resp) => {
expect(resp.status).to.eq(400);
expect(resp.status).to.eq(200);
expect(resp.body).to.have.property('phase_uuid').and.equal(Phases[0].uuid);
expect(resp.body).to.have.property('phase_priority').and.equal(Phases[0].priority);
console.log(resp);
})
})
})
Expand Down
10 changes: 5 additions & 5 deletions cypress/support/objects/objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export const Bounties = [
title: 'Phase 1 Bounty 1',
ticket_url: 'http://ticket.url',
workspace_uuid: 'workspace-uuid-123',
phase_uuid: Phases[0].uuid,
phase_uuid: Phases[1].uuid,
phase_priority: 0,
description: 'Detailed bug description',
wanted_type: 'Bugfix',
Expand Down Expand Up @@ -187,7 +187,7 @@ export const Bounties = [
assignee: '',
ticket_url: '',
workspace_uuid: Workspaces[0].uuid,
phase_uuid: Phases[0].uuid,
phase_uuid: Phases[2].uuid,
phase_priority: 1,
description: 'detailed bounty description',
wanted_type: 'Web development',
Expand Down Expand Up @@ -215,7 +215,7 @@ export const Bounties = [
assignee: '',
ticket_url: '',
workspace_uuid: Workspaces[0].uuid,
phase_uuid: Phases[0].uuid,
phase_uuid: Phases[1].uuid,
phase_priority: 2,
description: 'detailed bounty description',
wanted_type: 'Web development',
Expand Down Expand Up @@ -243,7 +243,7 @@ export const Bounties = [
assignee: '',
ticket_url: '',
workspace_uuid: Workspaces[0].uuid,
phase_uuid: Phases[0].uuid,
phase_uuid: Phases[1].uuid,
phase_priority: 3,
description: 'detailed bounty description',
wanted_type: 'Web development',
Expand Down Expand Up @@ -271,7 +271,7 @@ export const Bounties = [
assignee: '',
ticket_url: '',
workspace_uuid: Workspaces[0].uuid,
phase_uuid: Phases[0].uuid,
phase_uuid: Phases[2].uuid,
phase_priority: 4,
description: 'detailed bounty description',
wanted_type: 'Web development',
Expand Down
14 changes: 13 additions & 1 deletion db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,8 @@ func (db database) GetAllBounties(r *http.Request) []NewBounty {
languages := keys.Get("languages")
languageArray := strings.Split(languages, ",")
languageLength := len(languageArray)
PhaseUuid := keys.Get("phase_uuid")
PhasePriority := keys.Get("phase_priority")

if workspaceUuid == "" && orgUuid != "" {
workspaceUuid = orgUuid
Expand All @@ -1153,6 +1155,8 @@ func (db database) GetAllBounties(r *http.Request) []NewBounty {
searchQuery := ""
workspaceQuery := ""
languageQuery := ""
phaseUuidQuery := ""
phasePriorityQuery := ""

if sortBy != "" && direction != "" {
orderQuery = "ORDER BY " + sortBy + " " + direction
Expand All @@ -1166,6 +1170,14 @@ func (db database) GetAllBounties(r *http.Request) []NewBounty {
searchQuery = fmt.Sprintf("AND LOWER(title) LIKE %s", "'%"+strings.ToLower(search)+"%'")
}

if PhaseUuid != "" {
phaseUuidQuery = "AND phase_uuid = '" + PhaseUuid + "'"
}

if PhasePriority != "" {
phasePriorityQuery = "AND phase_priority = '" + PhasePriority + "'"
}

var statusConditions []string

if open == "true" {
Expand Down Expand Up @@ -1207,7 +1219,7 @@ func (db database) GetAllBounties(r *http.Request) []NewBounty {

query := "SELECT * FROM public.bounty WHERE show != false"

allQuery := query + " " + statusQuery + " " + searchQuery + " " + workspaceQuery + " " + languageQuery + " " + orderQuery + " " + limitQuery
allQuery := query + " " + statusQuery + " " + searchQuery + " " + workspaceQuery + " " + languageQuery + " " + phaseUuidQuery + " " + phasePriorityQuery + " " + orderQuery + " " + limitQuery

theQuery := db.db.Raw(allQuery)

Expand Down
18 changes: 18 additions & 0 deletions db/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,21 @@ func (db database) DeleteFeatureStoryByUuid(featureUuid, storyUuid string) error
}
return nil
}

func (db database) GetBountyByFeatureAndPhaseUuid(featureUuid string, phaseUuid string) (Bounty, error) {
bounty := Bounty{}

result := db.db.Model(&Bounty{}).
Select("bounty.*").
Joins(`INNER JOIN "feature_phases" ON "feature_phases"."uuid" = "bounty"."phase_uuid" `).
Where(`"feature_phases"."feature_uuid" = ? AND "feature_phases"."uuid" = ?`, featureUuid, phaseUuid).
Order(`"bounty"."id"`).
Limit(1).
First(&bounty)

if result.RowsAffected == 0 {
return bounty, errors.New("no bounty found")
}

return bounty, nil
}
1 change: 1 addition & 0 deletions db/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,5 @@ type Database interface {
GetFeatureStoryByUuid(featureUuid, storyUuid string) (FeatureStory, error)
DeleteFeatureStoryByUuid(featureUuid, storyUuid string) error
DeleteFeatureByUuid(uuid string) error
GetBountyByFeatureAndPhaseUuid(featureUuid string, phaseUuid string) (Bounty, error)
}
4 changes: 4 additions & 0 deletions db/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ type Bounty struct {
MarkAsPaidDate *time.Time `json:"mark_as_paid_date,omitempty"`
PaidDate *time.Time `json:"paid_date,omitempty"`
CodingLanguages pq.StringArray `gorm:"type:text[];not null default:'[]'" json:"coding_languages"`
PhaseUuid *string `json:"phase_uuid"`
PhasePriority *int `json:"phase_priority"`
}

// Todo: Change back to Bounty
Expand Down Expand Up @@ -422,6 +424,8 @@ type NewBounty struct {
MarkAsPaidDate *time.Time `json:"mark_as_paid_date,omitempty"`
PaidDate *time.Time `json:"paid_date,omitempty"`
CodingLanguages pq.StringArray `gorm:"type:text[];not null default:'[]'" json:"coding_languages"`
PhaseUuid *string `json:"phase_uuid"`
PhasePriority *int `json:"phase_priority"`
}

type BountyOwners struct {
Expand Down
1 change: 1 addition & 0 deletions handlers/bounty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func TestCreateOrEditBounty(t *testing.T) {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBounty)


existingBounty := db.NewBounty{
ID: 1,
Type: "coding",
Expand Down
14 changes: 14 additions & 0 deletions handlers/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,17 @@ func (oh *featureHandler) DeleteStory(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"message": "Story deleted successfully"})
}

func (oh *featureHandler) GetBountyByFeatureAndPhaseUuid(w http.ResponseWriter, r *http.Request) {
featureUuid := chi.URLParam(r, "feature_uuid")
phaseUuid := chi.URLParam(r, "phase_uuid")

bounty, err := oh.db.GetBountyByFeatureAndPhaseUuid(featureUuid, phaseUuid)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}

w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(bounty)
}
Loading

0 comments on commit 3478027

Please sign in to comment.