Skip to content

Commit

Permalink
Merge pull request stakwork#1801 from aliraza556/Refactor-TestBountyM…
Browse files Browse the repository at this point in the history
…etrics-UT

Refactor `TestBountyMetrics` To Use A Real Postgres DB For The Test
  • Loading branch information
elraphty authored Jul 1, 2024
2 parents 4017bcc + 2f6418f commit 63f4ccb
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 54 deletions.
34 changes: 17 additions & 17 deletions db/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ func (db database) TotalSatsPaid(r PaymentDateRange, workspace string) uint {
}

func (db database) SatsPaidPercentage(r PaymentDateRange, workspace string) uint {
satsPosted := DB.TotalSatsPosted(r, workspace)
satsPaid := DB.TotalSatsPaid(r, workspace)
satsPosted := db.TotalSatsPosted(r, workspace)
satsPaid := db.TotalSatsPaid(r, workspace)
if satsPaid != 0 && satsPosted != 0 {
value := (satsPaid * 100) / satsPosted
paidPercentage := math.Round(float64(value))
Expand Down Expand Up @@ -143,8 +143,8 @@ func (db database) TotalBountiesPosted(r PaymentDateRange, workspace string) int
}

func (db database) BountiesPaidPercentage(r PaymentDateRange, workspace string) uint {
bountiesPosted := DB.TotalBountiesPosted(r, workspace)
bountiesPaid := DB.TotalPaidBounties(r, workspace)
bountiesPosted := db.TotalBountiesPosted(r, workspace)
bountiesPaid := db.TotalPaidBounties(r, workspace)
if bountiesPaid != 0 && bountiesPosted != 0 {
value := bountiesPaid * 100 / bountiesPosted
paidPercentage := math.Round(float64(value))
Expand Down Expand Up @@ -176,11 +176,11 @@ func (db database) PaidDifferenceCount(r PaymentDateRange, workspace string) int
}

func (db database) AveragePaidTime(r PaymentDateRange, workspace string) uint {
paidList := DB.PaidDifference(r, workspace)
paidCount := DB.PaidDifferenceCount(r, workspace)
paidList := db.PaidDifference(r, workspace)
paidCount := db.PaidDifferenceCount(r, workspace)
var paidSum uint
for _, diff := range paidList {
paidSum = uint(math.Round(diff.Diff))
paidSum += uint(math.Round(diff.Diff))
}
return CalculateAverageDays(paidCount, paidSum)
}
Expand Down Expand Up @@ -208,11 +208,11 @@ func (db database) CompletedDifferenceCount(r PaymentDateRange, workspace string
}

func (db database) AverageCompletedTime(r PaymentDateRange, workspace string) uint {
paidList := DB.CompletedDifference(r, workspace)
paidCount := DB.CompletedDifferenceCount(r, workspace)
paidList := db.CompletedDifference(r, workspace)
paidCount := db.CompletedDifferenceCount(r, workspace)
var paidSum uint
for _, diff := range paidList {
paidSum = uint(math.Round(diff.Diff))
paidSum += uint(math.Round(diff.Diff))
}
return CalculateAverageDays(paidCount, paidSum)
}
Expand All @@ -231,7 +231,7 @@ func (db database) GetBountiesByDateRange(r PaymentDateRange, re *http.Request)
offset, limit, sortBy, direction, _ := utils.GetPaginationParams(re)
keys := re.URL.Query()
open := keys.Get("Open")
assingned := keys.Get("Assigned")
assigned := keys.Get("Assigned")
paid := keys.Get("Paid")
providers := keys.Get("provider")
workspace := keys.Get("workspace")
Expand All @@ -245,7 +245,7 @@ func (db database) GetBountiesByDateRange(r PaymentDateRange, re *http.Request)
if open == "true" {
statusConditions = append(statusConditions, "assignee = '' AND paid != true")
}
if assingned == "true" {
if assigned == "true" {
statusConditions = append(statusConditions, "assignee != '' AND paid = false")
}
if paid == "true" {
Expand All @@ -262,7 +262,7 @@ func (db database) GetBountiesByDateRange(r PaymentDateRange, re *http.Request)
if sortBy != "" && direction != "" {
orderQuery = "ORDER BY " + sortBy + " " + direction
} else {
orderQuery = " ORDER BY " + sortBy + "" + "DESC"
orderQuery = " ORDER BY " + sortBy + " DESC"
}
if limit > 1 {
limitQuery = fmt.Sprintf("LIMIT %d OFFSET %d", limit, offset)
Expand All @@ -289,7 +289,7 @@ func (db database) GetBountiesByDateRange(r PaymentDateRange, re *http.Request)
func (db database) GetBountiesByDateRangeCount(r PaymentDateRange, re *http.Request) int64 {
keys := re.URL.Query()
open := keys.Get("Open")
assingned := keys.Get("Assigned")
assigned := keys.Get("Assigned")
paid := keys.Get("Paid")
providers := keys.Get("provider")
workspace := keys.Get("workspace")
Expand All @@ -299,7 +299,7 @@ func (db database) GetBountiesByDateRangeCount(r PaymentDateRange, re *http.Requ
if open == "true" {
statusConditions = append(statusConditions, "assignee = '' AND paid != true")
}
if assingned == "true" {
if assigned == "true" {
statusConditions = append(statusConditions, "assignee != '' AND paid = false")
}
if paid == "true" {
Expand Down Expand Up @@ -335,7 +335,7 @@ func (db database) GetBountiesProviders(r PaymentDateRange, re *http.Request) []
offset, limit, _, _, _ := utils.GetPaginationParams(re)
keys := re.URL.Query()
open := keys.Get("Open")
assingned := keys.Get("Assigned")
assigned := keys.Get("Assigned")
paid := keys.Get("Paid")
providers := keys.Get("provider")

Expand All @@ -346,7 +346,7 @@ func (db database) GetBountiesProviders(r PaymentDateRange, re *http.Request) []
if open == "true" {
statusConditions = append(statusConditions, "assignee = '' AND paid != true")
}
if assingned == "true" {
if assigned == "true" {
statusConditions = append(statusConditions, "assignee != '' AND paid = false")
}
if paid == "true" {
Expand Down
8 changes: 6 additions & 2 deletions handlers/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,15 @@ func (mh *metricHandler) BountyMetrics(w http.ResponseWriter, r *http.Request) {
check redis if cache id available for the date range
or add to redis
*/
if db.RedisError == nil {
if db.RedisError == nil && db.RedisClient != nil {
redisMetrics := db.GetMap(metricsKey)
if len(redisMetrics) != 0 {
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(redisMetrics)
return
}
} else {
fmt.Println("Redis client is not initialized or there is an error with Redis")
}

totalBountiesPosted := mh.db.TotalBountiesPosted(request, workspace)
Expand Down Expand Up @@ -176,9 +178,11 @@ func (mh *metricHandler) BountyMetrics(w http.ResponseWriter, r *http.Request) {
NewHuntersPaid: newHuntersPaid,
}

if db.RedisError == nil {
if db.RedisError == nil && db.RedisClient != nil {
metricsMap := structs.Map(bountyMetrics)
db.SetMap(metricsKey, metricsMap)
} else {
fmt.Println("Redis client is not initialized or there is an error with Redis")
}

w.WriteHeader(http.StatusOK)
Expand Down
141 changes: 106 additions & 35 deletions handlers/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"github.com/google/uuid"
"github.com/lib/pq"
"net/http"
Expand All @@ -17,14 +16,89 @@ import (

"github.com/stakwork/sphinx-tribes/auth"
"github.com/stakwork/sphinx-tribes/db"
mocks "github.com/stakwork/sphinx-tribes/mocks"
"github.com/stretchr/testify/assert"
)

func TestBountyMetrics(t *testing.T) {
ctx := context.WithValue(context.Background(), auth.ContextKey, "test-key")
mockDb := mocks.NewDatabase(t)
mh := NewMetricHandler(mockDb)
teardownSuite := SetupSuite(t)
defer teardownSuite(t)

mh := NewMetricHandler(db.TestDB)

db.TestDB.DeleteAllBounties()

person := db.Person{
Uuid: uuid.New().String(),
OwnerPubKey: "person1_pubkey",
OwnerAlias: "person1",
UniqueName: "person1",
Description: "description",
Tags: pq.StringArray{},
Extras: db.PropertyMap{},
GithubIssues: db.PropertyMap{},
}
db.TestDB.CreateOrEditPerson(person)
ctx := context.WithValue(context.Background(), auth.ContextKey, person.OwnerPubKey)
now := time.Now()

bounty1 := db.NewBounty{
Type: "coding",
Title: "Bounty With ID 1",
Description: "Bounty ID 1 Description",
WorkspaceUuid: "workspace",
Assignee: "ali",
OwnerID: person.OwnerPubKey,
Show: true,
Created: now.AddDate(0, 0, -30).Unix(),
Paid: true,
Price: 100,
}
db.TestDB.CreateOrEditBounty(bounty1)

bounty2 := db.NewBounty{
Type: "coding",
Title: "Bounty With ID 2",
Description: "Bounty ID 2 Description",
WorkspaceUuid: "workspace",
Assignee: "raza",
OwnerID: person.OwnerPubKey,
Show: true,
Created: now.AddDate(0, 0, -20).Unix(),
Paid: true,
Price: 150,
}
db.TestDB.CreateOrEditBounty(bounty2)

bounty3 := db.NewBounty{
Type: "coding",
Title: "Bounty With ID 3",
Description: "Bounty ID 3 Description",
WorkspaceUuid: "workspace",
Assignee: "ali",
OwnerID: person.OwnerPubKey,
Show: true,
Created: now.AddDate(0, 0, -10).Unix(),
Paid: false,
}
db.TestDB.CreateOrEditBounty(bounty3)

bounty4 := db.NewBounty{
Type: "coding",
Title: "Bounty With ID 4",
Description: "Bounty ID 4 Description",
WorkspaceUuid: "workspace",
Assignee: "ali",
OwnerID: person.OwnerPubKey,
Show: true,
Created: now.Unix(),
Paid: false,
}
db.TestDB.CreateOrEditBounty(bounty4)

dateRange := db.PaymentDateRange{
StartDate: strconv.FormatInt(bounty1.Created, 10),
EndDate: strconv.FormatInt(bounty4.Created, 10),
}

t.Run("should return error if body is not a valid json", func(t *testing.T) {
rr := httptest.NewRecorder()
Expand Down Expand Up @@ -57,51 +131,48 @@ func TestBountyMetrics(t *testing.T) {
})

t.Run("should fetch stats from db", func(t *testing.T) {
db.RedisError = errors.New("redis not initialized")
rr := httptest.NewRecorder()
handler := http.HandlerFunc(mh.BountyMetrics)
workspace := "test-workspace"

dateRange := db.PaymentDateRange{
StartDate: "1111",
EndDate: "2222",
}
body, _ := json.Marshal(dateRange)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "/bounty_stats?workspace="+workspace, bytes.NewReader(body))
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "/bounty_stats?workspace=workspace", bytes.NewReader(body))
if err != nil {
t.Fatal(err)
}
mockDb.On("TotalBountiesPosted", dateRange, workspace).Return(int64(1)).Once()
mockDb.On("TotalPaidBounties", dateRange, workspace).Return(int64(1)).Once()
mockDb.On("TotalAssignedBounties", dateRange, workspace).Return(int64(2)).Once()
mockDb.On("BountiesPaidPercentage", dateRange, workspace).Return(uint(1)).Once()
mockDb.On("TotalSatsPosted", dateRange, workspace).Return(uint(1)).Once()
mockDb.On("TotalSatsPaid", dateRange, workspace).Return(uint(1)).Once()
mockDb.On("SatsPaidPercentage", dateRange, workspace).Return(uint(1)).Once()
mockDb.On("AveragePaidTime", dateRange, workspace).Return(uint(1)).Once()
mockDb.On("AverageCompletedTime", dateRange, workspace).Return(uint(1)).Once()
mockDb.On("TotalHuntersPaid", dateRange, workspace).Return(int64(1)).Once()
mockDb.On("NewHuntersPaid", dateRange, workspace).Return(int64(1)).Once()

handler.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)

totalBountiesPosted := int64(4)
totalBountiesPaid := int64(2)
totalBountiesAssigned := int64(2)
bountiesPaidPercentage := uint((totalBountiesPaid * 100) / totalBountiesPosted)
totalSatsPosted := bounty1.Price + bounty2.Price + bounty3.Price + bounty4.Price
totalSatsPaid := bounty1.Price + bounty2.Price
satsPaidPercentage := uint((totalSatsPaid * 100) / totalSatsPosted)
avgPaidDays := uint(0)
avgCompletedDays := uint(0)
uniqueHuntersPaid := int64(2)
newHuntersPaid := int64(2)

expectedMetricRes := db.BountyMetrics{
BountiesPosted: 1,
BountiesPaid: 1,
BountiesAssigned: 2,
BountiesPaidPercentage: 1,
SatsPosted: 1,
SatsPaid: 1,
SatsPaidPercentage: 1,
AveragePaid: 1,
AverageCompleted: 1,
UniqueHuntersPaid: 1,
NewHuntersPaid: 1,
BountiesPosted: totalBountiesPosted,
BountiesPaid: int64(totalBountiesPaid),
BountiesAssigned: int64(totalBountiesAssigned),
BountiesPaidPercentage: bountiesPaidPercentage,
SatsPosted: uint(totalSatsPosted),
SatsPaid: uint(totalSatsPaid),
SatsPaidPercentage: satsPaidPercentage,
AveragePaid: avgPaidDays,
AverageCompleted: avgCompletedDays,
UniqueHuntersPaid: uniqueHuntersPaid,
NewHuntersPaid: newHuntersPaid,
}

var res db.BountyMetrics
_ = json.Unmarshal(rr.Body.Bytes(), &res)

assert.EqualValues(t, expectedMetricRes, res)
assert.Equal(t, http.StatusOK, rr.Code)
})
}

Expand Down

0 comments on commit 63f4ccb

Please sign in to comment.