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

General:Make Request Feedback a standalone component #9323

Conversation

undernagruzez
Copy link
Contributor

@undernagruzez undernagruzez commented Sep 17, 2024

!! Can be tested only on TS1 !!

Checklist

General

Server

  • Important: I implemented the changes with a very good performance and prevented too many (unnecessary) and too complex database calls.
  • I strictly followed the principle of data economy for all database calls.
  • I strictly followed the server coding and design guidelines.
  • I added multiple integration tests (Spring) related to the features (with a high test coverage).
  • I added pre-authorization annotations according to the guidelines and checked the course groups for all new REST Calls (security).
  • I documented the Java code using JavaDoc style.

Client

  • Important: I implemented the changes with a very good performance, prevented too many (unnecessary) REST calls and made sure the UI is responsive, even with large data (e.g. using paging).
  • I strictly followed the principle of data economy for all client-server REST calls.
  • I strictly followed the client coding and design guidelines.
  • Following the theming guidelines, I specified colors only in the theming variable files and checked that the changes look consistent in both the light and the dark theme.
  • I added multiple integration tests (Jest) related to the features (with a high test coverage), while following the test guidelines.
  • I added authorities to all new routes and checked the course groups for displaying navigation elements (links, buttons).
  • I documented the TypeScript code using JSDoc style.
  • I added multiple screenshots/screencasts of my UI changes.
  • I translated all newly inserted strings into English and German.

Motivation and Context

Currently, the request feedback button is embedded within other components, making it less reusable and harder to maintain. Error handling around this feature takes place both on the client and server side. Now, it only happens on the server side. Additionally, students do not have the ability to request feedback directly from the code repository view in non-exam settings.

Description

Refactored the request feedback button into a standalone component to improve modularity and reusability.
Enhanced error handling to provide clearer feedback to users when issues occur during feedback requests.
Added the request feedback button to the code repository view for non-exam settings, allowing students to request feedback directly from there.
Ensured the button did not appear in exam mode to maintain exam integrity.

Steps for Testing

Prerequisites:

1 Instructor
1 Student
1 Programming Exercise with Feedback Requests enabled

  1. Log in as an instructor.

  2. Create a programming exercise with Feedback Requests enabled(set the due date, choose manual assessment, tick the checkboxes for Athena feedback suggestions and feedback requests)

  3. Log in to Artemis as a student.

  4. Navigate to the programming exercise.

  5. Open the code repository view (non-exam setting).

  6. Verify that the request feedback button is visible.

  7. Click the request feedback button.

  8. Confirm that a feedback request is successfully submitted and a confirmation message is displayed.

Exam Mode Testing
Prerequisites:

1 Instructor
1 Student
1 Exam with a Programming Exercise

  1. Log in to Artemis as a student.
  2. Participate in the exam.
  3. Navigate to the programming exercise.
  4. Verify that the request feedback button is not visible in the code repository view.
  5. Ensure that the UI of the programming exercise in exam mode remains unchanged.

Testserver States

Note

These badges show the state of the test servers.
Green = Currently available, Red = Currently locked
Click on the badges to get to the test servers.







Review Progress

Performance Review

  • I (as a reviewer) confirm that the client changes (in particular related to REST calls and UI responsiveness) are implemented with a very good performance even for very large courses with more than 2000 students.
  • I (as a reviewer) confirm that the server changes (in particular related to database calls) are implemented with a very good performance even for very large courses with more than 2000 students.

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Exam Mode Test

  • Test 1
  • Test 2

Performance Tests

  • Test 1
  • Test 2

Test Coverage

Info: ✅ ❌ in Confirmation (assert/expect) have to be adjusted manually, also delete trivial files!

Client

Class/File Line Coverage Confirmation (assert/expect)
code-editor-actions.component.ts 81.3% ✅ ❌
programming-exercise.utils.ts 94.82% ✅ ❌
participation.utils.ts 76.19% ✅ ❌
result.service.ts 91.52% ✅ ❌
result.utils.ts 90.65% ✅ ❌
updating-result.component.ts 97.05% ✅ ❌
course-exercise-details.component.ts 89.2% ✅ ❌
exercise-details-student-actions.component.ts 86.03% ✅ ❌
request-feedback-button.component.ts 89.65% ✅ ❌

Server

Class/File Line Coverage Confirmation (assert/expect)
Exercise.java 92% ✅ ❌
ParticipationResource.java 87% ✅ ❌
ProgrammingExerciseCodeReviewFeedbackService.java 74% ✅ ❌

