Skip to content

Commit 0b5e1e8

Browse files
authored
fix: income at correct position in recommended envelopes (#899)
1 parent a2bc262 commit 0b5e1e8

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

pkg/models/account.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ func (a Account) RecentEnvelopes(db *gorm.DB) ([]*uuid.UUID, error) {
183183
latest := db.
184184
Model(&Transaction{}).
185185
Joins("LEFT JOIN envelopes ON envelopes.id = transactions.envelope_id AND envelopes.deleted_at IS NULL").
186-
Select("envelopes.id as id, datetime(envelopes.created_at) as created").
186+
Select("envelopes.id as e_id, datetime(envelopes.created_at) as created").
187187
Where(&Transaction{
188188
TransactionCreate: TransactionCreate{
189189
DestinationAccountID: a.ID,
@@ -195,7 +195,8 @@ func (a Account) RecentEnvelopes(db *gorm.DB) ([]*uuid.UUID, error) {
195195
// Group by frequency
196196
err := db.
197197
Table("(?)", latest).
198-
Select("id").
198+
// Set the nil UUID as ID if the envelope ID is NULL, since count() only counts non-null values
199+
Select("IIF(e_id IS NOT NULL, e_id, '00000000-0000-0000-0000-000000000000') as id").
199200
Group("id").
200201
Order("count(id) DESC").
201202
Order("created ASC").

pkg/models/account_test.go

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ func (suite *TestSuiteStandard) TestAccountRecentEnvelopes() {
308308
// Sleep for 10 milliseconds because we only save timestamps with 1 millisecond accuracy
309309
// This is needed because the test runs so fast that all envelopes are sometimes created
310310
// within the same millisecond, making the result non-deterministic
311-
time.Sleep(1 * time.Second)
311+
time.Sleep(1 * time.Millisecond)
312312
}
313313

314314
// Create 15 transactions:
@@ -329,14 +329,24 @@ func (suite *TestSuiteStandard) TestAccountRecentEnvelopes() {
329329
})
330330
}
331331

332-
// Create one income transaction
333-
_ = suite.createTestTransaction(models.TransactionCreate{
334-
BudgetID: budget.ID,
335-
EnvelopeID: nil,
336-
SourceAccountID: externalAccount.ID,
337-
DestinationAccountID: account.ID,
338-
Amount: decimal.NewFromFloat(1337.42),
339-
})
332+
// Create three income transactions
333+
//
334+
// This is a regression test for income always showing at the last
335+
// position in the recent envelopes (before the LIMIT) since count(id) for
336+
// income was always 0. This is due to the envelope ID for income being NULL
337+
// and count() not counting NULL values.
338+
//
339+
// Creating three income transactions puts "income" as the second most common
340+
// envelope, verifying the fix
341+
for i := 0; i < 3; i++ {
342+
_ = suite.createTestTransaction(models.TransactionCreate{
343+
BudgetID: budget.ID,
344+
EnvelopeID: nil,
345+
SourceAccountID: externalAccount.ID,
346+
DestinationAccountID: account.ID,
347+
Amount: decimal.NewFromFloat(1337.42),
348+
})
349+
}
340350

341351
ids, err := account.RecentEnvelopes(suite.db)
342352
if err != nil {
@@ -351,9 +361,9 @@ func (suite *TestSuiteStandard) TestAccountRecentEnvelopes() {
351361
// has been the most common one
352362
suite.Assert().Equal(envelopeIDs[2], ids[0])
353363

354-
// Order for envelopes with the same frequency is undefined
355-
356-
// Income is the last one since it only appears once
364+
// Income is the second one since it appears three times
357365
var nilUUIDPointer *uuid.UUID
358-
suite.Assert().Equal(nilUUIDPointer, ids[3])
366+
suite.Assert().Equal(nilUUIDPointer, ids[1])
367+
368+
// Order for envelopes with the same frequency is undefined
359369
}

0 commit comments

Comments
 (0)