fix(wallet): fix activity filter updates special case
This commit fixes a special case where the activity filter incremental updates were reported as new even that they were present in a previous update. Updates status-desktop #12120
This commit is contained in:
parent
c8044bf400
commit
e1c7c715aa
|
@ -580,3 +580,73 @@ func TestService_IncrementalUpdateFetchWindowNoReset(t *testing.T) {
|
|||
}, common.NewAndSet(extraExpect{common.NewAndSet(2), nil}))
|
||||
require.Equal(t, 1, eventActivityDoneCount)
|
||||
}
|
||||
|
||||
// Simulate and validate a multi-step user flow that was also a regression in the original implementation
|
||||
func TestService_FilteredIncrementalUpdateResetAndClear(t *testing.T) {
|
||||
state := setupTestService(t)
|
||||
defer state.close()
|
||||
|
||||
transactionCount := 5
|
||||
allAddresses, pendings, ch, cleanup := setupTransactions(t, state, transactionCount, []transactions.TestTxSummary{{DontConfirm: true, Timestamp: transactionCount + 1}})
|
||||
defer cleanup()
|
||||
|
||||
// Generate new transaction for step 5
|
||||
newOffset := transactionCount + 2
|
||||
newTxs, newFromTrs, newToTrs := transfer.GenerateTestTransfers(t, state.service.db, newOffset, 1)
|
||||
allAddresses = append(append(allAddresses, newFromTrs...), newToTrs...)
|
||||
|
||||
// 1. User visualizes transactions for the first time
|
||||
sessionID := state.service.StartFilterSession(allAddresses, true, allNetworksFilter(), Filter{}, 4)
|
||||
require.Greater(t, sessionID, SessionID(0))
|
||||
defer state.service.StopFilterSession(sessionID)
|
||||
|
||||
validateFilteringDone(t, ch, 4, nil, nil)
|
||||
|
||||
// 2. User applies a filter for pending transactions
|
||||
err := state.service.UpdateFilterForSession(sessionID, Filter{Statuses: []Status{PendingAS}}, 4)
|
||||
require.NoError(t, err)
|
||||
|
||||
filterResponseCount := validateFilteringDone(t, ch, 0, nil, nil)
|
||||
|
||||
// 3. A pending transaction is added
|
||||
exp := pendings[0]
|
||||
err = state.pendingTracker.StoreAndTrackPendingTx(&exp)
|
||||
require.NoError(t, err)
|
||||
|
||||
vFn := getValidateSessionUpdateHasNewOnTopFn(t)
|
||||
pendingTransactionUpdate, sessionUpdatesCount := validateSessionUpdateEvent(t, ch, &filterResponseCount, 1, vFn)
|
||||
|
||||
// 4. User resets the view and the new pending transaction has the new flag
|
||||
err = state.service.ResetFilterSession(sessionID, 2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Validate the reset data
|
||||
eventActivityDoneCount := validateFilteringDone(t, ch, 1, func(payload FilterResponse) {
|
||||
require.True(t, payload.Activities[0].isNew)
|
||||
require.Equal(t, int64(transactionCount+1), payload.Activities[0].timestamp)
|
||||
}, nil)
|
||||
|
||||
require.Equal(t, 1, pendingTransactionUpdate)
|
||||
require.Equal(t, 1, filterResponseCount)
|
||||
require.Equal(t, 1, sessionUpdatesCount)
|
||||
require.Equal(t, 1, eventActivityDoneCount)
|
||||
|
||||
// 5. A new transaction is downloaded
|
||||
transfer.InsertTestTransfer(t, state.service.db, newTxs[0].To, &newTxs[0])
|
||||
|
||||
// 6. User clears the filter and only the new transaction should have the new flag
|
||||
err = state.service.UpdateFilterForSession(sessionID, Filter{}, 4)
|
||||
require.NoError(t, err)
|
||||
|
||||
eventActivityDoneCount = validateFilteringDone(t, ch, 4, func(payload FilterResponse) {
|
||||
require.True(t, payload.Activities[0].isNew)
|
||||
require.Equal(t, int64(newOffset), payload.Activities[0].timestamp)
|
||||
require.False(t, payload.Activities[1].isNew)
|
||||
require.Equal(t, int64(newOffset-1), payload.Activities[1].timestamp)
|
||||
require.False(t, payload.Activities[2].isNew)
|
||||
require.Equal(t, int64(newOffset-2), payload.Activities[2].timestamp)
|
||||
require.False(t, payload.Activities[3].isNew)
|
||||
require.Equal(t, int64(newOffset-3), payload.Activities[3].timestamp)
|
||||
}, nil)
|
||||
require.Equal(t, 1, eventActivityDoneCount)
|
||||
}
|
||||
|
|
|
@ -190,8 +190,8 @@ func (s *Service) UpdateFilterForSession(id SessionID, filter Filter, firstPageC
|
|||
return errors.New("session not found")
|
||||
}
|
||||
|
||||
prevEmpty := session.filter.IsEmpty()
|
||||
newEmpty := filter.IsEmpty()
|
||||
prevFilterEmpty := session.filter.IsEmpty()
|
||||
newFilerEmpty := filter.IsEmpty()
|
||||
s.sessionsRWMutex.RUnlock()
|
||||
|
||||
s.sessionsRWMutex.Lock()
|
||||
|
@ -200,7 +200,7 @@ func (s *Service) UpdateFilterForSession(id SessionID, filter Filter, firstPageC
|
|||
|
||||
session.filter = filter
|
||||
|
||||
if prevEmpty && !newEmpty {
|
||||
if prevFilterEmpty && !newFilerEmpty {
|
||||
// Session is moving from empty to non-empty filter
|
||||
// Take a snapshot of the current model
|
||||
session.noFilterModel = entryIdsToMap(session.model)
|
||||
|
@ -209,7 +209,7 @@ func (s *Service) UpdateFilterForSession(id SessionID, filter Filter, firstPageC
|
|||
|
||||
// In this case there is nothing to flag so we request the first page
|
||||
s.internalFilterForSession(session, firstPageCount)
|
||||
} else if !prevEmpty && newEmpty {
|
||||
} else if !prevFilterEmpty && newFilerEmpty {
|
||||
// Session is moving from non-empty to empty filter
|
||||
// In this case we need to flag all the new entries that are not in the noFilterModel
|
||||
s.internalFilter(
|
||||
|
@ -277,6 +277,13 @@ func (s *Service) ResetFilterSession(id SessionID, firstPageCount int) error {
|
|||
}
|
||||
session.new = nil
|
||||
|
||||
if session.noFilterModel != nil {
|
||||
// Add reported new entries to mark them as seen
|
||||
for _, a := range newMap {
|
||||
session.noFilterModel[a.key()] = a
|
||||
}
|
||||
}
|
||||
|
||||
// Mirror client identities for checking updates
|
||||
session.model = mirrorIdentities(entries)
|
||||
|
||||
|
|
Loading…
Reference in New Issue