diff options
Diffstat (limited to 'backend/internal/core/goal_service_test.go')
-rw-r--r-- | backend/internal/core/goal_service_test.go | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/backend/internal/core/goal_service_test.go b/backend/internal/core/goal_service_test.go new file mode 100644 index 0000000..2a4446a --- /dev/null +++ b/backend/internal/core/goal_service_test.go @@ -0,0 +1,129 @@ +package core + +import ( + "finance/backend/internal/models" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "gorm.io/gorm" +) + +// Mock goal for testing +func createTestGoal() *models.Goal { + return &models.Goal{ + Model: gorm.Model{ID: 1, CreatedAt: time.Now().Add(-30 * 24 * time.Hour)}, // created 30 days ago + UserID: 1, + Name: "Test Goal", + TargetAmount: 10000, + CurrentAmount: 3000, + Status: "Active", + TargetDate: time.Now().Add(60 * 24 * time.Hour), // due in 60 days + } +} + +// TestCalculateGoalProgress tests the goal progress calculation logic +func TestCalculateGoalProgress(t *testing.T) { + // Create a test service + service := &GoalService{} + + // Test with a goal that's on track + goal := createTestGoal() + progress, err := service.calculateGoalProgress(goal) + + assert.NoError(t, err) + assert.NotNil(t, progress) + + // Verify calculations + assert.Equal(t, int64(7000), progress.AmountRemaining) + assert.InDelta(t, 30.0, progress.PercentComplete, 0.1) + + // Should have around 60 days remaining (might vary slightly based on test execution time) + assert.True(t, progress.DaysRemaining > 55 && progress.DaysRemaining <= 61) + + // Test required amounts + assert.True(t, progress.RequiredPerDay > 0) + assert.True(t, progress.RequiredPerMonth > 0) + + // Verify on track status - goal is at 30% completion, we're 1/3 through the time period + // so it should be on track + assert.True(t, progress.OnTrack) + + // Test with a goal that's behind + goal.CurrentAmount = 1000 // only 10% complete after 1/3 of the time + progress, err = service.calculateGoalProgress(goal) + + assert.NoError(t, err) + assert.NotNil(t, progress) + assert.False(t, progress.OnTrack) + + // Test with a goal that has no target date + goal = createTestGoal() + goal.TargetDate = time.Time{} // zero time + progress, err = service.calculateGoalProgress(goal) + + assert.NoError(t, err) + assert.NotNil(t, progress) + assert.True(t, progress.OnTrack) // should be on track if any progress made + assert.Equal(t, 0, progress.DaysRemaining) + + // Test with a goal whose target date has passed + goal = createTestGoal() + goal.TargetDate = time.Now().Add(-10 * 24 * time.Hour) // 10 days ago + progress, err = service.calculateGoalProgress(goal) + + assert.NoError(t, err) + assert.NotNil(t, progress) + assert.Equal(t, 0, progress.DaysRemaining) + + // Not on track if target amount not reached + assert.False(t, progress.OnTrack) + + // But should be on track if target amount reached despite date passed + goal.CurrentAmount = goal.TargetAmount + progress, err = service.calculateGoalProgress(goal) + + assert.NoError(t, err) + assert.True(t, progress.OnTrack) +} + +// TestUpdateGoalFromTransactions tests updating a goal based on transactions +func TestUpdateGoalFromTransactions(t *testing.T) { + // This test would need a mock database to be fully implemented + // Here's a placeholder for when DB mocking is available + + /* + // Setup a mock DB + db, mock := setupMockDB(t) + service := &GoalService{db: db} + + // Setup expectations + goalID := uint(1) + userID := uint(1) + + // Expect a query to fetch the goal + mock.ExpectQuery(`SELECT * FROM "goals" WHERE "id" = ?`). + WithArgs(goalID). + WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "name", "target_amount", "current_amount", "status"}). + AddRow(goalID, userID, "Test Goal", 10000, 0, "Active")) + + // Expect a query to fetch transactions + mock.ExpectQuery(`SELECT * FROM "transactions" WHERE "user_id" = ? AND "category" = ?`). + WithArgs(userID, "Goal:1"). + WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "amount", "type", "category"}). + AddRow(1, userID, 500, "Income", "Goal:1"). + AddRow(2, userID, 300, "Income", "Goal:1"). + AddRow(3, userID, 200, "Expense", "Goal:1")) + + // Expect an update to the goal + mock.ExpectBegin() + mock.ExpectExec(`UPDATE "goals" SET`). + WithArgs(600, "Active", goalID). // 500 + 300 - 200 = 600 + WillReturnResult(sqlmock.NewResult(1, 1)) + mock.ExpectCommit() + + // Run the test + err := service.UpdateGoalFromTransactions(goalID) + assert.NoError(t, err) + */ +} |