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}))
|
}, common.NewAndSet(extraExpect{common.NewAndSet(2), nil}))
|
||||||
require.Equal(t, 1, eventActivityDoneCount)
|
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")
|
return errors.New("session not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
prevEmpty := session.filter.IsEmpty()
|
prevFilterEmpty := session.filter.IsEmpty()
|
||||||
newEmpty := filter.IsEmpty()
|
newFilerEmpty := filter.IsEmpty()
|
||||||
s.sessionsRWMutex.RUnlock()
|
s.sessionsRWMutex.RUnlock()
|
||||||
|
|
||||||
s.sessionsRWMutex.Lock()
|
s.sessionsRWMutex.Lock()
|
||||||
|
@ -200,7 +200,7 @@ func (s *Service) UpdateFilterForSession(id SessionID, filter Filter, firstPageC
|
||||||
|
|
||||||
session.filter = filter
|
session.filter = filter
|
||||||
|
|
||||||
if prevEmpty && !newEmpty {
|
if prevFilterEmpty && !newFilerEmpty {
|
||||||
// Session is moving from empty to non-empty filter
|
// Session is moving from empty to non-empty filter
|
||||||
// Take a snapshot of the current model
|
// Take a snapshot of the current model
|
||||||
session.noFilterModel = entryIdsToMap(session.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
|
// In this case there is nothing to flag so we request the first page
|
||||||
s.internalFilterForSession(session, firstPageCount)
|
s.internalFilterForSession(session, firstPageCount)
|
||||||
} else if !prevEmpty && newEmpty {
|
} else if !prevFilterEmpty && newFilerEmpty {
|
||||||
// Session is moving from non-empty to empty filter
|
// 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
|
// In this case we need to flag all the new entries that are not in the noFilterModel
|
||||||
s.internalFilter(
|
s.internalFilter(
|
||||||
|
@ -277,6 +277,13 @@ func (s *Service) ResetFilterSession(id SessionID, firstPageCount int) error {
|
||||||
}
|
}
|
||||||
session.new = nil
|
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
|
// Mirror client identities for checking updates
|
||||||
session.model = mirrorIdentities(entries)
|
session.model = mirrorIdentities(entries)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue