Skip to content

Commit

Permalink
Redirect to static feedback message if report form is successful.
Browse files Browse the repository at this point in the history
  • Loading branch information
isoos committed Aug 29, 2024
1 parent 52f37fd commit 5492b9c
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 22 deletions.
4 changes: 2 additions & 2 deletions app/lib/frontend/handlers/pubapi.client.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions app/lib/frontend/handlers/pubapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,7 @@ class PubApi {
listAdvisoriesForPackage(request, package);

@EndPoint.post('/api/report')
Future<Message> postReport(Request request, ReportForm body) async {
final message = await processReportPageHandler(request, body);
return Message(message: message);
Future<FormResponse> postReport(Request request, ReportForm body) async {
return await processReportPageHandler(request, body);
}
}
32 changes: 30 additions & 2 deletions app/lib/frontend/handlers/report.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'dart:async';

import 'package:_pub_shared/data/account_api.dart';
import 'package:_pub_shared/data/package_api.dart';
import 'package:clock/clock.dart';
import 'package:pub_dev/admin/backend.dart';
import 'package:pub_dev/shared/configuration.dart';
Expand Down Expand Up @@ -35,6 +36,23 @@ Future<shelf.Response> reportPageHandler(shelf.Request request) async {
return notFoundHandler(request);
}

final feedback = request.requestedUri.queryParameters['feedback'];
if (feedback != null) {
switch (feedback) {
case 'report-submitted':
return htmlResponse(renderReportFeedback(
title: 'Report submitted',
message: 'The report has been submitted successfully.',
));
case 'appeal-submitted':
return htmlResponse(renderReportFeedback(
title: 'Appeal submitted',
message: 'The appeal has been submitted successfully.',
));
}
return notFoundHandler(request);
}

final caseId = request.requestedUri.queryParameters['appeal'];
final mc = await _loadAndVerifyCase(caseId);

Expand Down Expand Up @@ -134,7 +152,7 @@ Future<void> _verifyCaseSubject(
}

/// Handles POST /api/report
Future<String> processReportPageHandler(
Future<FormResponse> processReportPageHandler(
shelf.Request request, ReportForm form) async {
if (!requestContext.experimentalFlags.isReportPageEnabled) {
throw NotFoundException('Experimental flag is not enabled.');
Expand Down Expand Up @@ -233,5 +251,15 @@ Future<String> processReportPageHandler(
bodyText: bodyText,
));

return 'The $kind was submitted successfully.';
final redirectTo = request.requestedUri.replace(
path: '/report',
queryParameters: {
'feedback': '$kind-submitted',
},
).toString();

return FormResponse(
message: null, // no modal feedback
redirectTo: redirectTo,
);
}
16 changes: 16 additions & 0 deletions app/lib/frontend/templates/report.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@ const _subjectKindLabels = {
ModerationSubjectKind.publisher: 'publisher',
};

/// Renders the feedback page with a simple paragraph of [message].
String renderReportFeedback({
required String title,
required String message,
}) {
return renderLayoutPage(
PageType.standalone,
d.fragment([
d.h1(text: title),
d.p(text: message),
]),
title: title,
noIndex: true,
);
}

/// Renders the create publisher page.
String renderReportPage({
SessionData? sessionData,
Expand Down
17 changes: 17 additions & 0 deletions pkg/_pub_shared/lib/data/package_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,23 @@ class Message {
Map<String, dynamic> toJson() => _$MessageToJson(this);
}

/// A message wrapper for pub client API compatibility.
@JsonSerializable(includeIfNull: false)
class FormResponse {
final String? message;
final String? redirectTo;

FormResponse({
required this.message,
required this.redirectTo,
});

factory FormResponse.fromJson(Map<String, dynamic> json) =>
_$FormResponseFromJson(json);

Map<String, dynamic> toJson() => _$FormResponseToJson(this);
}

/// Used in `pub` client for finding which versions exist.
/// (`listVersions` method in pubapi)
@JsonSerializable(includeIfNull: false)
Expand Down
19 changes: 19 additions & 0 deletions pkg/_pub_shared/lib/data/package_api.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/_pub_shared/lib/src/pubapi.client.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 7 additions & 8 deletions pkg/pub_integration/test/report_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ void main() {
await page.waitFocusAndType('#report-email', 'reporter@pub.dev');
await page.waitFocusAndType(
'#report-message', 'Huston, we have a problem.');
await page.waitAndClick('#report-submit', waitForOneResponse: true);
expect(await page.content,
contains('The report was submitted successfully.'));
await page.waitAndClickOnDialogOk();
await page.waitAndClick('#report-submit');
await page.waitForNavigation();
expect(
await page.content, contains('has been submitted successfully'));
},
);

Expand Down Expand Up @@ -197,10 +197,9 @@ void main() {

await page.waitFocusAndType(
'#report-message', 'Huston, I have a different idea.');
await page.waitAndClick('#report-submit', waitForOneResponse: true);
expect(await page.content,
contains('The appeal was submitted successfully.'));
await page.waitAndClickOnDialogOk();
await page.waitAndClick('#report-submit');
await page.waitForNavigation();
expect(await page.content, contains('has been submitted successfully'));
});

final appealEmail = await supportUser.readLatestEmail();
Expand Down
22 changes: 17 additions & 5 deletions pkg/web_app/lib/src/admin_pages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,23 @@ void _initGenericForm() {
fn: () =>
api_client.sendJson(verb: 'POST', path: endpoint, body: body),
successMessage: null,
onSuccess: (result) async {
final message =
result == null ? null : result['message']?.toString();
await modalMessage('Success', text(message ?? 'OK.'));
window.location.reload();
onSuccess: (r) async {
final result = r ?? <String, dynamic>{};
final redirectTo = result['redirectTo']?.toString();

// We shall display a minimal feedback when both the redirect and the message is omitted.
final message = result['message']?.toString() ??
(redirectTo == null ? 'Success. The page will reload.' : null);

if (message != null) {
await modalMessage('Success', text(message));
}

if (redirectTo != null) {
window.location.href = redirectTo;
} else {
window.location.reload();
}
},
);
});
Expand Down

0 comments on commit 5492b9c

Please sign in to comment.