Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix problem #8085

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from

Conversation

VasylyshynDmytro
Copy link
Collaborator

@VasylyshynDmytro VasylyshynDmytro commented Jan 30, 2025

Add checks if user with this email already exist

Summary by CodeRabbit

  • New Features

    • Enhanced the user registration experience with improved form validation and dynamic feedback.
    • Users now receive clear notifications upon successful registration and precise error alerts when issues such as duplicate emails occur.
    • Introduced a standardized error message for users attempting to register with an existing email.
  • Bug Fixes

    • Improved error handling during user registration, providing specific feedback for various error scenarios.

Copy link

coderabbitai bot commented Jan 30, 2025

Walkthrough

This pull request updates the user registration process. In the backend, the saveUser method now returns a structured HTTP response via a ResponseEntity with improved error handling and a standardized message key. The related test was adjusted to send JSON data and expect a 200 OK response. On the frontend, the AJAX form submission logic now uses jQuery to validate, serialize the form to JSON, and handle both success and error responses. Additionally, a new error message constant was added for duplicate email registrations.

Changes

File(s) Change Summary
core/src/main/java/greencity/webcontroller/ManagementUserController.java
core/src/test/java/greencity/webcontroller/ManagementUserControllerTest.java
Updated the saveUser method to return ResponseEntity<Map<String, String>> with try-catch for error handling and standardized response messages. The test was modified to send JSON and expect a 2xx success response.
core/src/main/resources/.../user/buttonsAJAX.js Revised form submission logic using jQuery for validation, JSON serialization of form data, and enhanced AJAX error handling with specific alerts and page reload on success.
service-api/.../constant/ErrorMessage.java Added a new constant USER_WITH_EMAIL_EXIST with the message "User with this email is already registered" to standardize error messaging.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as ManagementUserController
    Client->>Controller: POST /saveUser (JSON payload)
    alt Registration Successful
        Controller-->>Client: 200 OK, { "message": "Success" }
    else User Already Exists
        Controller-->>Client: 400 Bad Request, { "message": "User with this email is already registered" }
    else Other Exception
        Controller-->>Client: 500 Internal Server Error, { "message": "Internal error" }
    end
Loading
sequenceDiagram
    participant User
    participant UI as buttonsAJAX.js
    participant Controller as ManagementUserController
    User->>UI: Clicks Submit Button
    UI->>UI: Validate Form via jQuery
    alt Form Invalid
        UI-->>User: Highlight Validation Errors
    else Form Valid
        UI->>Controller: Send AJAX POST (JSON payload)
        Controller-->>UI: Return HTTP Response
        UI->>User: Alert with Response Message & Reload Page on Success
    end
Loading

Suggested reviewers

  • KizerovDmitriy
  • Maryna-511750
  • urio999

Poem

A fresh code breeze, a refined design,
Errors caught before they align.
From backend grace to AJAX’s might,
Each line now sings in crisp insight.
Cheers to our team—let brilliance ignite! 🚀

Happy coding!

Tip

🌐 Web search-backed reviews and chat
  • We have enabled web search-based reviews and chat for all users. This feature allows CodeRabbit to access the latest documentation and information on the web.
  • You can disable this feature by setting web_search: false in the knowledge_base settings.
  • Please share any feedback in the Discord discussion.

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3715ab1 and e16f852.

