Skip to content

Commit 92084c0

Browse files
committed
test(paynym): add PayNym.rs POST tests for endpoints
TODO: refactor `paynym_is`->`paynym_rs` chore: dart format
1 parent 0471b6d commit 92084c0

2 files changed

Lines changed: 344 additions & 0 deletions

File tree

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
import 'dart:convert';
2+
3+
import 'package:flutter_test/flutter_test.dart';
4+
import 'package:mockito/annotations.dart';
5+
import 'package:mockito/mockito.dart';
6+
import 'package:stackwallet/networking/http.dart';
7+
import 'package:stackwallet/utilities/paynym_is_api.dart';
8+
9+
import 'paynym_is_api_test.mocks.dart';
10+
11+
@GenerateMocks([HTTP])
12+
void main() {
13+
late PaynymIsApi api;
14+
late MockHTTP client;
15+
16+
setUp(() {
17+
client = MockHTTP();
18+
api = PaynymIsApi();
19+
api.client = client;
20+
});
21+
22+
void stubPost(
23+
String endpoint,
24+
String responseBody,
25+
int statusCode, {
26+
Map<String, String>? extraHeaders,
27+
}) {
28+
when(
29+
client.post(
30+
url: Uri.parse('https://paynym.rs/api/v1$endpoint'),
31+
headers: anyNamed('headers'),
32+
proxyInfo: anyNamed('proxyInfo'),
33+
body: anyNamed('body'),
34+
encoding: anyNamed('encoding'),
35+
),
36+
).thenAnswer((_) async => Response(utf8.encode(responseBody), statusCode));
37+
}
38+
39+
group('create', () {
40+
test('400 with empty body returns typed error', () async {
41+
stubPost('/create', '', 400);
42+
final r = await api.create('PM8Ttest');
43+
expect(r.statusCode, 400);
44+
expect(r.message, 'Bad request');
45+
expect(r.value, isNull);
46+
});
47+
48+
test('201 with valid JSON returns CreatedPaynym', () async {
49+
stubPost(
50+
'/create',
51+
'{"claimed":false,"nymID":"abc","nymName":"foo","segwit":true,"token":"tok"}',
52+
201,
53+
);
54+
final r = await api.create('PM8Ttest');
55+
expect(r.statusCode, 201);
56+
expect(r.message, 'PayNym created successfully');
57+
expect(r.value, isNotNull);
58+
expect(r.value!.nymId, 'abc');
59+
});
60+
61+
test('200 returns existing PayNym', () async {
62+
stubPost(
63+
'/create',
64+
'{"claimed":true,"nymID":"abc","nymName":"foo","segwit":true,"token":"tok"}',
65+
200,
66+
);
67+
final r = await api.create('PM8Ttest');
68+
expect(r.statusCode, 200);
69+
expect(r.message, 'PayNym already exists');
70+
expect(r.value, isNotNull);
71+
});
72+
});
73+
74+
group('token', () {
75+
test('404 with empty body returns typed error', () async {
76+
stubPost('/token', '', 404);
77+
final r = await api.token('PM8Ttest');
78+
expect(r.statusCode, 404);
79+
expect(r.message, 'Payment code was not found');
80+
expect(r.value, isNull);
81+
});
82+
83+
test('400 with empty body returns typed error', () async {
84+
stubPost('/token', '', 400);
85+
final r = await api.token('PM8Ttest');
86+
expect(r.statusCode, 400);
87+
expect(r.message, 'Bad request');
88+
expect(r.value, isNull);
89+
});
90+
91+
test('200 with valid JSON returns token string', () async {
92+
stubPost('/token', '{"token":"testToken123"}', 200);
93+
final r = await api.token('PM8Ttest');
94+
expect(r.statusCode, 200);
95+
expect(r.message, 'Token was successfully updated');
96+
expect(r.value, 'testToken123');
97+
});
98+
});
99+
100+
group('nym', () {
101+
test('404 with empty body returns typed error', () async {
102+
stubPost('/nym', '', 404);
103+
final r = await api.nym('PM8Ttest');
104+
expect(r.statusCode, 404);
105+
expect(r.message, 'Nym not found');
106+
expect(r.value, isNull);
107+
});
108+
109+
test('400 with empty body returns typed error', () async {
110+
stubPost('/nym', '', 400);
111+
final r = await api.nym('PM8Ttest');
112+
expect(r.statusCode, 400);
113+
expect(r.message, 'Bad request');
114+
expect(r.value, isNull);
115+
});
116+
117+
test('200 with valid JSON returns PaynymAccount', () async {
118+
stubPost(
119+
'/nym',
120+
jsonEncode({
121+
'nymID': 'testId',
122+
'nymName': 'testName',
123+
'segwit': true,
124+
'codes': [
125+
{'claimed': true, 'segwit': true, 'code': 'PM8Ttest'},
126+
],
127+
'followers': <Map<String, dynamic>>[],
128+
'following': <Map<String, dynamic>>[],
129+
}),
130+
200,
131+
);
132+
final r = await api.nym('PM8Ttest');
133+
expect(r.statusCode, 200);
134+
expect(r.message, 'Nym found and returned');
135+
expect(r.value, isNotNull);
136+
expect(r.value!.nymID, 'testId');
137+
});
138+
});
139+
140+
group('claim', () {
141+
test('400 with empty body returns typed error', () async {
142+
stubPost('/claim', '', 400);
143+
final r = await api.claim('tok', 'sig');
144+
expect(r.statusCode, 400);
145+
expect(r.message, 'Bad request');
146+
expect(r.value, isNull);
147+
});
148+
149+
test('200 with valid JSON returns PaynymClaim', () async {
150+
stubPost('/claim', '{"claimed":"PM8Ttest","token":"newTok"}', 200);
151+
final r = await api.claim('tok', 'sig');
152+
expect(r.statusCode, 200);
153+
expect(r.message, 'Payment code successfully claimed');
154+
expect(r.value, isNotNull);
155+
expect(r.value!.claimed, 'PM8Ttest');
156+
});
157+
});
158+
159+
group('follow', () {
160+
test('404 with empty body returns typed error', () async {
161+
stubPost('/follow', '', 404);
162+
final r = await api.follow('tok', 'sig', 'target');
163+
expect(r.statusCode, 404);
164+
expect(r.message, 'Payment code not found');
165+
expect(r.value, isNull);
166+
});
167+
168+
test('401 with empty body returns typed error', () async {
169+
stubPost('/follow', '', 401);
170+
final r = await api.follow('tok', 'sig', 'target');
171+
expect(r.statusCode, 401);
172+
expect(
173+
r.message,
174+
'Unauthorized token or signature or Unclaimed payment code',
175+
);
176+
expect(r.value, isNull);
177+
});
178+
179+
test('400 with empty body returns typed error', () async {
180+
stubPost('/follow', '', 400);
181+
final r = await api.follow('tok', 'sig', 'target');
182+
expect(r.statusCode, 400);
183+
expect(r.message, 'Bad request');
184+
expect(r.value, isNull);
185+
});
186+
});
187+
188+
group('unfollow', () {
189+
test('404 with empty body returns typed error', () async {
190+
stubPost('/unfollow', '', 404);
191+
final r = await api.unfollow('tok', 'sig', 'target');
192+
expect(r.statusCode, 404);
193+
expect(r.message, 'Payment code not found');
194+
expect(r.value, isNull);
195+
});
196+
197+
test('401 with empty body returns typed error', () async {
198+
stubPost('/unfollow', '', 401);
199+
final r = await api.unfollow('tok', 'sig', 'target');
200+
expect(r.statusCode, 401);
201+
expect(
202+
r.message,
203+
'Unauthorized token or signature or Unclaimed payment code',
204+
);
205+
expect(r.value, isNull);
206+
});
207+
208+
test('400 with empty body returns typed error', () async {
209+
stubPost('/unfollow', '', 400);
210+
final r = await api.unfollow('tok', 'sig', 'target');
211+
expect(r.statusCode, 400);
212+
expect(r.message, 'Bad request');
213+
expect(r.value, isNull);
214+
});
215+
});
216+
217+
group('add', () {
218+
test('400 with empty body returns typed error', () async {
219+
stubPost('/nym/add', '', 400);
220+
final r = await api.add('tok', 'sig', 'nym', 'code');
221+
expect(r.statusCode, 400);
222+
expect(r.message, 'Bad request');
223+
expect(r.value, false);
224+
});
225+
226+
test('401 with empty body returns typed error', () async {
227+
stubPost('/nym/add', '', 401);
228+
final r = await api.add('tok', 'sig', 'nym', 'code');
229+
expect(r.statusCode, 401);
230+
expect(
231+
r.message,
232+
'Unauthorized token or signature or Unclaimed payment code',
233+
);
234+
expect(r.value, false);
235+
});
236+
237+
test('404 with empty body returns typed error', () async {
238+
stubPost('/nym/add', '', 404);
239+
final r = await api.add('tok', 'sig', 'nym', 'code');
240+
expect(r.statusCode, 404);
241+
expect(r.message, 'Nym not found');
242+
expect(r.value, false);
243+
});
244+
});
245+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Mocks generated by Mockito 5.4.6 from annotations
2+
// in stackwallet/test/services/paynym/paynym_is_api_test.dart.
3+
// Do not manually edit this file.
4+
5+
// ignore_for_file: no_leading_underscores_for_library_prefixes
6+
import 'dart:async' as _i3;
7+
import 'dart:convert' as _i5;
8+
import 'dart:io' as _i4;
9+
10+
import 'package:mockito/mockito.dart' as _i1;
11+
import 'package:stackwallet/networking/http.dart' as _i2;
12+
13+
// ignore_for_file: type=lint
14+
// ignore_for_file: avoid_redundant_argument_values
15+
// ignore_for_file: avoid_setters_without_getters
16+
// ignore_for_file: comment_references
17+
// ignore_for_file: deprecated_member_use
18+
// ignore_for_file: deprecated_member_use_from_same_package
19+
// ignore_for_file: implementation_imports
20+
// ignore_for_file: invalid_use_of_visible_for_testing_member
21+
// ignore_for_file: must_be_immutable
22+
// ignore_for_file: prefer_const_constructors
23+
// ignore_for_file: unnecessary_parenthesis
24+
// ignore_for_file: camel_case_types
25+
// ignore_for_file: subtype_of_sealed_class
26+
// ignore_for_file: invalid_use_of_internal_member
27+
28+
class _FakeResponse_0 extends _i1.SmartFake implements _i2.Response {
29+
_FakeResponse_0(Object parent, Invocation parentInvocation)
30+
: super(parent, parentInvocation);
31+
}
32+
33+
/// A class which mocks [HTTP].
34+
///
35+
/// See the documentation for Mockito's code generation for more information.
36+
class MockHTTP extends _i1.Mock implements _i2.HTTP {
37+
MockHTTP() {
38+
_i1.throwOnMissingStub(this);
39+
}
40+
41+
@override
42+
_i3.Future<_i2.Response> get({
43+
required Uri? url,
44+
Map<String, String>? headers,
45+
required ({_i4.InternetAddress host, int port})? proxyInfo,
46+
Duration? connectionTimeout,
47+
}) =>
48+
(super.noSuchMethod(
49+
Invocation.method(#get, [], {
50+
#url: url,
51+
#headers: headers,
52+
#proxyInfo: proxyInfo,
53+
#connectionTimeout: connectionTimeout,
54+
}),
55+
returnValue: _i3.Future<_i2.Response>.value(
56+
_FakeResponse_0(
57+
this,
58+
Invocation.method(#get, [], {
59+
#url: url,
60+
#headers: headers,
61+
#proxyInfo: proxyInfo,
62+
#connectionTimeout: connectionTimeout,
63+
}),
64+
),
65+
),
66+
)
67+
as _i3.Future<_i2.Response>);
68+
69+
@override
70+
_i3.Future<_i2.Response> post({
71+
required Uri? url,
72+
Map<String, String>? headers,
73+
Object? body,
74+
_i5.Encoding? encoding,
75+
required ({_i4.InternetAddress host, int port})? proxyInfo,
76+
}) =>
77+
(super.noSuchMethod(
78+
Invocation.method(#post, [], {
79+
#url: url,
80+
#headers: headers,
81+
#body: body,
82+
#encoding: encoding,
83+
#proxyInfo: proxyInfo,
84+
}),
85+
returnValue: _i3.Future<_i2.Response>.value(
86+
_FakeResponse_0(
87+
this,
88+
Invocation.method(#post, [], {
89+
#url: url,
90+
#headers: headers,
91+
#body: body,
92+
#encoding: encoding,
93+
#proxyInfo: proxyInfo,
94+
}),
95+
),
96+
),
97+
)
98+
as _i3.Future<_i2.Response>);
99+
}

0 commit comments

Comments
 (0)