TF-145 Create and write unit-test for EmailCacheClient
This commit is contained in:
@@ -6,6 +6,8 @@ import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_cache.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_rights_cache.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/model/state_cache.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/model/state_type.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_address_hive_cache.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart';
|
||||
|
||||
class HiveCacheConfig {
|
||||
|
||||
@@ -29,5 +31,7 @@ class HiveCacheConfig {
|
||||
Hive.registerAdapter(MailboxRightsCacheAdapter());
|
||||
Hive.registerAdapter(StateCacheAdapter());
|
||||
Hive.registerAdapter(StateTypeAdapter());
|
||||
Hive.registerAdapter(EmailAddressHiveCacheAdapter());
|
||||
Hive.registerAdapter(EmailCacheAdapter());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:tmail_ui_user/features/caching/config/hive_cache_client.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart';
|
||||
|
||||
class EmailCacheClient extends HiveCacheClient<EmailCache> {
|
||||
|
||||
@override
|
||||
String get tableName => 'EmailCache';
|
||||
|
||||
@override
|
||||
Future<Box<EmailCache>> openBox() {
|
||||
return Future.sync(() async {
|
||||
if (Hive.isBoxOpen(tableName)) {
|
||||
return Hive.box<EmailCache>(tableName);
|
||||
}
|
||||
return await Hive.openBox<EmailCache>(tableName);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> isExistItem(String key) {
|
||||
return Future.sync(() async {
|
||||
final boxEmail = await openBox();
|
||||
return boxEmail.containsKey(key);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteItem(String key) {
|
||||
return Future.sync(() async {
|
||||
final boxEmail = await openBox();
|
||||
return boxEmail.delete(key);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<EmailCache?> getItem(String key) {
|
||||
return Future.sync(() async {
|
||||
final boxEmail = await openBox();
|
||||
return boxEmail.get(key);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<EmailCache>> getAll() {
|
||||
return Future.sync(() async {
|
||||
final boxEmail = await openBox();
|
||||
return boxEmail.values.toList();
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> insertItem(String key, EmailCache newObject) {
|
||||
return Future.sync(() async {
|
||||
final boxEmail = await openBox();
|
||||
boxEmail.put(key, newObject);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> insertMultipleItem(Map<String, EmailCache> mapObject) {
|
||||
return Future.sync(() async {
|
||||
final boxEmail = await openBox();
|
||||
boxEmail.putAll(mapObject);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateItem(String key, EmailCache newObject) {
|
||||
return Future.sync(() async {
|
||||
final boxEmail = await openBox();
|
||||
boxEmail.put(key, newObject);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> isExistTable() {
|
||||
return Future.sync(() async {
|
||||
return await Hive.boxExists(tableName);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteMultipleItem(List<String> listKey) {
|
||||
return Future.sync(() async {
|
||||
final boxEmail = await openBox();
|
||||
return boxEmail.deleteAll(listKey);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateMultipleItem(Map<String, EmailCache> mapObject) {
|
||||
return Future.sync(() async {
|
||||
final boxEmail = await openBox();
|
||||
boxEmail.putAll(mapObject);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_address_hive_cache.dart';
|
||||
|
||||
extension EmailAddressExtension on EmailAddress {
|
||||
|
||||
EmailAddressHiveCache toEmailAddressHiveCache() => EmailAddressHiveCache(name, email);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/model/email_cache.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/extensions/map_keywords_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/extensions/email_address_extension.dart';
|
||||
|
||||
extension EmailExtension on Email {
|
||||
|
||||
EmailCache toEmailCache() {
|
||||
return EmailCache(
|
||||
id.toString(),
|
||||
keywords: keywords?.toMapString(),
|
||||
size: size?.value.round(),
|
||||
receivedAt: receivedAt?.value,
|
||||
hasAttachment: hasAttachment,
|
||||
preview: preview,
|
||||
subject: subject,
|
||||
sentAt: sentAt?.value,
|
||||
from: from?.map((emailAddress) => emailAddress.toEmailAddressHiveCache()).toList(),
|
||||
to: to?.map((emailAddress) => emailAddress.toEmailAddressHiveCache()).toList(),
|
||||
cc: cc?.map((emailAddress) => emailAddress.toEmailAddressHiveCache()).toList(),
|
||||
bcc: bcc?.map((emailAddress) => emailAddress.toEmailAddressHiveCache()).toList(),
|
||||
replyTo: replyTo?.map((emailAddress) => emailAddress.toEmailAddressHiveCache()).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
|
||||
|
||||
extension MapKeywordsExtension on Map<KeyWordIdentifier, bool> {
|
||||
|
||||
Map<String, bool> toMapString() => Map.fromIterables(keys.map((keyword) => keyword.value), values);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'email_address_hive_cache.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// TypeAdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class EmailAddressHiveCacheAdapter extends TypeAdapter<EmailAddressHiveCache> {
|
||||
@override
|
||||
final int typeId = 6;
|
||||
|
||||
@override
|
||||
EmailAddressHiveCache read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return EmailAddressHiveCache(
|
||||
fields[0] as String?,
|
||||
fields[1] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, EmailAddressHiveCache obj) {
|
||||
writer
|
||||
..writeByte(2)
|
||||
..writeByte(0)
|
||||
..write(obj.name)
|
||||
..writeByte(1)
|
||||
..write(obj.email);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is EmailAddressHiveCacheAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'email_cache.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// TypeAdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class EmailCacheAdapter extends TypeAdapter<EmailCache> {
|
||||
@override
|
||||
final int typeId = 5;
|
||||
|
||||
@override
|
||||
EmailCache read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return EmailCache(
|
||||
fields[0] as String,
|
||||
keywords: (fields[1] as Map?)?.cast<String, bool>(),
|
||||
size: fields[2] as int?,
|
||||
receivedAt: fields[3] as DateTime?,
|
||||
hasAttachment: fields[4] as bool?,
|
||||
preview: fields[5] as String?,
|
||||
subject: fields[6] as String?,
|
||||
sentAt: fields[7] as DateTime?,
|
||||
from: (fields[8] as List?)?.cast<EmailAddressHiveCache>(),
|
||||
to: (fields[9] as List?)?.cast<EmailAddressHiveCache>(),
|
||||
cc: (fields[10] as List?)?.cast<EmailAddressHiveCache>(),
|
||||
bcc: (fields[11] as List?)?.cast<EmailAddressHiveCache>(),
|
||||
replyTo: (fields[12] as List?)?.cast<EmailAddressHiveCache>(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, EmailCache obj) {
|
||||
writer
|
||||
..writeByte(13)
|
||||
..writeByte(0)
|
||||
..write(obj.id)
|
||||
..writeByte(1)
|
||||
..write(obj.keywords)
|
||||
..writeByte(2)
|
||||
..write(obj.size)
|
||||
..writeByte(3)
|
||||
..write(obj.receivedAt)
|
||||
..writeByte(4)
|
||||
..write(obj.hasAttachment)
|
||||
..writeByte(5)
|
||||
..write(obj.preview)
|
||||
..writeByte(6)
|
||||
..write(obj.subject)
|
||||
..writeByte(7)
|
||||
..write(obj.sentAt)
|
||||
..writeByte(8)
|
||||
..write(obj.from)
|
||||
..writeByte(9)
|
||||
..write(obj.to)
|
||||
..writeByte(10)
|
||||
..write(obj.cc)
|
||||
..writeByte(11)
|
||||
..write(obj.bcc)
|
||||
..writeByte(12)
|
||||
..write(obj.replyTo);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is EmailCacheAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart';
|
||||
import 'package:tmail_ui_user/features/caching/email_cache_client.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/extensions/email_extension.dart';
|
||||
|
||||
import '../../fixtures/email_fixtures.dart';
|
||||
|
||||
void main() {
|
||||
|
||||
late EmailCacheClient _emailCacheClient;
|
||||
|
||||
setUpAll(() {
|
||||
HiveCacheConfig().setUp(cachePath: Directory.current.path);
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
_emailCacheClient = EmailCacheClient();
|
||||
});
|
||||
|
||||
group('[delete]', () {
|
||||
test('cache should delete item successfully when cache empty', () async {
|
||||
await _emailCacheClient.deleteItem(EmailFixtures.email1.id.toString());
|
||||
|
||||
final remainingItems = await _emailCacheClient.getAll();
|
||||
|
||||
expect(remainingItems.length, equals(0));
|
||||
});
|
||||
|
||||
test('cache should not delete item which not in the list', () async {
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email1.toEmailCache());
|
||||
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email2.id.toString(),
|
||||
EmailFixtures.email2.toEmailCache());
|
||||
|
||||
await _emailCacheClient.deleteItem(EmailFixtures.email3.id.toString());
|
||||
|
||||
final remainingItems = await _emailCacheClient.getAll();
|
||||
|
||||
expect(remainingItems.length, equals(2));
|
||||
expect(
|
||||
remainingItems,
|
||||
containsAll({
|
||||
EmailFixtures.email1.toEmailCache(),
|
||||
EmailFixtures.email2.toEmailCache()
|
||||
}));
|
||||
});
|
||||
|
||||
test('cache should delete item successfully', () async {
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email1.toEmailCache());
|
||||
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email2.id.toString(),
|
||||
EmailFixtures.email2.toEmailCache());
|
||||
|
||||
await _emailCacheClient.deleteItem(EmailFixtures.email1.id.toString());
|
||||
|
||||
final remainingItems = await _emailCacheClient.getAll();
|
||||
|
||||
expect(remainingItems.length, equals(1));
|
||||
expect(remainingItems.first, equals(EmailFixtures.email2.toEmailCache()));
|
||||
});
|
||||
|
||||
test('cache should not delete item twice', () async {
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email1.toEmailCache());
|
||||
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email2.id.toString(),
|
||||
EmailFixtures.email2.toEmailCache());
|
||||
|
||||
await _emailCacheClient.deleteItem(EmailFixtures.email1.id.toString());
|
||||
await _emailCacheClient.deleteItem(EmailFixtures.email1.id.toString());
|
||||
|
||||
final remainingItems = await _emailCacheClient.getAll();
|
||||
|
||||
expect(remainingItems.length, equals(1));
|
||||
expect(remainingItems.first, equals(EmailFixtures.email2.toEmailCache()));
|
||||
});
|
||||
});
|
||||
|
||||
group('[add]', () {
|
||||
test('cache should add item when cache empty', () async {
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email1.toEmailCache());
|
||||
|
||||
final remainingItems = await _emailCacheClient.getAll();
|
||||
|
||||
expect(remainingItems.length, equals(1));
|
||||
expect(remainingItems.first, equals(EmailFixtures.email1.toEmailCache()));
|
||||
});
|
||||
|
||||
test('cache should add item when cache not empty', () async {
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email1.toEmailCache());
|
||||
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email2.id.toString(),
|
||||
EmailFixtures.email2.toEmailCache());
|
||||
|
||||
final remainingItems = await _emailCacheClient.getAll();
|
||||
|
||||
expect(remainingItems.length, equals(2));
|
||||
expect(
|
||||
remainingItems,
|
||||
containsAll({
|
||||
EmailFixtures.email1.toEmailCache(),
|
||||
EmailFixtures.email2.toEmailCache()
|
||||
}));
|
||||
});
|
||||
|
||||
test('cache should not add item twice', () async {
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email1.toEmailCache());
|
||||
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email1.toEmailCache());
|
||||
|
||||
final remainingItems = await _emailCacheClient.getAll();
|
||||
|
||||
expect(remainingItems.length, equals(1));
|
||||
expect(
|
||||
remainingItems,
|
||||
containsAll({
|
||||
EmailFixtures.email1.toEmailCache(),
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
group('[update]', () {
|
||||
test('cache should update item when update to iem which not in cache', () async {
|
||||
await _emailCacheClient.updateItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email1.toEmailCache());
|
||||
|
||||
final remainingItems = await _emailCacheClient.getAll();
|
||||
|
||||
expect(remainingItems.length, equals(1));
|
||||
expect(remainingItems.first, equals(EmailFixtures.email1.toEmailCache()));
|
||||
});
|
||||
|
||||
test('cache should update correctly item', () async {
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email1.toEmailCache());
|
||||
|
||||
await _emailCacheClient.insertItem(
|
||||
EmailFixtures.email2.id.toString(),
|
||||
EmailFixtures.email2.toEmailCache());
|
||||
|
||||
await _emailCacheClient.updateItem(
|
||||
EmailFixtures.email1.id.toString(),
|
||||
EmailFixtures.email3.toEmailCache());
|
||||
|
||||
final remainingItems = await _emailCacheClient.getAll();
|
||||
|
||||
expect(remainingItems.length, equals(2));
|
||||
expect(
|
||||
remainingItems,
|
||||
containsAll({
|
||||
EmailFixtures.email2.toEmailCache(),
|
||||
EmailFixtures.email3.toEmailCache()
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await _emailCacheClient.deleteBox();
|
||||
});
|
||||
}
|
||||
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
|
||||
|
||||
class EmailFixtures {
|
||||
static final email1 = Email(
|
||||
EmailId(Id("382312d0-fa5c-11eb-b647-2fef1ee78d9e")),
|
||||
preview: "Dear QA,I attached image here",
|
||||
hasAttachment: false,
|
||||
subject: "test inline image",
|
||||
from: {EmailAddress("DatPH", "dphamhoang@linagora.com")},
|
||||
sentAt: UTCDate(DateTime.parse("2021-08-11T04:25:34Z")),
|
||||
receivedAt: UTCDate(DateTime.parse("2021-08-11T04:25:55Z")),
|
||||
keywords: {KeyWordIdentifier.emailSeen : true},
|
||||
to: {EmailAddress("DatVu", "tdvu@linagora.com")},
|
||||
);
|
||||
|
||||
static final email2 = Email(
|
||||
EmailId(Id("bc8a5320-fa58-11eb-b647-2fef1ee78d9e")),
|
||||
preview: "This event is about to begin Noti check TimeFriday 23 October 2020 12:00 - 12:30 Europe/Paris (See in Calendar)Location1 thai ha (See in Map)Attendees - User A <usera@qa.open-paas.org> (Organizer) - Lê Nguyễn <userb@qa.open-paas.org> - User C <userc@qa.ope",
|
||||
hasAttachment: false,
|
||||
subject: "Notification: Noti check",
|
||||
from: {EmailAddress(null, "noreply@qa.open-paas.org")},
|
||||
sentAt: UTCDate(DateTime.parse("2021-08-10T09:45:01Z")),
|
||||
receivedAt: UTCDate(DateTime.parse("2021-08-11T04:00:59Z")),
|
||||
to: {EmailAddress("DatVu", "tdvu@facebook.com")},
|
||||
);
|
||||
|
||||
static final email3 = Email(
|
||||
EmailId(Id("ba7e0860-fa58-11eb-b647-2fef1ee78d9e")),
|
||||
preview: "This event is about to begin Recurrencr TimeWednesday 26 August 2020 05:30 - 06:30 Europe/Paris (See in Calendar)Location1 thai ha (See in Map)Attendees - userb@qa.open-paas.org <userb@qa.open-paas.org> (Organizer) - User A <usera@qa.open-paas.org> Resourc",
|
||||
hasAttachment: false,
|
||||
subject: "Notification: Recurrencr",
|
||||
from: {EmailAddress(null, "noreply@qa.open-paas.org")},
|
||||
sentAt: UTCDate(DateTime.parse("2021-08-11T03:00:00Z")),
|
||||
receivedAt: UTCDate(DateTime.parse("2021-08-11T04:00:55Z")),
|
||||
keywords: {KeyWordIdentifier.emailFlagged : true},
|
||||
to: {EmailAddress("DatVu", "tdvu@gmail.com")},
|
||||
);
|
||||
|
||||
static final email4 = Email(
|
||||
EmailId(Id("d9b3b880-fa6f-11eb-b647-2fef1ee78d9e")),
|
||||
preview: "alo -- desktop signature",
|
||||
hasAttachment: true,
|
||||
subject: "test attachment",
|
||||
from: {EmailAddress("Haaheoo", "userc@qa.open-paas.org")},
|
||||
sentAt: UTCDate(DateTime.parse("2021-08-11T06:46:25Z")),
|
||||
receivedAt: UTCDate(DateTime.parse("2021-08-11T06:46:26Z")),
|
||||
keywords: {KeyWordIdentifier.emailFlagged : true},
|
||||
to: {EmailAddress("DatVu", "tdvu@icloud.com")},
|
||||
);
|
||||
|
||||
static final email5 = Email(
|
||||
EmailId(Id("637f1ef0-fa5d-11eb-b647-2fef1ee78d9e")),
|
||||
preview: "Dear, test inline Thanks and BRs-- desktop signature",
|
||||
hasAttachment: false,
|
||||
subject: "test inline image",
|
||||
from: {EmailAddress("Haaheoo", "userc@qa.open-paas.org")},
|
||||
sentAt: UTCDate(DateTime.parse("2021-08-11T04:34:13Z")),
|
||||
receivedAt: UTCDate(DateTime.parse("2021-08-11T04:34:17Z")),
|
||||
keywords: {KeyWordIdentifier.emailSeen : true},
|
||||
to: {EmailAddress("DatVu", "tdvu@yahoo.com")},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user