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

Text exercises: Replace feedback modal with inline feedback view #9395

Open
wants to merge 125 commits into
base: develop
Choose a base branch
from

Conversation

EneaGore
Copy link
Contributor

@EneaGore EneaGore commented Oct 1, 2024

Deploy only to TS1

Reopened from: #9310

Checklist

General

Server

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

The previous PR in Athena Feedback for Text Exercises added the option to enable preliminary AI Feedback for students. This PR improves the way the feedback is viewed by adding a new route. Enhanced error handling, integration tests and some minor bug fixes are also included.

Description

Create new route to view the (preliminary) results inline on the text submission. Add the timeline to that view and make results not show the modal but use that route for text exercises.

Steps for Testing

Prerequisites:

  • 1 Student
  • 1 Text Exercise
  1. Open a text exercise with athena feedback requests avilable
  2. Request feedback from inside the editor and from the overview
  3. Click on results and check that the correct submission is shown
  4. Assessment should continue working as usual

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

Test Coverage

✅ ❌

Class/File Line Coverage Confirmation (assert/expect)
header-participation-page.component.ts 100%
exercise-scores.component.ts 95.59%
feedback.component.ts 95%
rating.component.ts 91.66%
result.component.ts 88.81%
result.service.ts 90.75%
result.utils.ts 89.94%
text-editor.component.ts 82.5%
text-editor.route.ts 100%
course-exercise-details.component.ts 88.37%
exercise-details-student-actions.component.ts 86.33%

Screenshots

newAIButton
view
Flow

H01E01.Coupling.and.Cohesion.WS24._.Test.Course.Enea.Gore.-.Google.Chrome.2024-09-14.06-37-35.mp4

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced feedback request handling with new user messages for pending changes.
    • Improved exercise participation management with better error handling and access control.
    • New buttons for "Continue Submission" and "Request Feedback" in the text editor.
    • Added support for localized action labels in both German and English.
    • Dynamic filtering for exercise scores based on user input.
    • New functionality for viewing and hiding the timeline of submissions.
    • Introduction of a new feedback button component to streamline feedback requests.
  • Bug Fixes

    • Refined filtering logic for exercise scores and participation results.
    • Improved navigation handling for text exercises.
    • Adjusted success alert messages based on feedback generation results.
  • Documentation

    • Updated localization strings for improved clarity and accuracy.
  • Chores

    • General code refactoring for improved maintainability and readability.

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: 2

🧹 Outside diff range and nitpick comments (3)
src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.ts (2)

32-34: Add documentation for input properties.

Consider adding JSDoc comments to document the purpose and usage of these input properties. This will improve code maintainability and help other developers understand how to use this component correctly.

+    /** Indicates whether the exercise has been submitted */
     isSubmitted = input<boolean>();
+    /** Indicates whether there are unsaved changes in the exercise */
     pendingChanges = input<boolean>(false);
+    /** Indicates whether the latest submission has an Athena result */
     hasAthenaResultForLatestSubmission = input<boolean>(false);

Line range hint 91-101: Update method documentation to reflect current implementation.

The current documentation doesn't reflect all conditions and exercise types handled by the method. Update it to include MODELING type and text-specific conditions.

     /**
      * Checks if the conditions for requesting automatic non-graded feedback are satisfied.
      * The student can request automatic non-graded feedback under the following conditions:
+     * For PROGRAMMING and MODELING exercises:
      * 1. They have a graded submission.
      * 2. The deadline for the exercise has not been exceeded.
      * 3. There is no already pending feedback request.
+     * For TEXT exercises:
+     * 1. No Athena result exists for the latest submission
+     * 2. There are no pending changes
      * @returns {boolean} `true` if all conditions are satisfied, otherwise `false`.
      */
src/test/javascript/spec/component/overview/exercise-details/request-feedback-button/request-feedback-button.component.spec.ts (1)

Line range hint 1-238: Enhance test specificity and mocking practices.

While the test suite is well-structured, consider these improvements to align better with the coding guidelines:

  1. Use more specific assertions:

    • Replace toBeTrue()/toBeFalse() with toBe(true)/toBe(false) for boolean assertions
    • Add component state checks alongside DOM checks
    • Use toHaveBeenCalledExactlyOnceWith instead of toHaveBeenCalled
  2. Mock improvements:

    • Use MockProvider consistently for all services
    • Mock irrelevant dependencies more aggressively
    • Consider using jest.mocked() for better type safety
  3. Error handling:

    • Add test cases for different error scenarios
    • Verify error message content more specifically
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between be59db6 and 7c466a4.

📒 Files selected for processing (5)
  • src/main/webapp/app/exercises/text/participate/text-editor.component.html (4 hunks)
  • src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html (1 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 (2 hunks)
  • src/test/javascript/spec/component/overview/exercise-details/request-feedback-button/request-feedback-button.component.spec.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/webapp/app/exercises/text/participate/text-editor.component.html
  • src/main/webapp/app/overview/exercise-details/exercise-details-student-actions.component.html
🧰 Additional context used
📓 Path-based instructions (3)
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/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}}