📒 Files selected for processing (2)
  • core/src/main/java/greencity/webcontroller/ManagementUserController.java (4 hunks)
  • core/src/test/java/greencity/webcontroller/ManagementUserControllerTest.java (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • core/src/test/java/greencity/webcontroller/ManagementUserControllerTest.java
  • core/src/main/java/greencity/webcontroller/ManagementUserController.java

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
core/src/main/resources/static/management/user/buttonsAJAX.js (1)

507-508: Localize user-facing messages.

The alert message is hardcoded in Ukrainian. Use a localization system for better maintainability and internationalization support.

- alert("Максимальна кількість фільтрів 3. Видаліть фільтр для створення нового.")
+ alert(i18n.t('filters.max_limit_reached'))
🧹 Nitpick comments (3)
core/src/test/java/greencity/webcontroller/ManagementUserControllerTest.java (1)

183-193: Consider adding test for duplicate email scenario.

Since the PR adds checks for duplicate emails, it would be valuable to add a test case that verifies this scenario. This ensures the error handling works as expected.

Here's a suggested test method:

@Test
void saveUserTestWithDuplicateEmail() throws Exception {
    UserManagementDto dto = ModelUtils.getUserManagementDto();
    when(restClient.managementRegisterUser(dto))
        .thenThrow(new RuntimeException("User with this email already exists"));

    mockMvc.perform(post(MANAGEMENT_USER_LINK + "/register")
        .contentType(MediaType.APPLICATION_JSON)
        .content(new ObjectMapper().writeValueAsString(dto)))
        .andExpect(status().isConflict())
        .andExpect(jsonPath("$.message").value("User with this email already exists"));
}
core/src/main/resources/static/management/user/buttonsAJAX.js (2)

242-249: Form validation looks good, but consider using a form validation library.

The form validation implementation is correct, but for better maintainability and consistency, consider using a form validation library like jQuery Validate.

- if (!form[0].checkValidity()) {
-     form.addClass("was-validated");
-     return;
- }
+ form.validate({
+     submitHandler: function(form) {
+         // Your AJAX submission code here
+     },
+     invalidHandler: function(event, validator) {
+         $(form).addClass("was-validated");
+     }
+ });

186-186: Remove debug console.log statements.

Debug statements should not be present in production code.

- console.log(checkedCh)
- console.log("some");

Also applies to: 499-499

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d96c4a7 and 3715ab1.

📒 Files selected for processing (4)
  • core/src/main/java/greencity/webcontroller/ManagementUserController.java (4 hunks)
  • core/src/main/resources/static/management/user/buttonsAJAX.js (1 hunks)
  • core/src/test/java/greencity/webcontroller/ManagementUserControllerTest.java (1 hunks)
  • service-api/src/main/java/greencity/constant/ErrorMessage.java (1 hunks)
🔇 Additional comments (4)
core/src/main/java/greencity/webcontroller/ManagementUserController.java (2)

60-60: LGTM! Good practice using a constant for message key.

The constant helps maintain consistency across response structures.


104-114: Excellent error handling implementation!

The implementation properly handles:

  • Success case with 200 OK
  • Duplicate email case with 400 Bad Request
  • Unexpected errors with 500 Internal Server Error

Good practices:

  • Using proper HTTP status codes
  • Structured error responses
  • Specific error messages for better user experience
service-api/src/main/java/greencity/constant/ErrorMessage.java (1)

58-58: LGTM! Clear and descriptive error message.

The error message is user-friendly and follows the existing pattern in the file.

core/src/test/java/greencity/webcontroller/ManagementUserControllerTest.java (1)

187-190: LGTM! Clean transition to JSON-based API.

The changes correctly reflect the shift from form-based to JSON-based API, with proper content type and response status expectations.

Comment on lines +251 to +274
$.ajax({
url: form.attr('action'),
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(Object.fromEntries(new FormData(form[0]))),
success: function (response) {
alert(response.message);
window.location.reload();
},
error: function (xhr) {
if (xhr.status === 400) {
try {
const response = JSON.parse(xhr.responseText);
let errorMessage = response.find(e => e.name === "email")?.message || "Невідома помилка.";
alert("Помилка: " + errorMessage);
} catch (e) {
alert("Не вдалося розібрати відповідь сервера.");
}
} else {
alert("Помилка сервера. Статус: " + xhr.status);
}
}
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security and UX improvements needed in error handling.

The current implementation has several areas for improvement:

  1. Using alert() for error messages is not user-friendly
  2. Error messages are hardcoded in Ukrainian
  3. Direct exposure of server error messages could leak sensitive information

Consider this improved implementation:

 $.ajax({
     url: form.attr('action'),
     type: 'POST',
     contentType: 'application/json',
     data: JSON.stringify(Object.fromEntries(new FormData(form[0]))),
     success: function (response) {
-        alert(response.message);
+        showToast('success', response.message);
         window.location.reload();
     },
     error: function (xhr) {
         if (xhr.status === 400) {
             try {
                 const response = JSON.parse(xhr.responseText);
-                let errorMessage = response.find(e => e.name === "email")?.message || "Невідома помилка.";
-                alert("Помилка: " + errorMessage);
+                let errorMessage = response.find(e => e.name === "email")?.message || i18n.t('errors.unknown');
+                showToast('error', i18n.t('errors.prefix') + errorMessage);
             } catch (e) {
-                alert("Не вдалося розібрати відповідь сервера.");
+                showToast('error', i18n.t('errors.parse_failed'));
             }
         } else {
-            alert("Помилка сервера. Статус: " + xhr.status);
+            showToast('error', i18n.t('errors.server', { status: xhr.status }));
         }
     }
 });

+ function showToast(type, message) {
+     // Implementation using a toast library like toastr
+     toastr[type](message);
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$.ajax({
url: form.attr('action'),
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(Object.fromEntries(new FormData(form[0]))),
success: function (response) {
alert(response.message);
window.location.reload();
},
error: function (xhr) {
if (xhr.status === 400) {
try {
const response = JSON.parse(xhr.responseText);
let errorMessage = response.find(e => e.name === "email")?.message || "Невідома помилка.";
alert("Помилка: " + errorMessage);
} catch (e) {
alert("Не вдалося розібрати відповідь сервера.");
}
} else {
alert("Помилка сервера. Статус: " + xhr.status);
}
}
});
});
$.ajax({
url: form.attr('action'),
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(Object.fromEntries(new FormData(form[0]))),
success: function (response) {
showToast('success', response.message);
window.location.reload();
},
error: function (xhr) {
if (xhr.status === 400) {
try {
const response = JSON.parse(xhr.responseText);
let errorMessage = response.find(e => e.name === "email")?.message || i18n.t('errors.unknown');
showToast('error', i18n.t('errors.prefix') + errorMessage);
} catch (e) {
showToast('error', i18n.t('errors.parse_failed'));
}
} else {
showToast('error', i18n.t('errors.server', { status: xhr.status }));
}
}
});
});
function showToast(type, message) {
// Implementation using a toast library like toastr
toastr[type](message);
}

@KizerovDmitriy
Copy link
Contributor

Please increase your code coverage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants