Isrolling fixes and add tests

This commit is contained in:
johan-autohome 2025-01-03 19:11:50 +01:00
parent 11f1985831
commit 015aeba0c2
3 changed files with 97 additions and 15 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

@ -24,14 +24,14 @@ func scheduleNextDueDate(chore *chModel.Chore, completedDate time.Time) (*time.T
return nil, nil return nil, nil
} }
if chore.NextDueDate != nil { if chore.NextDueDate != nil && !chore.IsRolling {
// 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.IsRolling && (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:
t, err := time.Parse(time.RFC3339, frequencyMetadata.Time) t, err := time.Parse(time.RFC3339, frequencyMetadata.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,19 +73,71 @@ 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: choreTime.AddDate(0, 0, 14).UTC().Truncate(time.Hour).Add(30 * time.Minute), // Same 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: choreTime.AddDate(0, 0, 14).UTC().Truncate(time.Hour).Add(30 * time.Minute), // Same 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)
} }
}) })