Files
sharedinbox/test/unit/undo_service_test.mocks.dart
T
Thomas SharedInboxandClaude Sonnet 4.6 69e358204d fix(undo): keep undo log entry and fix IMAP UID mismatch after sync (#81)
Two fixes for the UndoLog:

1. Don't delete the original undo log entry when undo is performed.
   The entry stays in the log alongside the new inverse action, so
   the user can retry the undo if it was silently reverted by an
   IMAP sync.

2. Fix IMAP UID mismatch: after an IMAP move is applied on the server
   the email gets a new UID in the destination folder. The undo service
   now looks up the email by its RFC 2822 Message-ID when the original
   row is gone, so the reverse-move pending change carries the correct
   UID and actually succeeds on the server.

Add findEmailByMessageId to EmailRepository interface and impl.
Add a regression test that simulates the UID change scenario.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 10:46:12 +02:00

587 lines
15 KiB
Dart

// Mocks generated by Mockito 5.4.6 from annotations
// in sharedinbox/test/unit/undo_service_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i4;
import 'package:mockito/mockito.dart' as _i1;
import 'package:mockito/src/dummies.dart' as _i5;
import 'package:sharedinbox/core/models/email.dart' as _i2;
import 'package:sharedinbox/core/models/undo_action.dart' as _i7;
import 'package:sharedinbox/core/repositories/email_repository.dart' as _i3;
import 'package:sharedinbox/core/repositories/undo_repository.dart' as _i6;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: deprecated_member_use
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: must_be_immutable
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
// ignore_for_file: invalid_use_of_internal_member
class _FakeEmailBody_0 extends _i1.SmartFake implements _i2.EmailBody {
_FakeEmailBody_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeSyncEmailsResult_1 extends _i1.SmartFake
implements _i2.SyncEmailsResult {
_FakeSyncEmailsResult_1(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeReliabilityResult_2 extends _i1.SmartFake
implements _i2.ReliabilityResult {
_FakeReliabilityResult_2(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
/// A class which mocks [EmailRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockEmailRepository extends _i1.Mock implements _i3.EmailRepository {
MockEmailRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i4.Stream<String> get onChangesQueued => (super.noSuchMethod(
Invocation.getter(#onChangesQueued),
returnValue: _i4.Stream<String>.empty(),
) as _i4.Stream<String>);
@override
_i4.Stream<List<_i2.Email>> observeEmails(
String? accountId,
String? mailboxPath, {
int? limit = 50,
}) =>
(super.noSuchMethod(
Invocation.method(
#observeEmails,
[
accountId,
mailboxPath,
],
{#limit: limit},
),
returnValue: _i4.Stream<List<_i2.Email>>.empty(),
) as _i4.Stream<List<_i2.Email>>);
@override
_i4.Stream<List<_i2.EmailThread>> observeThreads(
String? accountId,
String? mailboxPath, {
int? limit = 50,
}) =>
(super.noSuchMethod(
Invocation.method(
#observeThreads,
[
accountId,
mailboxPath,
],
{#limit: limit},
),
returnValue: _i4.Stream<List<_i2.EmailThread>>.empty(),
) as _i4.Stream<List<_i2.EmailThread>>);
@override
_i4.Stream<List<_i2.Email>> observeEmailsInThread(
String? accountId,
String? mailboxPath,
String? threadId,
) =>
(super.noSuchMethod(
Invocation.method(
#observeEmailsInThread,
[
accountId,
mailboxPath,
threadId,
],
),
returnValue: _i4.Stream<List<_i2.Email>>.empty(),
) as _i4.Stream<List<_i2.Email>>);
@override
_i4.Future<_i2.Email?> getEmail(String? emailId) => (super.noSuchMethod(
Invocation.method(
#getEmail,
[emailId],
),
returnValue: _i4.Future<_i2.Email?>.value(),
) as _i4.Future<_i2.Email?>);
@override
_i4.Future<_i2.EmailBody> getEmailBody(String? emailId) =>
(super.noSuchMethod(
Invocation.method(
#getEmailBody,
[emailId],
),
returnValue: _i4.Future<_i2.EmailBody>.value(_FakeEmailBody_0(
this,
Invocation.method(
#getEmailBody,
[emailId],
),
)),
) as _i4.Future<_i2.EmailBody>);
@override
_i4.Future<_i2.SyncEmailsResult> syncEmails(
String? accountId,
String? mailboxPath,
) =>
(super.noSuchMethod(
Invocation.method(
#syncEmails,
[
accountId,
mailboxPath,
],
),
returnValue:
_i4.Future<_i2.SyncEmailsResult>.value(_FakeSyncEmailsResult_1(
this,
Invocation.method(
#syncEmails,
[
accountId,
mailboxPath,
],
),
)),
) as _i4.Future<_i2.SyncEmailsResult>);
@override
_i4.Future<void> setFlag(
String? emailId, {
bool? seen,
bool? flagged,
}) =>
(super.noSuchMethod(
Invocation.method(
#setFlag,
[emailId],
{
#seen: seen,
#flagged: flagged,
},
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<void> markAllAsRead(
String? accountId,
String? mailboxPath,
) =>
(super.noSuchMethod(
Invocation.method(
#markAllAsRead,
[
accountId,
mailboxPath,
],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<void> moveEmail(
String? emailId,
String? destMailboxPath,
) =>
(super.noSuchMethod(
Invocation.method(
#moveEmail,
[
emailId,
destMailboxPath,
],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<String?> deleteEmail(String? emailId) => (super.noSuchMethod(
Invocation.method(
#deleteEmail,
[emailId],
),
returnValue: _i4.Future<String?>.value(),
) as _i4.Future<String?>);
@override
_i4.Future<void> sendEmail(
String? accountId,
_i2.EmailDraft? draft,
) =>
(super.noSuchMethod(
Invocation.method(
#sendEmail,
[
accountId,
draft,
],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<String> downloadAttachment(
String? emailId,
_i2.EmailAttachment? attachment,
) =>
(super.noSuchMethod(
Invocation.method(
#downloadAttachment,
[
emailId,
attachment,
],
),
returnValue: _i4.Future<String>.value(_i5.dummyValue<String>(
this,
Invocation.method(
#downloadAttachment,
[
emailId,
attachment,
],
),
)),
) as _i4.Future<String>);
@override
_i4.Future<String> fetchRawRfc822(String? emailId) => (super.noSuchMethod(
Invocation.method(
#fetchRawRfc822,
[emailId],
),
returnValue: _i4.Future<String>.value(_i5.dummyValue<String>(
this,
Invocation.method(
#fetchRawRfc822,
[emailId],
),
)),
) as _i4.Future<String>);
@override
_i4.Future<List<_i2.Email>> searchEmails(
String? accountId,
String? mailboxPath,
String? query,
) =>
(super.noSuchMethod(
Invocation.method(
#searchEmails,
[
accountId,
mailboxPath,
query,
],
),
returnValue: _i4.Future<List<_i2.Email>>.value(<_i2.Email>[]),
) as _i4.Future<List<_i2.Email>>);
@override
_i4.Future<List<_i2.Email>> searchEmailsGlobal(
String? accountId,
String? query,
) =>
(super.noSuchMethod(
Invocation.method(
#searchEmailsGlobal,
[
accountId,
query,
],
),
returnValue: _i4.Future<List<_i2.Email>>.value(<_i2.Email>[]),
) as _i4.Future<List<_i2.Email>>);
@override
_i4.Future<List<_i2.Email>> getEmailsByAddress(
String? accountId,
String? address,
) =>
(super.noSuchMethod(
Invocation.method(
#getEmailsByAddress,
[
accountId,
address,
],
),
returnValue: _i4.Future<List<_i2.Email>>.value(<_i2.Email>[]),
) as _i4.Future<List<_i2.Email>>);
@override
_i4.Future<List<_i2.EmailAddress>> searchAddresses(
String? accountId,
String? query, {
int? limit = 10,
}) =>
(super.noSuchMethod(
Invocation.method(
#searchAddresses,
[
accountId,
query,
],
{#limit: limit},
),
returnValue:
_i4.Future<List<_i2.EmailAddress>>.value(<_i2.EmailAddress>[]),
) as _i4.Future<List<_i2.EmailAddress>>);
@override
_i4.Future<int> flushPendingChanges(
String? accountId,
String? password,
) =>
(super.noSuchMethod(
Invocation.method(
#flushPendingChanges,
[
accountId,
password,
],
),
returnValue: _i4.Future<int>.value(0),
) as _i4.Future<int>);
@override
_i4.Stream<List<_i2.FailedMutation>> observeFailedMutations(
String? accountId) =>
(super.noSuchMethod(
Invocation.method(
#observeFailedMutations,
[accountId],
),
returnValue: _i4.Stream<List<_i2.FailedMutation>>.empty(),
) as _i4.Stream<List<_i2.FailedMutation>>);
@override
_i4.Future<void> discardMutation(int? id) => (super.noSuchMethod(
Invocation.method(
#discardMutation,
[id],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<void> retryMutation(int? id) => (super.noSuchMethod(
Invocation.method(
#retryMutation,
[id],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<bool> cancelPendingChange(
String? emailId,
String? changeType,
) =>
(super.noSuchMethod(
Invocation.method(
#cancelPendingChange,
[
emailId,
changeType,
],
),
returnValue: _i4.Future<bool>.value(false),
) as _i4.Future<bool>);
@override
_i4.Future<void> snoozeEmail(
String? emailId,
DateTime? until,
) =>
(super.noSuchMethod(
Invocation.method(
#snoozeEmail,
[
emailId,
until,
],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<int> wakeUpEmails(String? accountId) => (super.noSuchMethod(
Invocation.method(
#wakeUpEmails,
[accountId],
),
returnValue: _i4.Future<int>.value(0),
) as _i4.Future<int>);
@override
_i4.Future<void> restoreEmails(List<_i2.Email>? emails) =>
(super.noSuchMethod(
Invocation.method(
#restoreEmails,
[emails],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<_i2.Email?> findEmailByMessageId(
String? accountId,
String? messageId,
) =>
(super.noSuchMethod(
Invocation.method(
#findEmailByMessageId,
[
accountId,
messageId,
],
),
returnValue: _i4.Future<_i2.Email?>.value(),
) as _i4.Future<_i2.Email?>);
@override
_i4.Stream<void> watchJmapPush(
String? accountId,
String? password,
) =>
(super.noSuchMethod(
Invocation.method(
#watchJmapPush,
[
accountId,
password,
],
),
returnValue: _i4.Stream<void>.empty(),
) as _i4.Stream<void>);
@override
_i4.Future<_i2.ReliabilityResult> verifySyncReliability(
String? accountId,
String? mailboxPath,
) =>
(super.noSuchMethod(
Invocation.method(
#verifySyncReliability,
[
accountId,
mailboxPath,
],
),
returnValue:
_i4.Future<_i2.ReliabilityResult>.value(_FakeReliabilityResult_2(
this,
Invocation.method(
#verifySyncReliability,
[
accountId,
mailboxPath,
],
),
)),
) as _i4.Future<_i2.ReliabilityResult>);
@override
_i4.Future<void> clearForResync(String? accountId) => (super.noSuchMethod(
Invocation.method(
#clearForResync,
[accountId],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
}
/// A class which mocks [UndoRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockUndoRepository extends _i1.Mock implements _i6.UndoRepository {
MockUndoRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i4.Future<void> saveAction(_i7.UndoAction? action) => (super.noSuchMethod(
Invocation.method(
#saveAction,
[action],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<void> deleteAction(String? id) => (super.noSuchMethod(
Invocation.method(
#deleteAction,
[id],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
@override
_i4.Future<List<_i7.UndoAction>> getHistory({int? limit = 10}) =>
(super.noSuchMethod(
Invocation.method(
#getHistory,
[],
{#limit: limit},
),
returnValue: _i4.Future<List<_i7.UndoAction>>.value(<_i7.UndoAction>[]),
) as _i4.Future<List<_i7.UndoAction>>);
@override
_i4.Future<void> clearHistory() => (super.noSuchMethod(
Invocation.method(
#clearHistory,
[],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);
}