Ignore cache if it failed and write unit test for forceEmailQuery = true
(cherry picked from commit 05496806823b6daed2b0abd889915a5fd7d5f88f)
This commit is contained in:
@@ -159,21 +159,39 @@ class ThreadRepositoryImpl extends ThreadRepository {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load cached emails + cached state
|
List<Email> cachedList = const [];
|
||||||
final cachedList = await localDataSource.getAllEmailCache(
|
jmap.State? cachedState;
|
||||||
accountId,
|
|
||||||
session.username,
|
|
||||||
inMailboxId: emailFilter?.mailboxId,
|
|
||||||
sort: sort,
|
|
||||||
limit: limit,
|
|
||||||
filterOption: emailFilter?.filterOption,
|
|
||||||
);
|
|
||||||
|
|
||||||
final cachedState = await stateDataSource.getState(
|
// Load cached emails
|
||||||
accountId,
|
try {
|
||||||
session.username,
|
cachedList = await localDataSource.getAllEmailCache(
|
||||||
StateType.email,
|
accountId,
|
||||||
);
|
session.username,
|
||||||
|
inMailboxId: emailFilter?.mailboxId,
|
||||||
|
sort: sort,
|
||||||
|
limit: limit,
|
||||||
|
filterOption: emailFilter?.filterOption,
|
||||||
|
);
|
||||||
|
} catch (_) {
|
||||||
|
logError(
|
||||||
|
'ThreadRepositoryImpl::forceQueryAllEmailsForWeb(): '
|
||||||
|
'Failed to load cached emails',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load cached state
|
||||||
|
try {
|
||||||
|
cachedState = await stateDataSource.getState(
|
||||||
|
accountId,
|
||||||
|
session.username,
|
||||||
|
StateType.email,
|
||||||
|
);
|
||||||
|
} catch (_) {
|
||||||
|
logError(
|
||||||
|
'ThreadRepositoryImpl::forceQueryAllEmailsForWeb(): '
|
||||||
|
'Failed to load cached email state',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final localResponse = EmailsResponse(
|
final localResponse = EmailsResponse(
|
||||||
emailList: cachedList,
|
emailList: cachedList,
|
||||||
@@ -211,7 +229,7 @@ class ThreadRepositoryImpl extends ThreadRepository {
|
|||||||
// Combine server list + keep existing state
|
// Combine server list + keep existing state
|
||||||
yield EmailsResponse(
|
yield EmailsResponse(
|
||||||
emailList: serverResponse.emailList,
|
emailList: serverResponse.emailList,
|
||||||
state: cachedState,
|
state: cachedState ?? serverResponse.state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,5 +103,339 @@ void main() {
|
|||||||
)
|
)
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should use forceQueryAllEmailsForWeb when forceEmailQuery = true',
|
||||||
|
() async {
|
||||||
|
final sort = <EmailComparator>{
|
||||||
|
EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false),
|
||||||
|
};
|
||||||
|
|
||||||
|
final emailFilter = EmailFilter(
|
||||||
|
filter: EmailFilterCondition(
|
||||||
|
inMailbox: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
mailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
when(threadRepository.forceQueryAllEmailsForWeb(
|
||||||
|
session: SessionFixtures.aliceSession,
|
||||||
|
accountId: AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
)).thenAnswer(
|
||||||
|
(_) => Stream<EmailsResponse>.fromIterable([
|
||||||
|
EmailsResponse(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1,
|
||||||
|
],
|
||||||
|
state: jmap.State('s_cached'),
|
||||||
|
),
|
||||||
|
EmailsResponse(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1,
|
||||||
|
EmailFixtures.email2,
|
||||||
|
EmailFixtures.email3,
|
||||||
|
],
|
||||||
|
state: jmap.State('s_cached'),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
final resultStream = getEmailsInMailboxInteractor.execute(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
forceEmailQuery: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
final states = await resultStream.toList();
|
||||||
|
|
||||||
|
expect(states.length, 3);
|
||||||
|
|
||||||
|
expect(states[0], Right(GetAllEmailLoading()));
|
||||||
|
|
||||||
|
expect(
|
||||||
|
states[1],
|
||||||
|
Right(
|
||||||
|
GetAllEmailSuccess(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1.toPresentationEmail(),
|
||||||
|
],
|
||||||
|
currentEmailState: jmap.State('s_cached'),
|
||||||
|
currentMailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
states[2],
|
||||||
|
Right(
|
||||||
|
GetAllEmailSuccess(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1.toPresentationEmail(),
|
||||||
|
EmailFixtures.email2.toPresentationEmail(),
|
||||||
|
EmailFixtures.email3.toPresentationEmail(),
|
||||||
|
],
|
||||||
|
currentEmailState: jmap.State('s_cached'),
|
||||||
|
currentMailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
verify(threadRepository.forceQueryAllEmailsForWeb(
|
||||||
|
session: SessionFixtures.aliceSession,
|
||||||
|
accountId: AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
)).called(1);
|
||||||
|
|
||||||
|
verifyNever(threadRepository.getAllEmail(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
limit: anyNamed('limit'),
|
||||||
|
sort: anyNamed('sort'),
|
||||||
|
emailFilter: anyNamed('emailFilter'),
|
||||||
|
propertiesCreated: anyNamed('propertiesCreated'),
|
||||||
|
propertiesUpdated: anyNamed('propertiesUpdated'),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'forceEmailQuery = true, should continue when cache throws error and still return server emails',
|
||||||
|
() async {
|
||||||
|
final sort = <EmailComparator>{
|
||||||
|
EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false),
|
||||||
|
};
|
||||||
|
|
||||||
|
final emailFilter = EmailFilter(
|
||||||
|
filter: EmailFilterCondition(
|
||||||
|
inMailbox: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
mailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
when(threadRepository.forceQueryAllEmailsForWeb(
|
||||||
|
session: SessionFixtures.aliceSession,
|
||||||
|
accountId: AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
)).thenAnswer(
|
||||||
|
(_) => Stream<EmailsResponse>.fromIterable([
|
||||||
|
const EmailsResponse(
|
||||||
|
emailList: null,
|
||||||
|
state: null,
|
||||||
|
),
|
||||||
|
EmailsResponse(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1,
|
||||||
|
EmailFixtures.email2,
|
||||||
|
],
|
||||||
|
state: jmap.State('server_1'),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
final resultStream = getEmailsInMailboxInteractor.execute(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
forceEmailQuery: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
final states = await resultStream.toList();
|
||||||
|
|
||||||
|
expect(states.length, 2 + 1);
|
||||||
|
|
||||||
|
expect(states[0], Right(GetAllEmailLoading()));
|
||||||
|
|
||||||
|
expect(
|
||||||
|
states[1],
|
||||||
|
Right(
|
||||||
|
GetAllEmailSuccess(
|
||||||
|
emailList: const [],
|
||||||
|
currentEmailState: null,
|
||||||
|
currentMailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
states[2],
|
||||||
|
Right(
|
||||||
|
GetAllEmailSuccess(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1.toPresentationEmail(),
|
||||||
|
EmailFixtures.email2.toPresentationEmail(),
|
||||||
|
],
|
||||||
|
currentEmailState: jmap.State('server_1'),
|
||||||
|
currentMailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'forceEmailQuery = true, should emit Failure when forceQueryAllEmailsForWeb throws exception',
|
||||||
|
() async {
|
||||||
|
final sort = <EmailComparator>{
|
||||||
|
EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false),
|
||||||
|
};
|
||||||
|
|
||||||
|
final emailFilter = EmailFilter(
|
||||||
|
filter: EmailFilterCondition(
|
||||||
|
inMailbox: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
mailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
when(threadRepository.forceQueryAllEmailsForWeb(
|
||||||
|
session: SessionFixtures.aliceSession,
|
||||||
|
accountId: AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
)).thenThrow(Exception('server_failed'));
|
||||||
|
|
||||||
|
final resultStream = getEmailsInMailboxInteractor.execute(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
forceEmailQuery: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
final states = await resultStream.toList();
|
||||||
|
|
||||||
|
expect(states[0], Right(GetAllEmailLoading()));
|
||||||
|
expect(states[1].isLeft(), true);
|
||||||
|
|
||||||
|
states[1].fold(
|
||||||
|
(failure) => expect(failure, isA<GetAllEmailFailure>()),
|
||||||
|
(_) => fail('Should not produce success'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'forceEmailQuery = false, should call getAllEmail() and not call forceQueryAllEmailsForWeb()',
|
||||||
|
() async {
|
||||||
|
final sort = <EmailComparator>{
|
||||||
|
EmailComparator(EmailComparatorProperty.sentAt)..setIsAscending(false),
|
||||||
|
};
|
||||||
|
|
||||||
|
final emailFilter = EmailFilter(
|
||||||
|
filter: EmailFilterCondition(
|
||||||
|
inMailbox: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
mailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
when(threadRepository.getAllEmail(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||||
|
getLatestChanges: true,
|
||||||
|
)).thenAnswer(
|
||||||
|
(_) => Stream<EmailsResponse>.fromIterable([
|
||||||
|
EmailsResponse(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1,
|
||||||
|
],
|
||||||
|
state: jmap.State('s1'),
|
||||||
|
),
|
||||||
|
EmailsResponse(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1,
|
||||||
|
EmailFixtures.email2,
|
||||||
|
EmailFixtures.email3,
|
||||||
|
],
|
||||||
|
state: jmap.State('s1'),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
final resultStream = getEmailsInMailboxInteractor.execute(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||||
|
forceEmailQuery: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
final states = await resultStream.toList();
|
||||||
|
|
||||||
|
expect(states.length, 3);
|
||||||
|
|
||||||
|
expect(states[0], Right(GetAllEmailLoading()));
|
||||||
|
|
||||||
|
expect(
|
||||||
|
states[1],
|
||||||
|
Right(
|
||||||
|
GetAllEmailSuccess(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1.toPresentationEmail(),
|
||||||
|
],
|
||||||
|
currentEmailState: jmap.State('s1'),
|
||||||
|
currentMailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
states[2],
|
||||||
|
Right(
|
||||||
|
GetAllEmailSuccess(
|
||||||
|
emailList: [
|
||||||
|
EmailFixtures.email1.toPresentationEmail(),
|
||||||
|
EmailFixtures.email2.toPresentationEmail(),
|
||||||
|
EmailFixtures.email3.toPresentationEmail(),
|
||||||
|
],
|
||||||
|
currentEmailState: jmap.State('s1'),
|
||||||
|
currentMailboxId: MailboxFixtures.inboxMailbox.id,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
verify(threadRepository.getAllEmail(
|
||||||
|
SessionFixtures.aliceSession,
|
||||||
|
AccountFixtures.aliceAccountId,
|
||||||
|
limit: UnsignedInt(20),
|
||||||
|
sort: sort,
|
||||||
|
emailFilter: emailFilter,
|
||||||
|
propertiesCreated: ThreadConstants.propertiesDefault,
|
||||||
|
propertiesUpdated: ThreadConstants.propertiesUpdatedDefault,
|
||||||
|
getLatestChanges: true,
|
||||||
|
)).called(1);
|
||||||
|
|
||||||
|
verifyNever(threadRepository.forceQueryAllEmailsForWeb(
|
||||||
|
session: SessionFixtures.aliceSession,
|
||||||
|
accountId: AccountFixtures.aliceAccountId,
|
||||||
|
limit: anyNamed('limit'),
|
||||||
|
sort: anyNamed('sort'),
|
||||||
|
emailFilter: anyNamed('emailFilter'),
|
||||||
|
propertiesCreated: anyNamed('propertiesCreated'),
|
||||||
|
));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user