Screenshots

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a feedback request button for programming exercises, enhancing user interaction.
    • Added validation checks for feedback requests, ensuring users must have valid submissions.
  • Improvements

    • Enhanced error handling with more specific messages for various scenarios.
    • Streamlined feedback generation logic and rate-limiting checks.
  • User Interface

    • Updated the exercise details to include conditional rendering of feedback buttons based on exercise type and user participation.
  • Localization

    • Updated error messages in the localization files for clarity.
  • Testing

    • Added tests for the new feedback request button functionality and improved existing test cases for better coverage.

@github-actions github-actions bot added the client Pull requests that update TypeScript code. (Added Automatically!) label Sep 17, 2024
@undernagruzez undernagruzez temporarily deployed to artemis-test1.artemis.cit.tum.de September 17, 2024 15:08 — with GitHub Actions Inactive
@undernagruzez undernagruzez changed the title move request feedback to a standalone component and add a button to t… General:Make Request Feedback a standalone component Sep 17, 2024
Copy link

There hasn't been any activity on this pull request recently. Therefore, this pull request has been automatically marked as stale and will be closed if no further activity occurs within seven days. Thank you for your contributions.

@github-actions github-actions bot added stale and removed stale labels Sep 25, 2024
@github-actions github-actions bot added tests server Pull requests that update Java code. (Added Automatically!) exercise Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module labels Sep 30, 2024
@undernagruzez undernagruzez marked this pull request as ready for review September 30, 2024 16:26
@undernagruzez undernagruzez requested a review from a team as a code owner September 30, 2024 16:26
Copy link

coderabbitai bot commented Sep 30, 2024

Walkthrough

The changes involve enhancements to error handling, validation logic, and feedback mechanisms across multiple components in the codebase. Key updates include improved error messages in the ParticipationResource and ProgrammingExerciseCodeReviewFeedbackService, the addition of a new RequestFeedbackButtonComponent, and modifications to HTML templates to streamline feedback requests. Several integration tests have also been updated to reflect these changes, ensuring that the functionality aligns with the new requirements.

Changes

File Change Summary
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java, src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseCodeReviewFeedbackService.java Enhanced error handling and validation logic, including updated exception messages and refined feedback request conditions.
src/main/webapp/app/exercises/programming/shared/code-editor/actions/code-editor-actions.component.html, src/main/webapp/app/exercises/programming/shared/code-editor/actions/code-editor-actions.component.ts Added conditional rendering for feedback buttons and introduced a new input property for participation data in the code editor actions component.
src/main/webapp/app/exercises/programming/shared/code-editor/code-editor.module.ts, src/main/webapp/app/overview/exercise-details/exercise-buttons.module.ts Introduced RequestFeedbackButtonComponent to respective modules, enhancing the feedback request functionality.
src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html, src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts Refactored feedback request button logic and updated handling for exercise types, including new methods for managing feedback requests.
src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.html, src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.ts Created a new component for requesting feedback with conditional rendering based on exercise type and Athena status.
src/test/java/de/tum/cit/aet/artemis/exercise/participation/ParticipationIntegrationTest.java Added a new disabled test case for feedback requests and updated existing tests to reflect new error handling and conditions.
src/test/javascript/spec/component/overview/exercise-details/request-feedback-button/request-feedback-button.component.spec.ts Introduced tests for the RequestFeedbackButtonComponent, covering various scenarios related to feedback requests.

Possibly related PRs

Suggested labels

component:Programming, ready to merge, enhancement

Suggested reviewers

  • krusche
  • EneaGore
  • SimonEntholzer
  • pzdr7
  • BBesrour

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 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 or @coderabbitai title 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: 28

🧹 Outside diff range comments (5)
src/main/webapp/app/overview/exercise-details/exercise-buttons.module.ts (1)

Line range hint 1-17: Summary: Changes align with PR objectives, pending verification.

The changes in this file contribute to the PR's goal of making the Request Feedback feature a standalone component. The new RequestFeedbackButtonComponent is imported and added to the module, which aligns with the objective of enhancing modularity and reusability.

However, to ensure full compliance with Angular best practices and maintain consistency within the module, we need to verify if RequestFeedbackButtonComponent is indeed a standalone component. Once confirmed, we can be certain that the implementation fully meets the PR objectives and follows the correct Angular architecture.

After confirming the component's status, consider the following to further improve the module's architecture:

  1. If RequestFeedbackButtonComponent is standalone, document this decision and consider gradually migrating other components to standalone for consistency.
  2. If it's not standalone, adjust its integration into the module to match other components.

These steps will ensure that the module remains consistent and maintainable as it evolves.

src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html (1)

Line range hint 234-244: Consider using the new feedback button component for text and modeling exercises.

