TF-3260 Parsing Linagora Ecosystem in AppGrid

This commit is contained in:
dab246
2024-12-06 14:48:05 +07:00
committed by Dat H. Pham
parent e91f1bbc6a
commit 95f05c4715
14 changed files with 473 additions and 0 deletions
@@ -0,0 +1,19 @@
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/converters/api_key_linagora_ecosystem_converter.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_properties.dart';
class ApiKeyLinagoraEcosystem extends LinagoraEcosystemProperties {
final String value;
ApiKeyLinagoraEcosystem(this.value);
static LinagoraEcosystemProperties? deserialize(dynamic json) {
if (json is String) {
return const ApiKeyLinagoraEcosystemConverter().fromJson(json);
} else {
return null;
}
}
@override
List<Object?> get props => [value];
}
@@ -0,0 +1,20 @@
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/converters/api_url_linagora_ecosystem_converter.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/empty_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_properties.dart';
class ApiUrlLinagoraEcosystem extends LinagoraEcosystemProperties {
final String value;
ApiUrlLinagoraEcosystem(this.value);
static LinagoraEcosystemProperties? deserialize(dynamic json) {
if (json is String) {
return const ApiUrlLinagoraEcosystemConverter().fromJson(json);
} else {
return EmptyLinagoraEcosystem();
}
}
@override
List<Object?> get props => [value];
}
@@ -0,0 +1,46 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/empty_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_properties.dart';
part 'app_linagora_ecosystem.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class AppLinagoraEcosystem extends LinagoraEcosystemProperties {
final String? appName;
final String? logoURL;
final String? androidPackageId;
final String? iosUrlScheme;
final String? iosAppStoreLink;
final String? webLink;
AppLinagoraEcosystem({
this.appName,
this.logoURL,
this.androidPackageId,
this.iosUrlScheme,
this.iosAppStoreLink,
this.webLink,
});
factory AppLinagoraEcosystem.fromJson(Map<String, dynamic> json) => _$AppLinagoraEcosystemFromJson(json);
Map<String, dynamic> toJson() => _$AppLinagoraEcosystemToJson(this);
static LinagoraEcosystemProperties? deserialize(dynamic json) {
if (json is Map<String, dynamic>) {
return AppLinagoraEcosystem.fromJson(json);
} else {
return EmptyLinagoraEcosystem();
}
}
@override
List<Object?> get props => [
appName,
logoURL,
androidPackageId,
iosUrlScheme,
iosAppStoreLink,
webLink,
];
}
@@ -0,0 +1,12 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/api_key_linagora_ecosystem.dart';
class ApiKeyLinagoraEcosystemConverter implements JsonConverter<ApiKeyLinagoraEcosystem?, String?> {
const ApiKeyLinagoraEcosystemConverter();
@override
ApiKeyLinagoraEcosystem? fromJson(String? json) => json != null ? ApiKeyLinagoraEcosystem(json) : null;
@override
String? toJson(ApiKeyLinagoraEcosystem? object) => object?.value;
}
@@ -0,0 +1,12 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/api_url_linagora_ecosystem.dart';
class ApiUrlLinagoraEcosystemConverter implements JsonConverter<ApiUrlLinagoraEcosystem?, String?> {
const ApiUrlLinagoraEcosystemConverter();
@override
ApiUrlLinagoraEcosystem? fromJson(String? json) => json != null ? ApiUrlLinagoraEcosystem(json) : null;
@override
String? toJson(ApiUrlLinagoraEcosystem? object) => object?.value;
}
@@ -0,0 +1,62 @@
import 'package:built_collection/built_collection.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/api_key_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/api_url_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/app_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/converters/mobile_apps_linagora_ecosystem_converter.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/default_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/empty_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_identifier.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_properties.dart';
class LinagoraEcosystemConverter {
static final defaultConverter = LinagoraEcosystemConverter();
BuiltMap<LinagoraEcosystemIdentifier, LinagoraEcosystemProperties? Function(dynamic)>? _mapLinagoraEcosystemConverter;
final mapLinagoraEcosystemConverterBuilder = MapBuilder<LinagoraEcosystemIdentifier, LinagoraEcosystemProperties? Function(dynamic)>();
LinagoraEcosystemConverter() {
mapLinagoraEcosystemConverterBuilder.addAll(
{
LinagoraEcosystemIdentifier.linShareApiUrl: ApiUrlLinagoraEcosystem.deserialize,
LinagoraEcosystemIdentifier.linToApiUrl: ApiUrlLinagoraEcosystem.deserialize,
LinagoraEcosystemIdentifier.twakeApiUrl: ApiUrlLinagoraEcosystem.deserialize,
LinagoraEcosystemIdentifier.linToApiKey: ApiKeyLinagoraEcosystem.deserialize,
LinagoraEcosystemIdentifier.twakeDrive: AppLinagoraEcosystem.deserialize,
LinagoraEcosystemIdentifier.twakeChat: AppLinagoraEcosystem.deserialize,
LinagoraEcosystemIdentifier.twakeSync: AppLinagoraEcosystem.deserialize,
LinagoraEcosystemIdentifier.linShare: AppLinagoraEcosystem.deserialize,
LinagoraEcosystemIdentifier.mobileApps: MobileAppsLinagoraEcosystemConverter.deserialize,
});
}
void build() {
_mapLinagoraEcosystemConverter = mapLinagoraEcosystemConverterBuilder.build();
}
MapEntry<LinagoraEcosystemIdentifier, LinagoraEcosystemProperties?> convert(String key, dynamic value) {
if (_mapLinagoraEcosystemConverter == null) {
build();
}
final identifier = LinagoraEcosystemIdentifier(key);
if (_mapLinagoraEcosystemConverter!.containsKey(identifier)) {
try {
return MapEntry(identifier, _mapLinagoraEcosystemConverter![identifier]!.call(value));
} catch (e) {
return MapEntry(identifier, EmptyLinagoraEcosystem());
}
} else {
if (value is Map<String, dynamic>) {
return MapEntry(identifier, AppLinagoraEcosystem.deserialize(value));
} else {
return MapEntry(identifier, DefaultLinagoraEcosystem(value));
}
}
}
static LinagoraEcosystem deserialize(Map<String, dynamic>? json) {
final apps = json?.map((key, value) => defaultConverter.convert(key, value));
return LinagoraEcosystem(apps);
}
}
@@ -0,0 +1,15 @@
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/converters/linagora_ecosystem_converter.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/mobile_apps_linagora_ecosystem.dart';
class MobileAppsLinagoraEcosystemConverter extends LinagoraEcosystemConverter {
static final defaultConverter = MobileAppsLinagoraEcosystemConverter();
static MobileAppsLinagoraEcosystem? deserialize(dynamic json) {
if (json is Map<String, dynamic>) {
final apps = json.map((key, value) => defaultConverter.convert(key, value));
return MobileAppsLinagoraEcosystem(apps);
} else {
return null;
}
}
}
@@ -0,0 +1,20 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_properties.dart';
part 'default_linagora_ecosystem.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false)
class DefaultLinagoraEcosystem extends LinagoraEcosystemProperties with EquatableMixin {
final dynamic properties;
DefaultLinagoraEcosystem(this.properties);
factory DefaultLinagoraEcosystem.fromJson(Map<String, dynamic> json) => _$DefaultLinagoraEcosystemFromJson(json);
Map<String, dynamic> toJson() => _$DefaultLinagoraEcosystemToJson(this);
@override
List<Object?> get props => [properties];
}
@@ -0,0 +1,18 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_properties.dart';
part 'empty_linagora_ecosystem.g.dart';
@JsonSerializable()
class EmptyLinagoraEcosystem extends LinagoraEcosystemProperties {
EmptyLinagoraEcosystem();
factory EmptyLinagoraEcosystem.fromJson(Map<String, dynamic> json) => _$EmptyLinagoraEcosystemFromJson(json);
Map<String, dynamic> toJson() => _$EmptyLinagoraEcosystemToJson(this);
@override
List<Object?> get props => [];
}
@@ -0,0 +1,18 @@
import 'package:equatable/equatable.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/converters/linagora_ecosystem_converter.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_identifier.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_properties.dart';
class LinagoraEcosystem with EquatableMixin {
final Map<LinagoraEcosystemIdentifier, LinagoraEcosystemProperties?>? properties;
LinagoraEcosystem(this.properties);
factory LinagoraEcosystem.deserialize(Map<String, dynamic>? json) {
return LinagoraEcosystemConverter.deserialize(json);
}
@override
List<Object?> get props => [properties];
}
@@ -0,0 +1,21 @@
import 'package:equatable/equatable.dart';
class LinagoraEcosystemIdentifier with EquatableMixin {
static final linShareApiUrl = LinagoraEcosystemIdentifier('linShareApiUrl');
static final linToApiUrl = LinagoraEcosystemIdentifier('linToApiUrl');
static final twakeApiUrl = LinagoraEcosystemIdentifier('twakeApiUrl');
static final linToApiKey = LinagoraEcosystemIdentifier('linToApiKey');
static final mobileApps = LinagoraEcosystemIdentifier('mobileApps');
static final twakeDrive = LinagoraEcosystemIdentifier('Twake Drive');
static final twakeChat = LinagoraEcosystemIdentifier('Twake Chat');
static final twakeSync = LinagoraEcosystemIdentifier('Twake Sync');
static final linShare = LinagoraEcosystemIdentifier('LinShare');
final String value;
LinagoraEcosystemIdentifier(this.value);
@override
List<Object?> get props => [value];
}
@@ -0,0 +1,4 @@
import 'package:equatable/equatable.dart';
abstract class LinagoraEcosystemProperties with EquatableMixin {}
@@ -0,0 +1,11 @@
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_identifier.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_properties.dart';
class MobileAppsLinagoraEcosystem extends LinagoraEcosystemProperties {
final Map<LinagoraEcosystemIdentifier, LinagoraEcosystemProperties?>? apps;
MobileAppsLinagoraEcosystem(this.apps);
@override
List<Object?> get props => [apps];
}
@@ -0,0 +1,195 @@
import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/api_key_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/api_url_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/app_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/default_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/empty_linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/linagora_ecosystem_identifier.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/linagora_ecosystem/mobile_apps_linagora_ecosystem.dart';
void main() {
group('Deserialize LinagoraEcosystem test', () {
test('Should parse correctly when all properties are present', () {
const linagoraEcosystemString = '''
{
"linShareApiUrl": "https://example.com/api",
"linToApiUrl": "https://example.com/api",
"linToApiKey": "apiKey",
"twakeApiUrl": "https://example.com/api",
"Twake Drive": {
"appName": "Twake Drive",
"logoURL": "https://xyz",
"webLink": "https://abc"
},
"mobileApps": {
"Twake Chat": {
"appName": "Twake Chat",
"logoURL": "https://xyz",
"androidPackageId": "com.example.android",
"iosUrlScheme": "app.scheme",
"iosAppStoreLink": "itms-apps://itunes.apple.com/app"
},
"Twake Sync": {
"appName": "Twake Sync",
"logoURL": "https://xyz",
"androidPackageId": "com.example.android"
},
"LinShare": {
"appName": "LinShare",
"logoURL": "https://xyz",
"androidPackageId": "com.example.android",
"iosUrlScheme": "app.scheme",
"iosAppStoreLink": "itms-apps://itunes.apple.com/app"
}
}
}
''';
final expectedLinagoraEcosystem = LinagoraEcosystem({
LinagoraEcosystemIdentifier.linShareApiUrl: ApiUrlLinagoraEcosystem('https://example.com/api'),
LinagoraEcosystemIdentifier.linToApiUrl: ApiUrlLinagoraEcosystem('https://example.com/api'),
LinagoraEcosystemIdentifier.linToApiKey: ApiKeyLinagoraEcosystem('apiKey'),
LinagoraEcosystemIdentifier.twakeApiUrl: ApiUrlLinagoraEcosystem('https://example.com/api'),
LinagoraEcosystemIdentifier.twakeDrive: AppLinagoraEcosystem(
appName: 'Twake Drive',
logoURL: 'https://xyz',
webLink: 'https://abc',
),
LinagoraEcosystemIdentifier.mobileApps: MobileAppsLinagoraEcosystem({
LinagoraEcosystemIdentifier.twakeChat: AppLinagoraEcosystem(
appName: 'Twake Chat',
logoURL: 'https://xyz',
androidPackageId: 'com.example.android',
iosUrlScheme: 'app.scheme',
iosAppStoreLink: 'itms-apps://itunes.apple.com/app',
),
LinagoraEcosystemIdentifier.twakeSync: AppLinagoraEcosystem(
appName: 'Twake Sync',
logoURL: 'https://xyz',
androidPackageId: 'com.example.android',
),
LinagoraEcosystemIdentifier.linShare: AppLinagoraEcosystem(
appName: 'LinShare',
logoURL: 'https://xyz',
androidPackageId: 'com.example.android',
iosUrlScheme: 'app.scheme',
iosAppStoreLink: 'itms-apps://itunes.apple.com/app',
),
}),
});
final parsedLinagoraEcosystem = LinagoraEcosystem.deserialize(json.decode(linagoraEcosystemString));
expect(parsedLinagoraEcosystem, equals(expectedLinagoraEcosystem));
});
test('Should parse correctly when some properties are null', () {
const linagoraEcosystemString = '''
{
"linShareApiUrl": "https://example.com/api",
"linToApiUrl": null,
"linToApiKey": "apiKey",
"twakeApiUrl": "https://example.com/api",
"Twake Drive": null,
"mobileApps": {
"Twake Chat": {
"appName": "Twake Chat",
"logoURL": "https://xyz",
"androidPackageId": "com.example.android",
"iosUrlScheme": "app.scheme",
"iosAppStoreLink": "itms-apps://itunes.apple.com/app"
},
"Twake Sync": null,
"LinShare": {
"appName": "LinShare",
"logoURL": "https://xyz",
"androidPackageId": "com.example.android",
"iosUrlScheme": "app.scheme",
"iosAppStoreLink": "itms-apps://itunes.apple.com/app"
}
}
}
''';
final expectedLinagoraEcosystem = LinagoraEcosystem({
LinagoraEcosystemIdentifier.linShareApiUrl: ApiUrlLinagoraEcosystem('https://example.com/api'),
LinagoraEcosystemIdentifier.linToApiUrl: EmptyLinagoraEcosystem(),
LinagoraEcosystemIdentifier.linToApiKey: ApiKeyLinagoraEcosystem('apiKey'),
LinagoraEcosystemIdentifier.twakeApiUrl: ApiUrlLinagoraEcosystem('https://example.com/api'),
LinagoraEcosystemIdentifier.twakeDrive: EmptyLinagoraEcosystem(),
LinagoraEcosystemIdentifier.mobileApps: MobileAppsLinagoraEcosystem({
LinagoraEcosystemIdentifier.twakeChat: AppLinagoraEcosystem(
appName: 'Twake Chat',
logoURL: 'https://xyz',
androidPackageId: 'com.example.android',
iosUrlScheme: 'app.scheme',
iosAppStoreLink: 'itms-apps://itunes.apple.com/app',
),
LinagoraEcosystemIdentifier.twakeSync: EmptyLinagoraEcosystem(),
LinagoraEcosystemIdentifier.linShare: AppLinagoraEcosystem(
appName: 'LinShare',
logoURL: 'https://xyz',
androidPackageId: 'com.example.android',
iosUrlScheme: 'app.scheme',
iosAppStoreLink: 'itms-apps://itunes.apple.com/app',
),
}),
});
final parsedLinagoraEcosystem = LinagoraEcosystem.deserialize(json.decode(linagoraEcosystemString));
expect(parsedLinagoraEcosystem, equals(expectedLinagoraEcosystem));
});
test('Should parse correctly when some properties are not default', () {
const linagoraEcosystemString = '''
{
"abc": "https://example.com/api",
"custom": "apiKey",
"twakeApiUrl": "https://example.com/api",
"mobileApps": {
"Twake Chat": {
"appName": "Twake Chat",
"logoURL": "https://xyz",
"androidPackageId": "com.example.android",
"iosUrlScheme": "app.scheme",
"iosAppStoreLink": "itms-apps://itunes.apple.com/app"
},
"xyz": {
"appName": "LinShare",
"logoURL": "https://xyz"
},
"dab": "test"
}
}
''';
final expectedLinagoraEcosystem = LinagoraEcosystem({
LinagoraEcosystemIdentifier('abc'): DefaultLinagoraEcosystem('https://example.com/api'),
LinagoraEcosystemIdentifier('custom'): DefaultLinagoraEcosystem('apiKey'),
LinagoraEcosystemIdentifier.twakeApiUrl: ApiUrlLinagoraEcosystem('https://example.com/api'),
LinagoraEcosystemIdentifier.mobileApps: MobileAppsLinagoraEcosystem({
LinagoraEcosystemIdentifier.twakeChat: AppLinagoraEcosystem(
appName: 'Twake Chat',
logoURL: 'https://xyz',
androidPackageId: 'com.example.android',
iosUrlScheme: 'app.scheme',
iosAppStoreLink: 'itms-apps://itunes.apple.com/app',
),
LinagoraEcosystemIdentifier('xyz'): AppLinagoraEcosystem(
appName: 'LinShare',
logoURL: 'https://xyz'
),
LinagoraEcosystemIdentifier('dab'): DefaultLinagoraEcosystem('test'),
}),
});
final parsedLinagoraEcosystem = LinagoraEcosystem.deserialize(json.decode(linagoraEcosystemString));
expect(parsedLinagoraEcosystem, equals(expectedLinagoraEcosystem));
});
});
}