Skip to content

Commit f1650fd

Browse files
Add Thread/get method (#109)
1 parent ad588c1 commit f1650fd

File tree

7 files changed

+267
-0
lines changed

7 files changed

+267
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import 'package:jmap_dart_client/http/converter/account_id_converter.dart';
2+
import 'package:jmap_dart_client/http/converter/id_converter.dart';
3+
import 'package:jmap_dart_client/http/converter/properties_converter.dart';
4+
import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart';
5+
import 'package:jmap_dart_client/jmap/core/method/request/get_method.dart';
6+
import 'package:jmap_dart_client/jmap/core/request/request_invocation.dart';
7+
import 'package:jmap_dart_client/jmap/core/request/result_reference.dart';
8+
import 'package:json_annotation/json_annotation.dart';
9+
10+
part 'get_thread_method.g.dart';
11+
12+
@JsonSerializable(
13+
includeIfNull: false,
14+
explicitToJson: true,
15+
converters: [
16+
AccountIdConverter(),
17+
IdConverter(),
18+
PropertiesConverter(),
19+
],
20+
)
21+
class GetThreadMethod extends GetMethod {
22+
GetThreadMethod(super.accountId);
23+
24+
@override
25+
MethodName get methodName => MethodName('Thread/get');
26+
27+
@override
28+
List<Object?> get props => [accountId, ids];
29+
30+
@override
31+
Set<CapabilityIdentifier> get requiredCapabilities => {
32+
CapabilityIdentifier.jmapCore,
33+
CapabilityIdentifier.jmapMail,
34+
};
35+
36+
@override
37+
Map<String, dynamic> toJson() => _$GetThreadMethodToJson(this);
38+
}

lib/jmap/thread/get/get_thread_method.g.dart

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import 'package:jmap_dart_client/http/converter/account_id_converter.dart';
2+
import 'package:jmap_dart_client/http/converter/id_converter.dart';
3+
import 'package:jmap_dart_client/http/converter/state_converter.dart';
4+
import 'package:jmap_dart_client/jmap/core/method/response/get_response.dart';
5+
import 'package:jmap_dart_client/jmap/thread/thread.dart';
6+
import 'package:json_annotation/json_annotation.dart';
7+
8+
part 'get_thread_response.g.dart';
9+
10+
@JsonSerializable(
11+
createToJson: false,
12+
includeIfNull: false,
13+
converters: [AccountIdConverter(), StateConverter(), IdConverter()],
14+
)
15+
class GetThreadResponse extends GetResponse<Thread> {
16+
GetThreadResponse(super.accountId, super.state, super.list, super.notFound);
17+
18+
@override
19+
List<Object?> get props => [accountId, state, list, notFound];
20+
21+
static GetThreadResponse deserialize(Map<String, dynamic> json)
22+
=> _$GetThreadResponseFromJson(json);
23+
}

lib/jmap/thread/get/get_thread_response.g.dart

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/jmap/thread/thread.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:jmap_dart_client/http/converter/email_id_converter.dart';
3+
import 'package:jmap_dart_client/http/converter/thread_id_converter.dart';
4+
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
5+
import 'package:json_annotation/json_annotation.dart';
6+
7+
part 'thread.g.dart';
8+
9+
@JsonSerializable(
10+
includeIfNull: false,
11+
converters: [ThreadIdConverter(), EmailIdConverter()],
12+
)
13+
class Thread with EquatableMixin {
14+
final ThreadId id;
15+
final List<EmailId> emailIds;
16+
17+
const Thread({required this.id, required this.emailIds});
18+
19+
factory Thread.fromJson(Map<String, dynamic> json) => _$ThreadFromJson(json);
20+
21+
Map<String, dynamic> toJson() => _$ThreadToJson(this);
22+
23+
@override
24+
List<Object?> get props => [id, emailIds];
25+
}

lib/jmap/thread/thread.g.dart

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import 'package:dio/dio.dart';
2+
import 'package:flutter_test/flutter_test.dart';
3+
import 'package:http_mock_adapter/http_mock_adapter.dart';
4+
import 'package:jmap_dart_client/http/http_client.dart';
5+
import 'package:jmap_dart_client/jmap/account_id.dart';
6+
import 'package:jmap_dart_client/jmap/core/id.dart';
7+
import 'package:jmap_dart_client/jmap/core/request/request_invocation.dart';
8+
import 'package:jmap_dart_client/jmap/core/state.dart';
9+
import 'package:jmap_dart_client/jmap/jmap_request.dart';
10+
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
11+
import 'package:jmap_dart_client/jmap/thread/get/get_thread_method.dart';
12+
import 'package:jmap_dart_client/jmap/thread/get/get_thread_response.dart';
13+
import 'package:jmap_dart_client/jmap/thread/thread.dart';
14+
15+
void main() {
16+
final baseOption = BaseOptions(method: 'POST');
17+
final dio = Dio(baseOption)..options.baseUrl = 'http://domain.com/jmap';
18+
final dioAdapter = DioAdapter(dio: dio);
19+
final dioAdapterHeaders = {"accept": "application/json;jmapVersion=rfc-8621"};
20+
final httpClient = HttpClient(dio);
21+
final processingInvocation = ProcessingInvocation();
22+
final requestBuilder = JmapRequestBuilder(httpClient, processingInvocation);
23+
final accountId = AccountId(Id('123abc'));
24+
final foundId = Id('found-thread-id');
25+
final emailIdFound = EmailId(Id('email-id-found'));
26+
final foundThread = Thread(id: ThreadId(foundId), emailIds: [emailIdFound]);
27+
final notFoundId = Id('not-found-thread-id');
28+
final getThreadMethod = GetThreadMethod(accountId)
29+
..addIds({foundId, notFoundId});
30+
final methodCallId = MethodCallId('c0');
31+
32+
group('get thread method test:', () {
33+
test(
34+
'should return list email id '
35+
'when thread found '
36+
'and return not found '
37+
'when thread not found',
38+
() async {
39+
// arrange
40+
final sampleRequest = {
41+
"using": getThreadMethod.requiredCapabilities
42+
.map((capability) => capability.value.toString())
43+
.toList(),
44+
"methodCalls": [
45+
[
46+
getThreadMethod.methodName.value,
47+
{
48+
"accountId": accountId.id.value,
49+
"ids": getThreadMethod.ids?.map((e) => e.value).toList(),
50+
},
51+
methodCallId.value
52+
]
53+
]
54+
};
55+
final sampleResponse = {
56+
"sessionState": "abcdefghij",
57+
"methodResponses": [
58+
[
59+
getThreadMethod.methodName.value,
60+
{
61+
"accountId": accountId.id.value,
62+
"state": "state",
63+
"list": [foundThread.toJson()],
64+
"notFound": [notFoundId.value],
65+
},
66+
methodCallId.value,
67+
]
68+
]
69+
};
70+
dioAdapter.onPost(
71+
'',
72+
(server) => server.reply(200, sampleResponse),
73+
data: sampleRequest,
74+
headers: dioAdapterHeaders
75+
);
76+
77+
// act
78+
final invocation = requestBuilder.invocation(
79+
getThreadMethod,
80+
methodCallId: methodCallId,
81+
);
82+
final response = (await (requestBuilder..usings(getThreadMethod.requiredCapabilities))
83+
.build()
84+
.execute())
85+
.parse(invocation.methodCallId, GetThreadResponse.deserialize);
86+
87+
// assert
88+
expect(
89+
response,
90+
equals(GetThreadResponse(
91+
accountId,
92+
State('state'),
93+
[foundThread],
94+
[notFoundId],
95+
)),
96+
);
97+
});
98+
});
99+
}

0 commit comments

Comments
 (0)