🔇 Additional comments (3)
src/main/webapp/app/overview/exercise-details/request-feedback-button/request-feedback-button.component.html (2)

Line range hint 1-3: LGTM: Proper usage of new Angular control flow syntax.

The template correctly uses the new @if syntax instead of the older *ngIf directives, following the latest Angular best practices and project coding guidelines.


8-8: LGTM: Clean refactoring of disabled state condition.

The simplified condition !isSubmitted() improves readability by moving the complex logic to the component class. This change makes the template more maintainable and easier to understand.

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

113-116: ⚠️ Potential issue

Fix input property access.

The hasAthenaResultForLatestSubmission is an input property but is being called as a method. This needs to be fixed to access the property value correctly.

-        if (this.hasAthenaResultForLatestSubmission()) {
+        if (this.hasAthenaResultForLatestSubmission()) {

Likely invalid or redundant comment.

Copy link

⚠️ Unable to deploy to test servers ⚠️

The docker build needs to run through before deploying.

@github-actions github-actions bot added the deployment-error Added by deployment workflows if an error occured label Oct 27, 2024
coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 27, 2024
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: 0

🧹 Outside diff range and nitpick comments (2)
src/test/javascript/spec/component/overview/exercise-details/request-feedback-button/request-feedback-button.component.spec.ts (2)

218-219: Enhance test specificity with additional assertions.

While the test correctly verifies the button state, consider adding assertions to explicitly verify that both conditions influence the button's enabled state:

expect(component.isSubmitted).toBeTrue();
expect(component.isGeneratingFeedback).toBeFalse();

This makes it clearer which conditions are being tested and helps with debugging if the test fails.


Line range hint 1-230: Add test coverage for missing scenarios.

The test suite is missing coverage for:

  1. The pendingChanges input property's effect on the button state
  2. The case when isGeneratingFeedback is true but isSubmitted is also true

Consider adding these test cases:

it('should disable the button when there are pending changes', fakeAsync(() => {
    setAthenaEnabled(true);
    const participation = {
        id: 1,
        submissions: [{ id: 1, submitted: true }],
        testRun: false,
    } as StudentParticipation;
    const exercise = { id: 1, type: ExerciseType.TEXT, studentParticipations: [participation], course: {}, allowFeedbackRequests: true } as Exercise;
    fixture.componentRef.setInput('exercise', exercise);
    fixture.componentRef.setInput('isSubmitted', true);
    fixture.componentRef.setInput('isGeneratingFeedback', false);
    fixture.componentRef.setInput('pendingChanges', true);
    mockExerciseDetails(exercise);

    component.ngOnInit();
    tick();
    fixture.detectChanges();

    const button = debugElement.query(By.css('button'));
    expect(button.nativeElement.disabled).toBeTrue();
    expect(component.pendingChanges).toBeTrue();
}));

it('should disable the button when feedback is being generated regardless of submission state', fakeAsync(() => {
    setAthenaEnabled(true);
    const participation = {
        id: 1,
        submissions: [{ id: 1, submitted: true }],
        testRun: false,
    } as StudentParticipation;
    const exercise = { id: 1, type: ExerciseType.TEXT, studentParticipations: [participation], course: {}, allowFeedbackRequests: true } as Exercise;
    fixture.componentRef.setInput('exercise', exercise);
    fixture.componentRef.setInput('isSubmitted', true);
    fixture.componentRef.setInput('isGeneratingFeedback', true);
    mockExerciseDetails(exercise);

    component.ngOnInit();
    tick();
    fixture.detectChanges();

    const button = debugElement.query(By.css('button'));
    expect(button.nativeElement.disabled).toBeTrue();
    expect(component.isGeneratingFeedback).toBeTrue();
}));
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 7c466a4 and ba65dc0.

📒 Files selected for processing (1)
  • src/test/javascript/spec/component/overview/exercise-details/request-feedback-button/request-feedback-button.component.spec.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
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}}

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

196-197: Past review comment is still applicable.

The existing review comment about splitting this test case into multiple test cases for better coverage is still valid.

Copy link

@HawKhiem HawKhiem 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. Reapprove

image

@krusche krusche modified the milestones: 7.6.4, 7.6.5 Oct 27, 2024
Copy link

@sachmii sachmii 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, still works fine. Re-approve

Copy link

@SindiBuklaji SindiBuklaji 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. Re-approved 👍

Copy link
Contributor

@undernagruzez undernagruzez left a comment

Choose a reason for hiding this comment

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

code- latest changes look good to me

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 lock:artemis-test1 playwright server Pull requests that update Java code. (Added Automatically!) tests text Pull requests that affect the corresponding module
Projects
Status: Ready For Review
Development

Successfully merging this pull request may close these issues.