Merge pull request #73 from johan-autohome/feature/isRolling

IsRolling tests
This commit is contained in:
Mohamad Tarbin 2025-01-06 18:59:08 -05:00 committed by GitHub
commit c5ff204c0a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 99 additions and 13 deletions

View file

@ -195,14 +195,17 @@ func (h *Handler) createChore(c *gin.Context) {
} }
circleUsers, err := h.circleRepo.GetCircleUsers(c, currentUser.CircleID) circleUsers, err := h.circleRepo.GetCircleUsers(c, currentUser.CircleID)
if err != nil {
log.Print(err)
c.JSON(500, gin.H{"error": "Error getting circle users"})
return
}
for _, assignee := range choreReq.Assignees { for _, assignee := range choreReq.Assignees {
userFound := false userFound := false
for _, circleUser := range circleUsers { for _, circleUser := range circleUsers {
if assignee.UserID == circleUser.UserID { if assignee.UserID == circleUser.UserID {
userFound = true userFound = true
break break
} }
} }
if !userFound { if !userFound {

View file

@ -26,11 +26,11 @@ func scheduleNextDueDate(chore *chModel.Chore, completedDate time.Time) (*time.T
if chore.NextDueDate != nil { if chore.NextDueDate != nil {
// no due date set, use the current date // no due date set, use the current date
baseDate = chore.NextDueDate.UTC() baseDate = chore.NextDueDate.UTC()
} else { } else {
baseDate = completedDate.UTC() baseDate = completedDate.UTC()
} }
if chore.FrequencyType == "day_of_the_month" || chore.FrequencyType == "days_of_the_week" || chore.FrequencyType == "interval" { if chore.FrequencyType == "day_of_the_month" || chore.FrequencyType == "days_of_the_week" || chore.FrequencyType == "interval" {
// time in frequency metadata stored as RFC3339 format like `2024-07-07T13:27:00-04:00` // time in frequency metadata stored as RFC3339 format like `2024-07-07T13:27:00-04:00`
// parse it to time.Time: // parse it to time.Time:

View file

@ -2,6 +2,7 @@ package chore
import ( import (
"encoding/json" "encoding/json"
"fmt"
"testing" "testing"
"time" "time"
@ -11,9 +12,12 @@ import (
func TestScheduleNextDueDateBasic(t *testing.T) { func TestScheduleNextDueDateBasic(t *testing.T) {
choreTime := time.Now() choreTime := time.Now()
freqencyMetadataBytes := `{"time":"2024-07-07T14:30:00-04:00"}` freqencyMetadataBytes := `{"time":"2024-07-07T14:30:00-04:00"}`
intervalFreqencyMetadataBytes := `{"time":"2024-07-07T14:30:00-04:00", "unit": "days"}`
testTable := []struct { testTable := []struct {
Name string
chore *chModel.Chore chore *chModel.Chore
completedAt time.Time
expected time.Time expected time.Time
}{ }{
{ {
@ -22,14 +26,36 @@ func TestScheduleNextDueDateBasic(t *testing.T) {
NextDueDate: &choreTime, NextDueDate: &choreTime,
FrequencyMetadata: &freqencyMetadataBytes, FrequencyMetadata: &freqencyMetadataBytes,
}, },
completedAt: choreTime,
expected: choreTime.AddDate(0, 0, 1), expected: choreTime.AddDate(0, 0, 1),
}, },
{ // Completed 1 day late
chore: &chModel.Chore{
FrequencyType: chModel.FrequancyTypeDaily,
NextDueDate: &choreTime,
FrequencyMetadata: &freqencyMetadataBytes,
},
completedAt: choreTime.AddDate(0, 0, 1),
expected: choreTime.AddDate(0, 0, 1),
},
{
Name: "Rolling completed 1 day late",
chore: &chModel.Chore{
FrequencyType: chModel.FrequancyTypeDaily,
NextDueDate: &choreTime,
FrequencyMetadata: &freqencyMetadataBytes,
IsRolling: true,
},
completedAt: choreTime.AddDate(0, 0, 1),
expected: choreTime.AddDate(0, 0, 1+1),
},
{ {
chore: &chModel.Chore{ chore: &chModel.Chore{
FrequencyType: chModel.FrequancyTypeWeekly, FrequencyType: chModel.FrequancyTypeWeekly,
NextDueDate: &choreTime, NextDueDate: &choreTime,
FrequencyMetadata: &freqencyMetadataBytes, FrequencyMetadata: &freqencyMetadataBytes,
}, },
completedAt: choreTime,
expected: choreTime.AddDate(0, 0, 7), expected: choreTime.AddDate(0, 0, 7),
}, },
{ {
@ -38,6 +64,7 @@ func TestScheduleNextDueDateBasic(t *testing.T) {
NextDueDate: &choreTime, NextDueDate: &choreTime,
FrequencyMetadata: &freqencyMetadataBytes, FrequencyMetadata: &freqencyMetadataBytes,
}, },
completedAt: choreTime,
expected: choreTime.AddDate(0, 1, 0), expected: choreTime.AddDate(0, 1, 0),
}, },
{ {
@ -46,25 +73,81 @@ func TestScheduleNextDueDateBasic(t *testing.T) {
NextDueDate: &choreTime, NextDueDate: &choreTime,
FrequencyMetadata: &freqencyMetadataBytes, FrequencyMetadata: &freqencyMetadataBytes,
}, },
completedAt: choreTime,
expected: choreTime.AddDate(1, 0, 0), expected: choreTime.AddDate(1, 0, 0),
}, },
{
Name: "14 days interval Rolling Completed in time",
chore: &chModel.Chore{
FrequencyType: chModel.FrequancyTypeIntervel,
NextDueDate: &choreTime,
FrequencyMetadata: &intervalFreqencyMetadataBytes,
Frequency: 14,
IsRolling: true,
},
completedAt: choreTime,
expected: choreTime.AddDate(0, 0, 14),
},
{
Name: "14 days interval Rolling Completed late",
chore: &chModel.Chore{
FrequencyType: chModel.FrequancyTypeIntervel,
NextDueDate: &choreTime,
FrequencyMetadata: &intervalFreqencyMetadataBytes,
Frequency: 14,
IsRolling: true,
},
completedAt: choreTime.AddDate(0, 0, 1),
expected: choreTime.AddDate(0, 0, 14+1),
},
{
Name: "14 days interval Completed in time",
chore: &chModel.Chore{
FrequencyType: chModel.FrequancyTypeIntervel,
NextDueDate: &choreTime,
FrequencyMetadata: &intervalFreqencyMetadataBytes,
Frequency: 14,
IsRolling: false,
},
completedAt: choreTime,
expected: truncateToDay(choreTime.AddDate(0, 0, 14).UTC()).Add(18 * time.Hour).Add(30 * time.Minute), // Note: Same Hour and Minute as Metadata time
},
{
Name: "14 days interval Completed late",
chore: &chModel.Chore{
FrequencyType: chModel.FrequancyTypeIntervel,
NextDueDate: &choreTime,
FrequencyMetadata: &intervalFreqencyMetadataBytes,
Frequency: 14,
IsRolling: false,
},
completedAt: choreTime.AddDate(0, 0, 1),
expected: truncateToDay(choreTime.AddDate(0, 0, 14).UTC()).Add(18 * time.Hour).Add(30 * time.Minute), // Note: Same Hour and Minute as Metadata time
},
// //
} }
for _, tt := range testTable { for i, tt := range testTable {
t.Run(string(tt.chore.FrequencyType), func(t *testing.T) { t.Run(fmt.Sprintf("%s %s %d", tt.chore.FrequencyType, tt.Name, i), func(t *testing.T) {
actual, err := scheduleNextDueDate(tt.chore, choreTime) actual, err := scheduleNextDueDate(tt.chore, tt.completedAt)
if err != nil { if err != nil {
t.Errorf("Error: %v", err) t.Errorf("Error: %v", err)
t.FailNow()
} }
if actual != nil && actual.UTC().Format(time.RFC3339) != tt.expected.UTC().Format(time.RFC3339) { if actual == nil {
t.Errorf("Expected: %v, Error: Actual missing", tt.expected)
} else if actual.UTC().Format(time.RFC3339) != tt.expected.UTC().Format(time.RFC3339) {
t.Errorf("Expected: %v, Actual: %v", tt.expected, actual) t.Errorf("Expected: %v, Actual: %v", tt.expected, actual)
} }
}) })
} }
} }
func truncateToDay(t time.Time) time.Time {
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
}
func TestScheduleNextDueDateDayOfTheWeek(t *testing.T) { func TestScheduleNextDueDateDayOfTheWeek(t *testing.T) {
choreTime := time.Now() choreTime := time.Now()