For consistency and to fully leverage the new standalone component, consider refactoring the feedback request button for text and modeling exercises to use the <jhi-request-feedback-button> component. This would improve maintainability and ensure a uniform approach across different exercise types.

Replace the current implementation with:

@if (exercise.allowFeedbackRequests && athenaEnabled && (exercise.type === ExerciseType.TEXT || exercise.type === ExerciseType.MODELING)) {
    <jhi-request-feedback-button 
        [exercise]="exercise" 
        [smallButtons]="smallButtons"
        [disabled]="!gradedParticipation?.submissions?.last()?.submitted || isGeneratingFeedback"
    ></jhi-request-feedback-button>
}

Note: You may need to adjust the <jhi-request-feedback-button> component to handle the disabled property and the specific behavior for text and modeling exercises.

src/test/java/de/tum/cit/aet/artemis/exercise/participation/ParticipationIntegrationTest.java (1)

Line range hint 1659-1719: Good addition, but needs alignment with recent changes

The new test method whenFeedbackRequestedAndRateLimitStillUnknownDueRequestsInProgress_thenFail() is a valuable addition to cover an important edge case. The overall structure and setup of the test are well done.

There are a couple of points that need attention:

  1. The error message assertion still uses the old generic message "preconditions not met". This should be updated to a more specific message, consistent with the changes made in other tests.

  2. The number of Athena results generated (5) is inconsistent with the change made earlier in the file where it was increased to 20.

Please apply the following changes:

  1. Update the error message:
request.putAndExpectError("/api/exercises/" + programmingExercise.getId() + "/request-feedback", null, HttpStatus.BAD_REQUEST, "rateLimitUnknown");
  1. Align the number of Athena results:
for (int i = 0; i < MAX_ATHENA_RESULTS; i++) {
    // ... existing code ...
}

Make sure to use the MAX_ATHENA_RESULTS constant suggested earlier.

src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts (2)

Line range hint 113-133: Refactor conditional logic for setting theiaEnabled to improve clarity

The current logic sets theiaEnabled to true and then conditionally sets it to false based on multiple checks. It's clearer and more maintainable to initialize theiaEnabled to false and set it to true only if all conditions are met.

Apply this diff to refactor the logic:

if (profileInfo.activeProfiles?.includes(PROFILE_THEIA) && this.programmingExercise) {
-    this.theiaEnabled = true;
-
-    // Set variables now, sanitize later on
-    this.theiaPortalURL = profileInfo.theiaPortalURL ?? '';
-
-    // Verify that Theia's portal URL is set
-    if (this.theiaPortalURL === '') {
-        this.theiaEnabled = false;
-    }
-
-    // Verify that the exercise allows the online IDE
-    if (!this.programmingExercise.allowOnlineIde) {
-        this.theiaEnabled = false;
-    }
-
-    // Verify that the exercise has a theia blueprint configured
-    if (!this.programmingExercise.buildConfig?.theiaImage) {
-        this.theiaEnabled = false;
-    }
+    // Initialize as false
+    this.theiaEnabled = false;
+
+    // Set variables now, sanitize later on
+    this.theiaPortalURL = profileInfo.theiaPortalURL ?? '';
+
+    // Verify that all conditions are met to enable Theia
+    if (
+        this.theiaPortalURL !== '' &&
+        this.programmingExercise.allowOnlineIde &&
+        this.programmingExercise.buildConfig?.theiaImage
+    ) {
+        this.theiaEnabled = true;
+    }
}

Line range hint 343-370: Fix logical error in the assignment of latestResult

The assignment of latestResult uses a logical AND (&&), which can result in latestResult being assigned a boolean value (false) rather than the expected result object. This may cause unexpected behavior when accessing properties like latestResult?.score.

Apply this diff to correct the assignment:

-const latestResult = this.gradedParticipation?.results && this.gradedParticipation.results.find(({ assessmentType }) => assessmentType === AssessmentType.AUTOMATIC);
+const latestResult = this.gradedParticipation?.results?.find(({ assessmentType }) => assessmentType === AssessmentType.AUTOMATIC);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 4932dc9 and dabd872.

