Skip to content

Commit 8cce66c

Browse files
committed
Merge branch 'main' into fix/dio-additional-request-data
2 parents 8359ad8 + 54acf91 commit 8cce66c

File tree

6 files changed

+105
-8
lines changed

6 files changed

+105
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
- Tag all spans with thread info on non-web platforms ([#3101](https://github.com/getsentry/sentry-dart/pull/3101), [#3144](https://github.com/getsentry/sentry-dart/pull/3144))
99
- feat(feedback): Add option to disable keyboard resize ([#3154](https://github.com/getsentry/sentry-dart/pull/3154))
1010

11+
### Fixes
12+
13+
- Implement prefill logic in `SentryFeedbackWidget` for `useSentryUser` parameter to populate fields with current user data ([#3180](https://github.com/getsentry/sentry-dart/pull/3180))
14+
1115
### Enhancements
1216

1317
- Add `DioException` response data to error breadcrumb ([#3164](https://github.com/getsentry/sentry-dart/pull/3164))

packages/dart/lib/src/protocol/access_aware_map.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'dart:collection';
33
import 'package:meta/meta.dart';
44

55
@internal
6-
class AccessAwareMap<String, V> extends MapBase<String, V> {
6+
class AccessAwareMap<V> extends MapBase<String, V> {
77
AccessAwareMap(this._map);
88

99
final Map<String, V> _map;

packages/file/lib/src/sentry_io_overrides.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import '../sentry_file.dart';
66
/// If set to [IOOverrides.global], newly created [File] instances will be of
77
/// type [SentryFile].
88
/// Enable by adding [SentryIOOverridesIntegration] to [SentryOptions].
9-
class SentryIOOverrides extends IOOverrides {
9+
final class SentryIOOverrides extends IOOverrides {
1010
final Hub _hub;
1111

1212
SentryIOOverrides(this._hub);

packages/flutter/lib/src/feedback/sentry_feedback_widget.dart

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ class _SentryFeedbackWidgetState extends State<SentryFeedbackWidget> {
9494
void initState() {
9595
super.initState();
9696

97+
if (widget.options.useSentryUser) {
98+
_setSentryUserData();
99+
}
97100
_restorePreservedData();
98101
_captureReplay();
99102

@@ -407,6 +410,28 @@ class _SentryFeedbackWidgetState extends State<SentryFeedbackWidget> {
407410
}
408411
}
409412

413+
SentryUser? _getUser() {
414+
SentryUser? user;
415+
widget._hub.configureScope((scope) {
416+
user = scope.user;
417+
});
418+
return user;
419+
}
420+
421+
void _setSentryUserData() {
422+
final user = _getUser();
423+
if (user == null) return;
424+
425+
final userName = user.name;
426+
if (userName != null) {
427+
_nameController.text = userName;
428+
}
429+
final userEmail = user.email;
430+
if (userEmail != null) {
431+
_emailController.text = userEmail;
432+
}
433+
}
434+
410435
void _restorePreservedData() {
411436
final preservedName = SentryFeedbackWidget.preservedName;
412437
if (preservedName != null) {

packages/flutter/test/feedback/sentry_feedback_widget_test.dart

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@ void main() {
2020
final mockBinding = MockSentryNativeBinding();
2121
when(mockBinding.supportsReplay).thenReturn(true);
2222
when(fixture.hub.scope).thenReturn(fixture.scope);
23-
when(fixture.hub.configureScope(any)).thenAnswer((invocation) {
24-
final callback = invocation.positionalArguments.first;
25-
callback(fixture.scope);
26-
return null;
27-
});
23+
2824
final replayId = SentryId.fromId('1988bb1b6f0d4c509e232f0cb9aaeaea');
2925
when(mockBinding.captureReplay()).thenAnswer((_) async => replayId);
3026

@@ -228,6 +224,59 @@ void main() {
228224
});
229225
});
230226

227+
group('$SentryFeedbackWidget prefills fields from sentryUser', () {
228+
late Fixture fixture;
229+
230+
setUp(() {
231+
fixture = Fixture();
232+
});
233+
234+
testWidgets('prefills form data if useSentryUser is true', (tester) async {
235+
fixture.options.feedback.useSentryUser = true;
236+
fixture.hub.configureScope((scope) {
237+
scope.setUser(fixture.sentryUser);
238+
});
239+
240+
await fixture.pumpFeedbackWidget(
241+
tester,
242+
(hub) => SentryFeedbackWidget(hub: hub),
243+
);
244+
245+
final nameField = tester.widget<TextFormField>(
246+
find.byKey(ValueKey('sentry_feedback_name_textfield')),
247+
);
248+
final emailField = tester.widget<TextFormField>(
249+
find.byKey(ValueKey('sentry_feedback_email_textfield')),
250+
);
251+
252+
expect(nameField.controller?.text, "fixture-name");
253+
expect(emailField.controller?.text, "fixture@example.com");
254+
});
255+
256+
testWidgets('does not prefill form data if useSentryUser is false',
257+
(tester) async {
258+
fixture.options.feedback.useSentryUser = false;
259+
fixture.hub.configureScope((scope) {
260+
scope.setUser(fixture.sentryUser);
261+
});
262+
263+
await fixture.pumpFeedbackWidget(
264+
tester,
265+
(hub) => SentryFeedbackWidget(hub: hub),
266+
);
267+
268+
final nameField = tester.widget<TextFormField>(
269+
find.byKey(ValueKey('sentry_feedback_name_textfield')),
270+
);
271+
final emailField = tester.widget<TextFormField>(
272+
find.byKey(ValueKey('sentry_feedback_email_textfield')),
273+
);
274+
275+
expect(nameField.controller?.text, isEmpty);
276+
expect(emailField.controller?.text, isEmpty);
277+
});
278+
});
279+
231280
group('$SentryFeedbackWidget uses naming from options', () {
232281
late Fixture fixture;
233282

@@ -759,6 +808,7 @@ class Fixture {
759808
var options = SentryFlutterOptions();
760809
var hub = MockHub();
761810
late var scope = Scope(options);
811+
late SentryUser sentryUser;
762812

763813
Fixture() {
764814
when(hub.options).thenReturn(options);
@@ -768,9 +818,20 @@ class Fixture {
768818
hint: anyNamed('hint'),
769819
withScope: anyNamed('withScope'),
770820
)).thenAnswer((_) async => SentryId.empty());
771-
821+
when(hub.configureScope(any)).thenAnswer((invocation) {
822+
final callback = invocation.positionalArguments.first;
823+
callback(scope);
824+
return null;
825+
});
772826
SentryFeedbackWidget.pendingAssociatedEventId = null;
773827
SentryFeedbackWidget.clearPreservedData();
828+
829+
sentryUser = SentryUser(
830+
id: 'fixture-id',
831+
username: 'fixture-username',
832+
name: 'fixture-name',
833+
email: 'fixture@example.com',
834+
);
774835
}
775836

776837
Future<void> pumpFeedbackWidget(

packages/flutter/test/screenshot/sentry_screenshot_widget_test.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,14 @@ void main() {
102102
options.navigatorKey = navigatorKey;
103103

104104
var hub = mocks.MockHub();
105+
late var scope = Scope(options);
106+
105107
when(hub.options).thenReturn(options);
108+
when(hub.configureScope(any)).thenAnswer((invocation) {
109+
final callback = invocation.positionalArguments.first;
110+
callback(scope);
111+
return null;
112+
});
106113

107114
await tester.pumpWidget(
108115
MaterialApp(

0 commit comments

Comments
 (0)