📒 Files selected for processing (17)
  • src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (3 hunks)
  • src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseCodeReviewFeedbackService.java (2 hunks)
  • src/main/webapp/app/exercises/programming/shared/code-editor/actions/code-editor-actions.component.html (1 hunks)
  • src/main/webapp/app/exercises/programming/shared/code-editor/actions/code-editor-actions.component.ts (3 hunks)
  • src/main/webapp/app/exercises/programming/shared/code-editor/code-editor.module.ts (2 hunks)
  • src/main/webapp/app/exercises/programming/shared/code-editor/container/code-editor-container.component.html (1 hunks)
  • src/main/webapp/app/overview/exercise-details/exercise-buttons.module.ts (1 hunks)
  • src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html (1 hunks)
  • src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts (4 hunks)
  • src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.html (1 hunks)
  • src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.ts (1 hunks)
  • src/main/webapp/i18n/de/exercise.json (1 hunks)
  • src/main/webapp/i18n/en/exercise.json (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/exercise/participation/ParticipationIntegrationTest.java (3 hunks)
  • src/test/javascript/spec/component/exam/participate/exam-navigation-sidebar.component.spec.ts (2 hunks)
  • src/test/javascript/spec/component/overview/exercise-details/request-feedback-button/request-feedback-button.component.spec.ts (1 hunks)
  • src/test/javascript/spec/integration/code-editor/code-editor-container.integration.spec.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseCodeReviewFeedbackService.java (1)

Pattern src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

src/main/webapp/app/exercises/programming/shared/code-editor/actions/code-editor-actions.component.html (1)

Pattern src/main/webapp/**/*.html: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

src/main/webapp/app/exercises/programming/shared/code-editor/actions/code-editor-actions.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/main/webapp/app/exercises/programming/shared/code-editor/code-editor.module.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/main/webapp/app/exercises/programming/shared/code-editor/container/code-editor-container.component.html (1)

Pattern src/main/webapp/**/*.html: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

src/main/webapp/app/overview/exercise-details/exercise-buttons.module.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html (1)

Pattern src/main/webapp/**/*.html: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.html (1)

Pattern src/main/webapp/**/*.html: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/main/webapp/i18n/de/exercise.json (1)

Pattern src/main/webapp/i18n/de/**/*.json: German language translations should be informal (dutzen) and should never be formal (sietzen). So the user should always be addressed with "du/dein" and never with "sie/ihr".

src/test/java/de/tum/cit/aet/artemis/exercise/participation/ParticipationIntegrationTest.java (1)

Pattern src/test/java/**/*.java: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true

src/test/javascript/spec/component/exam/participate/exam-navigation-sidebar.component.spec.ts (1)

Pattern src/test/javascript/spec/**/*.ts: jest: true; mock: NgMocks; bad_practices: avoid_full_module_import; perf_improvements: mock_irrelevant_deps; service_testing: mock_http_for_logic; no_schema: avoid_NO_ERRORS_SCHEMA; expectation_specificity: true; solutions: {boolean: toBeTrue/False, reference: toBe, existence: toBeNull/NotNull, undefined: toBeUndefined, class_obj: toContainEntries/toEqual, spy_calls: {not_called: not.toHaveBeenCalled, once: toHaveBeenCalledOnce, with_value: toHaveBeenCalledWith|toHaveBeenCalledExactlyOnceWith}}

src/test/javascript/spec/component/overview/exercise-details/request-feedback-button/request-feedback-button.component.spec.ts (1)

Pattern src/test/javascript/spec/**/*.ts: jest: true; mock: NgMocks; bad_practices: avoid_full_module_import; perf_improvements: mock_irrelevant_deps; service_testing: mock_http_for_logic; no_schema: avoid_NO_ERRORS_SCHEMA; expectation_specificity: true; solutions: {boolean: toBeTrue/False, reference: toBe, existence: toBeNull/NotNull, undefined: toBeUndefined, class_obj: toContainEntries/toEqual, spy_calls: {not_called: not.toHaveBeenCalled, once: toHaveBeenCalledOnce, with_value: toHaveBeenCalledWith|toHaveBeenCalledExactlyOnceWith}}

src/test/javascript/spec/integration/code-editor/code-editor-container.integration.spec.ts (1)

Pattern src/test/javascript/spec/**/*.ts: jest: true; mock: NgMocks; bad_practices: avoid_full_module_import; perf_improvements: mock_irrelevant_deps; service_testing: mock_http_for_logic; no_schema: avoid_NO_ERRORS_SCHEMA; expectation_specificity: true; solutions: {boolean: toBeTrue/False, reference: toBe, existence: toBeNull/NotNull, undefined: toBeUndefined, class_obj: toContainEntries/toEqual, spy_calls: {not_called: not.toHaveBeenCalled, once: toHaveBeenCalledOnce, with_value: toHaveBeenCalledWith|toHaveBeenCalledExactlyOnceWith}}

🪛 Biome
src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.ts

[error] 60-60: Forbidden non-null assertion.

(lint/style/noNonNullAssertion)


[error] 62-62: Forbidden non-null assertion.

Unsafe fix: Replace with optional chain operator ?. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator

(lint/style/noNonNullAssertion)


[error] 83-83: Forbidden non-null assertion.

(lint/style/noNonNullAssertion)

🔇 Additional comments (26)
src/main/webapp/app/overview/exercise-details/exercise-buttons.module.ts (2)

9-9: LGTM: Import statement follows Angular style guide.

The import statement for RequestFeedbackButtonComponent is correctly formatted and follows Angular's style guide. The component name uses PascalCase as required by the coding guidelines.


12-12: Verify if RequestFeedbackButtonComponent is a standalone component.

The RequestFeedbackButtonComponent is added to the imports array, which is typically used for modules. This suggests that it might be a standalone component (a feature introduced in Angular 14+). If this is the case, the current implementation is correct.

However, for consistency with other components in this module (which are in the declarations array), consider the following options:

  1. If RequestFeedbackButtonComponent is not a standalone component, move it to the declarations array.
  2. If it is a standalone component, consider converting other components to standalone as well for consistency across the module.

Could you confirm if RequestFeedbackButtonComponent is indeed a standalone component? This will help ensure the module structure is correct and consistent.

✅ Verification successful

Verified: RequestFeedbackButtonComponent is a standalone component. Adding it to the imports array is correct.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify if RequestFeedbackButtonComponent is a standalone component

# Test: Search for the component definition
rg --type typescript -A 5 'export class RequestFeedbackButtonComponent'

Length of output: 108


Script:

#!/bin/bash
# Description: Verify if RequestFeedbackButtonComponent is a standalone component

# Test: Search for the component definition within .ts files
rg 'export class RequestFeedbackButtonComponent' --glob '*.ts'

Length of output: 235


Script:

#!/bin/bash
# Description: Check if RequestFeedbackButtonComponent is a standalone component

# Search for 'standalone: true' in the component's TypeScript file
rg 'standalone:\s*true' src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.ts

Length of output: 154

src/main/webapp/app/exercises/programming/shared/code-editor/actions/code-editor-actions.component.html (2)

1-3: LGTM! New request feedback button aligns with PR objectives.

The addition of the standalone <jhi-request-feedback-button> component is in line with the PR objectives to enhance modularity and reusability. The conditional rendering ensures the button is only displayed when an exercise is present, which is a good practice.

A few observations:

  1. The @if syntax is correctly used, adhering to the new Angular template syntax guidelines.
  2. The null-safe navigation operator (?.) is appropriately used to prevent errors if participation() is null.
  3. The non-null assertion operator (!) is used when passing the exercise to the component, which assumes the exercise will always be defined when the condition is true.

1-3: Overall changes enhance UI functionality and align with PR objectives.

The addition of the request feedback button at the beginning of the template enhances the user interface by providing easy access to the feedback feature. This change, combined with the existing action buttons, creates a comprehensive set of controls for the code editor component.

Key points:

  1. The new feedback button is correctly placed before other action buttons, giving it prominence.
  2. Existing functionality for handling conflicts, refreshing, and submitting remains intact.
  3. The conditional rendering ensures appropriate display of buttons based on the current state.

These changes successfully implement the PR objective of adding the request feedback button to the code repository view for non-exam settings, while maintaining the existing functionality.

src/main/webapp/app/exercises/programming/shared/code-editor/container/code-editor-container.component.html (1)

Line range hint 9-9: Excellent use of the new Angular syntax!

The template correctly uses the new @if syntax instead of the older *ngIf, which aligns perfectly with the provided coding guidelines. This usage is consistent throughout the file.

Also applies to: 72-72

src/main/webapp/app/exercises/programming/shared/code-editor/code-editor.module.ts (4)

27-27: LGTM: Import of RequestFeedbackButtonComponent

The import statement for RequestFeedbackButtonComponent is correctly implemented and follows the Angular style guide. The component's location in the file structure (overview/exercise-details) seems appropriate for its functionality.


Line range hint 27-39: Changes align well with PR objectives

The integration of RequestFeedbackButtonComponent as a standalone component in this module aligns perfectly with the PR objectives of enhancing modularity and reusability of the request feedback feature. The changes are minimal and focused, suggesting a clean implementation that doesn't disrupt existing functionality.

Key observations:

  1. The component is correctly imported and added to the imports array, indicating its standalone nature.
  2. No other parts of the module were modified, maintaining the integrity of existing components.
  3. The implementation follows Angular best practices for integrating standalone components.

These changes should contribute to improved maintainability and clearer separation of concerns in the codebase.


Line range hint 27-39: Verify implementation of visibility logic for exam mode

While the integration of RequestFeedbackButtonComponent looks good, it's important to ensure that the visibility logic mentioned in the PR objectives is correctly implemented. Specifically:

  1. The button should be visible in the code repository view for non-exam settings.
  2. The button should not appear in exam mode.

Since this logic is not present in the current file, it's likely implemented within the RequestFeedbackButtonComponent itself or in its parent component.

To confirm the correct implementation of this logic, you can run the following script:

#!/bin/bash
# Description: Check for exam mode visibility logic in RequestFeedbackButtonComponent

# Test: Search for conditional rendering based on exam mode
echo "Checking for exam mode visibility logic in RequestFeedbackButtonComponent:"
rg --type typescript -A 5 $'(ngIf|\\[hidden\\]|\\*ngIf).*exam' src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.ts

# Test: Search for property or method related to exam mode
echo "Checking for exam mode related properties or methods:"
rg --type typescript -A 5 $'(isExamMode|examMode|inExam)' src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.ts

Please ensure that the visibility logic is correctly implemented to meet the PR objectives.


39-39: Confirm standalone component configuration

The addition of RequestFeedbackButtonComponent to the imports array suggests that it's implemented as a standalone component. This aligns with the PR objective of making the Request Feedback feature more modular and reusable.

To ensure full compliance with Angular's standalone component pattern:

  1. Verify that RequestFeedbackButtonComponent is decorated with @Component and includes standalone: true in its configuration.
  2. Confirm that the component declares all its dependencies in its own imports array.

You can run the following script to check the component's configuration:

src/test/javascript/spec/component/exam/participate/exam-navigation-sidebar.component.spec.ts (4)

23-23: LGTM: Import statement for ArtemisSharedCommonModule.

The import statement for ArtemisSharedCommonModule is correctly placed and necessary for the changes in the TestBed configuration.


Line range hint 1-280: Summary and Recommendation

The changes to this test file are minimal, focusing on adding the ArtemisSharedCommonModule to the test configuration. This aligns with the PR objective of making the Request Feedback a standalone component. However, to ensure the integrity of the test suite and the component's functionality, I recommend the following actions before approving this PR:

  1. Run all suggested verification steps mentioned in the previous comments.
  2. If all tests pass and no unexpected behaviors are observed, this change can be approved.
  3. If any issues arise, please address them and update the test cases accordingly.

Once these steps are completed and any potential issues are resolved, this change can be confidently merged.


Line range hint 1-280: Ensure comprehensive testing after adding ArtemisSharedCommonModule.

While no changes were made to the existing test cases, the addition of ArtemisSharedCommonModule could potentially affect the component's behavior. To ensure the integrity of the test suite:

  1. Run all related tests, not just for this file, to catch any potential side effects.
  2. Manually verify the ExamNavigationSidebarComponent's behavior in the actual application to ensure it still functions as expected.

Run the following commands to perform a comprehensive test:

#!/bin/bash
# Run all tests related to the exam module
npm test -- --testPathPattern=src/test/javascript/spec/component/exam

# Run the entire test suite to catch any potential side effects
npm test

After running these tests, please report any failures or unexpected behaviors.


37-37: Verify the impact of ArtemisSharedCommonModule on existing tests.

The addition of MockModule(ArtemisSharedCommonModule) to the imports array is consistent with the existing pattern. However, please ensure that this addition doesn't introduce any unintended side effects on the existing tests.

To verify the impact, please run the following command and check if all tests still pass:

src/main/webapp/app/exercises/programming/shared/code-editor/actions/code-editor-actions.component.ts (2)

17-17: LGTM: Import statement added correctly.

The import for the Participation model is properly placed and follows the coding guidelines.


Line range hint 1-324: Summary: Changes align with PR objectives.

The modifications to this file are minimal and focused, supporting the PR objective of making the request feedback a standalone component. The addition of the participation input property allows the component to receive necessary data, which is likely used in the request feedback functionality.

The changes do not alter existing logic, maintaining the integrity of the component while enhancing its capabilities. This aligns well with the PR summary, which emphasizes improved modularity and reusability.

To ensure that the participation property is used correctly in the component's template or in child components, please run the following command:

This will help verify that the new input property is being utilized as intended in the component's view or passed down to child components.

✅ Verification successful

Participation Property Usage Verified

The participation input property is correctly utilized in the component's template. It is properly accessed to conditionally render elements and to pass necessary data to the jhi-request-feedback-button component, aligning with the PR's objective of enhancing functionality through modular components.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of the participation property in the component's template and child components
rg --type html 'participation' src/main/webapp/app/exercises/programming/shared/code-editor/actions/

Length of output: 461

src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html (1)

Line range hint 1-280: Overall implementation looks good!

The changes in this file align well with the PR objectives and adhere to the coding guidelines. The new @if and @for Angular syntax is correctly used throughout the file. The structure is clear, well-organized, and the logic seems sound.

src/main/webapp/i18n/en/exercise.json (1)

171-171: Approved: Message key and content updated for clarity.

The change from "notEnoughPoints" to "noSubmissionExists" with the message "You have to submit your work at least once." is a good improvement. It provides a clearer explanation of the requirement for requesting feedback, aligning with the PR objectives.

To ensure consistency across all language files, please run the following script:

This will help identify if similar updates are needed in other language files.

src/main/webapp/i18n/de/exercise.json (1)

171-171: LGTM! Translation is correct and follows guidelines.

The German translation for the message when a user attempts to send a feedback request without any submissions is correct and follows the coding guidelines. It uses the informal "du" form as required, maintaining consistency with other translations in the file.

src/test/javascript/spec/integration/code-editor/code-editor-container.integration.spec.ts (2)

78-78: New component import looks good.

The import statement for the RequestFeedbackButtonComponent has been added correctly.


127-127: RequestFeedbackButtonComponent added to declarations.

The RequestFeedbackButtonComponent has been properly added to the declarations array in the TestBed configuration using MockComponent.

src/test/java/de/tum/cit/aet/artemis/exercise/participation/ParticipationIntegrationTest.java (1)

27-27: LGTM: Import for @disabled annotation added

The addition of the @disabled import is appropriate and aligns with the coding guidelines for using JUnit 5 features. This suggests that a test method will be disabled, which can be useful for temporarily skipping tests or marking tests that are not yet ready for execution.

src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.ts (1)

32-35: ⚠️ Potential issue

Use '@input' and '@output' decorators for inputs and outputs

Currently, inputs and outputs are declared using input and output functions, which is not standard Angular practice. Use @Input() and @Output() decorators to declare component inputs and outputs.

-isGeneratingFeedback = input<boolean>();
+@Input() isGeneratingFeedback!: boolean;

-smallButtons = input<boolean>(false);
+@Input() smallButtons = false;

-exercise = input.required<Exercise>();
+@Input() exercise!: Exercise;

-generatingFeedback = output<void>();
+@Output() generatingFeedback = new EventEmitter<void>();

Also, make sure to import EventEmitter from @angular/core:

+import { Component, OnInit, inject, Input, Output, EventEmitter } from '@angular/core';

Likely invalid or redundant comment.

src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseCodeReviewFeedbackService.java (1)

231-231: Verify the correctness of the BadRequestAlertException constructor

At line 231, you have added true as a fourth parameter to the BadRequestAlertException constructor. Ensure that this constructor exists and accepts a boolean as the fourth parameter.

Run the following script to verify the constructor usage:

src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.ts (1)

Line range hint 258-277: Method requestFeedback() implementation looks good

The requestFeedback() method correctly handles condition checks, user confirmations, and service calls with proper success and error handling.

src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java (1)

416-416: Verify the logic for checking if a feedback request has already been sent

The condition checks if participationIndividualDueDate is not null and if the current date is after it, then throws an exception stating "Request has already been sent". Ensure this logic accurately determines whether a feedback request has already been sent, as passing the individual due date might not necessarily indicate that a request was previously sent.

src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.html (1)

3-3: Ensure ExerciseType is accessible in the template

In line 3, ExerciseType.TEXT is used within the template. Please verify that the ExerciseType enum is properly imported and exposed in the component class so it's accessible in the template.

You can confirm this by checking the component class and ensuring that ExerciseType is a public property:

import { ExerciseType } from 'app/entities/exercise.model';

@Component({
  // ...
})
export class RequestFeedbackButtonComponent {
  public ExerciseType = ExerciseType;
  // ...
}

@@ -75,6 +75,7 @@
import { MockResizeObserver } from '../../helpers/mocks/service/mock-resize-observer';
import { MonacoEditorModule } from 'app/shared/monaco-editor/monaco-editor.module';
import { CodeEditorMonacoComponent } from 'app/exercises/programming/shared/code-editor/monaco/code-editor-monaco.component';
import { RequestFeedbackButtonComponent } from 'app/overview/exercise-details/request-feedback-button/request-feedback-button.component';
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Summary of changes and suggestions for improvement.

The addition of RequestFeedbackButtonComponent to the imports and declarations is a good start for integrating this new feature. However, to ensure robust testing and maintain the high quality of the codebase, consider the following improvements:

  1. Add specific tests for RequestFeedbackButtonComponent to verify its behavior within the CodeEditorContainerComponent.
  2. Update existing tests if RequestFeedbackButtonComponent interacts with or affects the behavior of other components.
  3. If applicable, add tests for any new functionality introduced by RequestFeedbackButtonComponent.

These additions will help maintain the comprehensive test coverage evident in the rest of the file.

Also applies to: 127-127

Comment on lines +391 to +395
// submissions.results is always undefined so this is neccessary
return (
this.gradedParticipation.submissions.last()?.id ===
this.gradedParticipation?.results.filter((result) => result.assessmentType == AssessmentType.AUTOMATIC_ATHENA).first()?.submission?.id
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential runtime errors due to non-standard first() and last() methods on arrays

JavaScript arrays do not have first() and last() methods by default, which could lead to runtime errors. Consider using array indexing to access the first and last elements.

Apply this diff to fix the issue:

-return (
-    this.gradedParticipation.submissions.last()?.id ===
-    this.gradedParticipation?.results.filter((result) => result.assessmentType == AssessmentType.AUTOMATIC_ATHENA).first()?.submission?.id
-);
+const latestSubmissionId = this.gradedParticipation.submissions?.[this.gradedParticipation.submissions.length - 1]?.id;
+const firstAthenaResultSubmissionId = this.gradedParticipation?.results.filter((result) => result.assessmentType === AssessmentType.AUTOMATIC_ATHENA)?.[0]?.submission?.id;
+return latestSubmissionId === firstAthenaResultSubmissionId;
📝 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
// submissions.results is always undefined so this is neccessary
return (
this.gradedParticipation.submissions.last()?.id ===
this.gradedParticipation?.results.filter((result) => result.assessmentType == AssessmentType.AUTOMATIC_ATHENA).first()?.submission?.id
);
// submissions.results is always undefined so this is necessary
const latestSubmissionId = this.gradedParticipation.submissions?.[this.gradedParticipation.submissions.length - 1]?.id;
const firstAthenaResultSubmissionId = this.gradedParticipation?.results.filter((result) => result.assessmentType === AssessmentType.AUTOMATIC_ATHENA)?.[0]?.submission?.id;
return latestSubmissionId === firstAthenaResultSubmissionId;

@@ -382,7 +381,7 @@ private ResponseEntity<StudentParticipation> handleExerciseFeedbackRequest(Exerc
throw new BadRequestAlertException("Not intended for the use in exams", "participation", "preconditions not met");
}
if (exercise.getDueDate() != null && now().isAfter(exercise.getDueDate())) {
throw new BadRequestAlertException("The due date is over", "participation", "preconditions not met");
throw new BadRequestAlertException("The due date is over", "participation", "feedbackRequestAfterDueDate", true);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Consider using AccessForbiddenException instead of BadRequestAlertException

Requesting feedback after the due date is a forbidden action. Using AccessForbiddenException, which results in a 403 Forbidden status code, would more accurately represent the access restriction compared to BadRequestAlertException (400 Bad Request).

@@ -393,7 +392,7 @@
StudentParticipation participation = (exercise instanceof ProgrammingExercise)
? programmingExerciseParticipationService.findStudentParticipationByExerciseAndStudentId(exercise, principal.getName())
: studentParticipationRepository.findByExerciseIdAndStudentLogin(exercise.getId(), principal.getName())
.orElseThrow(() -> new ResourceNotFoundException("Participation not found"));
.orElseThrow(() -> new BadRequestAlertException("Participation not found", "participation", "noSubmissionExists", true));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use EntityNotFoundException for missing participation

When a participation is not found, it's appropriate to throw an EntityNotFoundException, which corresponds to a 404 Not Found status code. This provides a clearer indication of the error compared to BadRequestAlertException (400 Bad Request).

EneaGore
EneaGore previously approved these changes Oct 1, 2024
Copy link
Contributor

@EneaGore EneaGore left a comment

Choose a reason for hiding this comment

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

Tested on TS1. Works as described.

@undernagruzez undernagruzez changed the base branch from develop to feature/programming-exercises/revised-feedback October 1, 2024 10:46
@undernagruzez undernagruzez changed the base branch from feature/programming-exercises/revised-feedback to develop October 1, 2024 10:46
@undernagruzez undernagruzez dismissed EneaGore’s stale review October 1, 2024 10:46

The base branch was changed.

Copy link

There hasn't been any activity on this pull request recently. Therefore, this pull request has been automatically marked as stale and will be closed if no further activity occurs within seven days. Thank you for your contributions.

@undernagruzez
Copy link
Contributor Author

Implemented in #refactoring of preli

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client Pull requests that update TypeScript code. (Added Automatically!) exercise Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module server Pull requests that update Java code. (Added Automatically!) stale tests
Projects
Status: Ready For Review
Development

Successfully merging this pull request may close these issues.

2 participants