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

Adaptive learning: Improve competency student view #9916

Merged
merged 7 commits into from
Dec 2, 2024

Conversation

MaximilianAnzinger
Copy link
Collaborator

@MaximilianAnzinger MaximilianAnzinger commented Nov 30, 2024

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.
  • I added multiple integration tests (Jest) related to the features (with a high test coverage), while following the test guidelines.
  • I documented the TypeScript code using JSDoc style.

Motivation and Context

The student view of competencies shows competencies that are not linked to any resources. Furthermore the order of the competencies might be confusing.

Description

  • Adjusted endpoint to support request param to filter out competencies without existing exercise or lecture unit links
  • Client: Sort list of competency in student view by due date

Steps for Testing

Prerequisites:

  • 1 Students
  • at least one exercise / lecture unit
  • at least 4 competencies
  1. Competency without due date but linked to exercise / lecture unit

  2. Competency with due date and linked to exercise / lecture unit

  3. Competency with due date and linked to exercise / lecture unit

  4. Competency that is not linked to any exercise / lecture unit

  5. Log in to Artemis

  6. Navigate to Course Competencies

  7. You should not see the Competency that isn't linked to any exercise / lecture unit

  8. You should see all the other competencies ordered by the due date (earliest first, no due date last)

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

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Summary by CodeRabbit

  • New Features

    • Introduced a method to filter course competencies based on their linkage to learning objects.
    • Added functionality to retrieve filtered course competencies in the user interface.
    • Implemented sorting of competencies by their due dates.
    • Enhanced the ability to retrieve competencies with additional filtering options.
  • Bug Fixes

    • Enhanced filtering logic to ensure accurate retrieval of competencies.
  • Tests

    • Expanded test coverage for filtered competency retrieval scenarios.

@github-actions github-actions bot added tests server Pull requests that update Java code. (Added Automatically!) client Pull requests that update TypeScript code. (Added Automatically!) atlas Pull requests that affect the corresponding module labels Nov 30, 2024
@MaximilianAnzinger MaximilianAnzinger marked this pull request as ready for review November 30, 2024 10:46
@MaximilianAnzinger MaximilianAnzinger requested a review from a team as a code owner November 30, 2024 10:46
Copy link

coderabbitai bot commented Nov 30, 2024

Walkthrough

The pull request introduces enhancements to the course competency management system by adding a new method to the CourseCompetencyRepository for retrieving competencies linked to learning objects. It updates the CourseCompetencyService and CourseCompetencyResource classes to include a filtering option for competencies. Additionally, the frontend service has been modified to support filtering in HTTP requests, and various integration tests have been expanded to validate these new features, particularly focusing on filtered competency retrieval.

Changes

File Change Summary
src/main/java/de/tum/cit/aet/artemis/atlas/repository/CourseCompetencyRepository.java Added method findByCourseIdAndLinkedToLearningObjectOrderById(long courseId) for specific queries.
src/main/java/de/tum/cit/aet/artemis/atlas/service/competency/CourseCompetencyService.java Updated method signature to findCourseCompetenciesWithProgressForUserByCourseId(long courseId, long userId, boolean filter) for filtering capabilities.
src/main/java/de/tum/cit/aet/artemis/atlas/web/CourseCompetencyResource.java Updated method signature to getCourseCompetenciesWithProgress(long courseId, boolean filter) to include filtering parameter.
src/main/webapp/app/course/competencies/course-competency.service.ts Updated method signature to getAllForCourse(courseId: number, filtered = false) to support filtering in HTTP requests.
src/main/webapp/app/entities/competency.model.ts Added method compareSoftDueDate(a: CourseCompetency, b: CourseCompetency): number for sorting competencies.
src/main/webapp/app/overview/course-competencies/course-competencies.component.ts Updated loadData method to utilize the new filtering and sorting functionalities.
src/test/java/de/tum/cit/aet/artemis/atlas/competency/AbstractCompetencyPrerequisiteIntegrationTest.java Added abstract method getAllFilteredCall(long courseId, HttpStatus expectedStatus) and test method shouldReturnCompetenciesForCourseFiltered(CourseCompetency newCompetency) for filtered competency tests.
src/test/java/de/tum/cit/aet/artemis/atlas/competency/CompetencyIntegrationTest.java Introduced method getAllFilteredCall throwing UnsupportedOperationException indicating unsupported functionality.
src/test/java/de/tum/cit/aet/artemis/atlas/competency/CourseCompetencyIntegrationTest.java Added getAllFilteredCall method for filtered competency retrieval and test method shouldReturnCompetenciesForStudentOfCourseFiltered().
src/test/java/de/tum/cit/aet/artemis/atlas/competency/PrerequisiteIntegrationTest.java Introduced method getAllFilteredCall throwing UnsupportedOperationException for prerequisites.

Possibly related PRs

Suggested labels

enhancement, ready to merge, core, exam, exercise, modeling, programming, quiz, text

Suggested reviewers

  • JohannesStoehr
  • Jan-Thurner
  • florian-glombik
  • az108
  • pzdr7
  • HanyangXu0508

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 pmd (7.7.0)
src/test/java/de/tum/cit/aet/artemis/atlas/competency/AbstractCompetencyPrerequisiteIntegrationTest.java

The following rules are missing or misspelled in your ruleset file category/vm/bestpractices.xml: BooleanInstantiation, DontImportJavaLang, DuplicateImports, EmptyFinallyBlock, EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, EmptyStatementNotInLoop, EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, EmptyWhileStmt, ExcessiveClassLength, ExcessiveMethodLength, ImportFromSamePackage, MissingBreakInSwitch, SimplifyBooleanAssertion. Please check your ruleset configuration.

src/test/java/de/tum/cit/aet/artemis/atlas/competency/CourseCompetencyIntegrationTest.java

The following rules are missing or misspelled in your ruleset file category/vm/bestpractices.xml: BooleanInstantiation, DontImportJavaLang, DuplicateImports, EmptyFinallyBlock, EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, EmptyStatementNotInLoop, EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, EmptyWhileStmt, ExcessiveClassLength, ExcessiveMethodLength, ImportFromSamePackage, MissingBreakInSwitch, SimplifyBooleanAssertion. Please check your ruleset configuration.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6d5bc75 and 1455912.

📒 Files selected for processing (2)
  • src/test/java/de/tum/cit/aet/artemis/atlas/competency/AbstractCompetencyPrerequisiteIntegrationTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/atlas/competency/CourseCompetencyIntegrationTest.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/test/java/de/tum/cit/aet/artemis/atlas/competency/CourseCompetencyIntegrationTest.java
  • src/test/java/de/tum/cit/aet/artemis/atlas/competency/AbstractCompetencyPrerequisiteIntegrationTest.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 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: 2

🧹 Outside diff range and nitpick comments (11)
src/main/webapp/app/overview/course-competencies/course-competencies.component.ts (2)

89-89: Consider using a named constant for the boolean parameter

While the service call is correct, using a magic value true reduces code readability. Consider introducing a named constant to clarify the parameter's purpose.

-const courseCompetencyObservable = this.courseCompetencyService.getAllForCourse(this.courseId, true);
+const INCLUDE_SOFT_DUE_DATE = true;
+const courseCompetencyObservable = this.courseCompetencyService.getAllForCourse(this.courseId, INCLUDE_SOFT_DUE_DATE);

95-96: Consider combining filter and sort operations for better performance

While the current implementation is correct, we can optimize it by using a single array traversal for both filtering and sorting operations.

-this.competencies = courseCompetenciesResponse
-    .filter((competency) => competency.type === CourseCompetencyType.COMPETENCY)
-    .sort(compareSoftDueDate);
+this.competencies = courseCompetenciesResponse.reduce((acc, competency) => {
+    if (competency.type === CourseCompetencyType.COMPETENCY) {
+        const insertIndex = acc.findIndex(c => compareSoftDueDate(competency, c) < 0);
+        if (insertIndex === -1) {
+            acc.push(competency);
+        } else {
+            acc.splice(insertIndex, 0, competency);
+        }
+    }
+    return acc;
+}, [] as Competency[]);
src/main/webapp/app/entities/competency.model.ts (1)

291-296: Documentation should specify the sorting order and null handling behavior.

While the JSDoc is present, it would be more helpful to explicitly document:

  • The sorting order (ascending by due date)
  • How null/undefined dates are handled (placed last)

Add these details to the JSDoc:

 /**
  * Simple comparator for sorting competencies by their soft due date
+ * Competencies are sorted in ascending order by their soft due date.
+ * Competencies without a due date are placed last in the sort order.
  * @param a The first competency
  * @param b The second competency
+ * @returns -1 if a comes before b, 0 if equal, 1 if a comes after b
  */
src/main/webapp/app/course/competencies/course-competency.service.ts (2)

77-83: Add JSDoc documentation for the new parameter.

The implementation looks good and aligns with the PR objectives. However, the method should be documented to explain the purpose of the filtered parameter.

Add JSDoc documentation:

+    /**
+     * Retrieves all competencies for a course.
+     * @param courseId - The ID of the course
+     * @param filtered - When true, returns only competencies that are linked to exercises or lecture units
+     * @returns Observable of course competencies wrapped in an HTTP response
+     */
     getAllForCourse(courseId: number, filtered = false): Observable<EntityArrayResponseType> {

77-83: Consider using type-safe query parameters.

While the implementation is functional, using string literals for query parameters can be error-prone. Consider using HttpParams for better type safety and maintainability.

Here's a suggested improvement:

     getAllForCourse(courseId: number, filtered = false): Observable<EntityArrayResponseType> {
+        const params = filtered ? new HttpParams().set('filter', 'true') : new HttpParams();
         return this.httpClient
-            .get<CourseCompetency[]>(`${this.resourceURL}/courses/${courseId}/course-competencies${filtered ? '?filter=true' : ''}`, { observe: 'response' })
+            .get<CourseCompetency[]>(`${this.resourceURL}/courses/${courseId}/course-competencies`, { params, observe: 'response' })
             .pipe(
                 map((res: EntityArrayResponseType) => this.convertArrayResponseDatesFromServer(res)),
                 tap((res: EntityArrayResponseType) => res?.body?.forEach(this.sendTitlesToEntityTitleService.bind(this))),
             );
     }
src/main/java/de/tum/cit/aet/artemis/atlas/repository/CourseCompetencyRepository.java (1)

298-304: Consider performance optimization for SIZE checks

The current query uses SIZE function in the WHERE clause which might not perform optimally for large datasets as it requires checking collection sizes for each competency.

Consider these alternatives:

  1. Use EXISTS subqueries which can be more efficient:
     @Query("""
             SELECT c
             FROM CourseCompetency c
             WHERE c.course.id = :courseId
-                AND (SIZE(c.lectureUnitLinks) > 0 OR SIZE(c.exerciseLinks) > 0)
+                AND (EXISTS (SELECT 1 FROM c.lectureUnitLinks) OR EXISTS (SELECT 1 FROM c.exerciseLinks))
             ORDER BY c.id
             """)
  1. Or use JOIN FETCH with DISTINCT if you need the relationships loaded:
     @Query("""
-            SELECT c
+            SELECT DISTINCT c
             FROM CourseCompetency c
+                LEFT JOIN FETCH c.lectureUnitLinks lul
+                LEFT JOIN FETCH c.exerciseLinks el
             WHERE c.course.id = :courseId
-                AND (SIZE(c.lectureUnitLinks) > 0 OR SIZE(c.exerciseLinks) > 0)
+                AND (lul IS NOT NULL OR el IS NOT NULL)
             ORDER BY c.id
             """)
src/test/java/de/tum/cit/aet/artemis/atlas/competency/PrerequisiteIntegrationTest.java (1)

112-115: LGTM! Consider adding a test for the unsupported operation.

The implementation correctly indicates that filtering is not supported for prerequisites through an UnsupportedOperationException. This follows best practices by explicitly defining unsupported operations.

Consider adding a test case to verify this unsupported operation:

+ @Test
+ @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
+ void shouldThrowUnsupportedOperationForFiltering() {
+     assertThatThrownBy(() -> getAllFilteredCall(course.getId(), HttpStatus.OK))
+         .isInstanceOf(UnsupportedOperationException.class)
+         .hasMessage("Not implemented for prerequisites");
+ }
src/main/java/de/tum/cit/aet/artemis/atlas/web/CourseCompetencyResource.java (1)

170-174: Add JavaDoc for the new filter parameter.

The method implementation looks good, but the JavaDoc should be updated to document the new filter parameter.

     /**
      * GET courses/:courseId/course-competencies : gets all the course competencies of a course
      *
      * @param courseId the id of the course for which the competencies should be fetched
+     * @param filter whether to filter out competencies that are not linked to any exercises or lecture units (defaults to false)
      * @return the ResponseEntity with status 200 (OK) and with body the found competencies
      */
src/main/java/de/tum/cit/aet/artemis/atlas/service/competency/CourseCompetencyService.java (1)

131-137: Consider extracting the repository call logic to a private method.

While the implementation is correct, the conditional logic could be made more maintainable by extracting it to a private method. This would align with the single responsibility principle and improve code reusability.

Consider this refactoring:

-        List<CourseCompetency> competencies;
-        if (filter) {
-            competencies = courseCompetencyRepository.findByCourseIdAndLinkedToLearningObjectOrderById(courseId);
-        }
-        else {
-            competencies = courseCompetencyRepository.findByCourseIdOrderById(courseId);
-        }
+        List<CourseCompetency> competencies = fetchCompetenciesForCourse(courseId, filter);
         return findProgressForCompetenciesAndUser(competencies, userId);
+    }
+
+    private List<CourseCompetency> fetchCompetenciesForCourse(long courseId, boolean filter) {
+        return filter
+            ? courseCompetencyRepository.findByCourseIdAndLinkedToLearningObjectOrderById(courseId)
+            : courseCompetencyRepository.findByCourseIdOrderById(courseId);
src/test/java/de/tum/cit/aet/artemis/atlas/competency/CourseCompetencyIntegrationTest.java (1)

160-164: Add test documentation to clarify the test's purpose.

Consider adding a descriptive JavaDoc comment to explain what this test verifies, including:

  • The expected behavior when filtering competencies
  • The test's prerequisites
  • The expected outcome
+/**
+ * Verifies that a student can successfully retrieve filtered competencies for their course.
+ * The filtering ensures that only competencies linked to exercises or lecture units are returned.
+ */
 @Test
 @WithMockUser(username = TEST_PREFIX + "student1", roles = "USER")
 void shouldReturnCompetenciesForStudentOfCourseFiltered() throws Exception {
     super.shouldReturnCompetenciesForCourseFiltered(new Competency());
 }
src/test/java/de/tum/cit/aet/artemis/atlas/competency/AbstractCompetencyPrerequisiteIntegrationTest.java (1)

230-241: Enhance test coverage for filtered competencies.

While the test verifies that unlinked competencies are excluded, consider adding the following improvements:

  1. Add positive test cases to verify competencies that should be included in the filtered results
  2. Add test cases for edge cases (e.g., competencies with only exercise links, only lecture unit links)
  3. Consider renaming the test to be more specific, e.g., shouldNotReturnUnlinkedCompetenciesWhenFiltered
-    void shouldReturnCompetenciesForCourseFiltered(CourseCompetency newCompetency) throws Exception {
+    void shouldNotReturnUnlinkedCompetenciesWhenFiltered(CourseCompetency newCompetency) throws Exception {
         newCompetency.setTitle("Title");
         newCompetency.setDescription("Description");
         newCompetency.setCourse(course);
         courseCompetencyRepository.save(newCompetency);
 
         List<? extends CourseCompetency> competenciesOfCourse = getAllFilteredCall(course.getId(), HttpStatus.OK);
 
         assertThat(competenciesOfCourse).noneMatch(c -> c.getId().equals(courseCompetency.getId()));
+        
+        // Add positive test case
+        CompetencyExerciseLink link = new CompetencyExerciseLink(newCompetency, textExercise, 1);
+        competencyExerciseLinkRepository.save(link);
+        
+        competenciesOfCourse = getAllFilteredCall(course.getId(), HttpStatus.OK);
+        assertThat(competenciesOfCourse).anyMatch(c -> c.getId().equals(newCompetency.getId()));
     }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2611d04 and 6e5e013.

📒 Files selected for processing (10)
  • src/main/java/de/tum/cit/aet/artemis/atlas/repository/CourseCompetencyRepository.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/atlas/service/competency/CourseCompetencyService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/atlas/web/CourseCompetencyResource.java (1 hunks)
  • src/main/webapp/app/course/competencies/course-competency.service.ts (1 hunks)
  • src/main/webapp/app/entities/competency.model.ts (1 hunks)
  • src/main/webapp/app/overview/course-competencies/course-competencies.component.ts (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/atlas/competency/AbstractCompetencyPrerequisiteIntegrationTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/atlas/competency/CompetencyIntegrationTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/atlas/competency/CourseCompetencyIntegrationTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/atlas/competency/PrerequisiteIntegrationTest.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
src/main/webapp/app/entities/competency.model.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/course/competencies/course-competency.service.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/java/de/tum/cit/aet/artemis/atlas/competency/CompetencyIntegrationTest.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/java/de/tum/cit/aet/artemis/atlas/competency/PrerequisiteIntegrationTest.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/main/webapp/app/overview/course-competencies/course-competencies.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/java/de/tum/cit/aet/artemis/atlas/repository/CourseCompetencyRepository.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/test/java/de/tum/cit/aet/artemis/atlas/competency/AbstractCompetencyPrerequisiteIntegrationTest.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/main/java/de/tum/cit/aet/artemis/atlas/web/CourseCompetencyResource.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/atlas/service/competency/CourseCompetencyService.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/test/java/de/tum/cit/aet/artemis/atlas/competency/CourseCompetencyIntegrationTest.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

🔇 Additional comments (9)
src/main/webapp/app/overview/course-competencies/course-competencies.component.ts (1)

6-6: LGTM: Import changes follow guidelines

The addition of compareSoftDueDate to the existing competency model imports is clean and follows the TypeScript coding guidelines.

src/main/webapp/app/entities/competency.model.ts (2)

296-310: LGTM! Implementation handles all cases correctly.

The comparator function:

  • Properly handles all combinations of present/absent due dates
  • Uses appropriate dayjs methods for date comparison
  • Returns correct comparator values (-1, 0, 1)
  • Aligns with the PR objective of sorting competencies by due date

296-310: Verify consistent usage of the comparator function.

Let's ensure this comparator is used consistently throughout the codebase for competency sorting.

✅ Verification successful

Let me gather more context about the sorting implementations to ensure completeness of the verification.


Based on the gathered information, I can now provide the final response:

Different sorting mechanisms are used appropriately in distinct contexts

The compareSoftDueDate function is used specifically for sorting competencies by due date in the course overview component, while the import-related components use a generic sorting service for different sorting needs. This separation of concerns is correct as:

  • Course overview uses compareSoftDueDate to sort by due dates
  • Import components use sortService.sortByProperty for flexible column-based sorting
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of compareSoftDueDate to ensure consistent sorting implementation

# Search for direct usage of the comparator
echo "Searching for direct usage of compareSoftDueDate..."
rg "compareSoftDueDate" --type ts

# Search for array sorting operations on competencies to verify consistent sorting
echo "Searching for competency sorting operations..."
rg "sort.*Competenc" --type ts

Length of output: 1290


Script:

#!/bin/bash
# Check the implementation of sorting in the import components
echo "Checking implementation in import components..."
rg -A 5 "sortSelected" src/main/webapp/app/course/competencies/import/import-course-competencies.component.ts

echo "Checking sortService implementation..."
rg -A 5 "sortByProperty" src/main/webapp/app/course/competencies/import-standardized-competencies/course-import-standardized-course-competencies.component.ts

# Check if there are any other competency-related sorting utilities
echo "Checking for other competency-related sorting utilities..."
ast-grep --pattern 'function $FUNC($_, $_): number { $$$' src/main/webapp/app/entities/competency.model.ts

Length of output: 1404

src/test/java/de/tum/cit/aet/artemis/atlas/competency/CompetencyIntegrationTest.java (1)

112-115: ⚠️ Potential issue

Implementation appears inconsistent with PR objectives

The PR objectives mention implementing filtering for competencies not linked to exercises/lecture units, but this method throws UnsupportedOperationException. This seems to contradict the intended functionality.

Consider either:

  1. Implementing the filtering functionality in this method to align with PR objectives
  2. Adding a comment explaining why filtering is handled differently for competencies
  3. Creating separate test methods specifically for the new filtering functionality

Let's verify if filtering is implemented elsewhere:

src/main/java/de/tum/cit/aet/artemis/atlas/web/CourseCompetencyResource.java (1)

170-174: LGTM! Implementation follows best practices.

The changes look good:

  • Proper use of @RequestParam with default value
  • Consistent error handling through service layer
  • Maintains existing security constraints
  • Follows REST controller patterns
src/main/java/de/tum/cit/aet/artemis/atlas/service/competency/CourseCompetencyService.java (2)

127-130: Good use of primitive types for better performance!

The change from Long to long for parameters aligns with the coding guideline to prefer primitives when null values aren't needed.


130-130: Verify all callers are updated with the new parameter.

Let's verify that all calling code has been updated to handle the new filter parameter.

✅ Verification successful

All callers are correctly updated with the new filter parameter

The method is only called in one place in CourseCompetencyResource.java and it correctly passes the filter parameter to the service method. No other usages were found in the codebase, confirming that all callers have been properly updated.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for method calls to ensure they're updated with the filter parameter
rg -A 2 "findCourseCompetenciesWithProgressForUserByCourseId\(" --type java

Length of output: 979

src/test/java/de/tum/cit/aet/artemis/atlas/competency/CourseCompetencyIntegrationTest.java (1)

155-158: LGTM!

The implementation correctly overrides the parent method and follows the established pattern for making HTTP requests in the test class.

src/test/java/de/tum/cit/aet/artemis/atlas/competency/AbstractCompetencyPrerequisiteIntegrationTest.java (1)

228-229: LGTM! Method signature follows established patterns.

The abstract method declaration is well-designed and consistent with other abstract methods in the class.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 30, 2024
sachmii
sachmii previously approved these changes Nov 30, 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 TS6, everything works fine.

Bildschirmfoto 2024-11-30 um 12 19 15 Bildschirmfoto 2024-11-30 um 12 19 25

kevinfischer4
kevinfischer4 previously approved these changes Nov 30, 2024
Copy link

@kevinfischer4 kevinfischer4 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 TS4, works as expected.

JohannesWt
JohannesWt previously approved these changes Nov 30, 2024
Copy link
Contributor

@JohannesWt JohannesWt left a comment

Choose a reason for hiding this comment

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

Code 👍

zagemello
zagemello previously approved these changes Dec 2, 2024
Copy link

@zagemello zagemello 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 TS4, all works as expected

ahbitaqu
ahbitaqu previously approved these changes Dec 2, 2024
Copy link

@ahbitaqu ahbitaqu 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 TS4]
Looks good here :)

@krusche krusche merged commit ae08a1e into develop Dec 2, 2024
19 of 25 checks passed
@krusche krusche deleted the feature/adaptive-learning/competency-student-view branch December 2, 2024 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
atlas Pull requests that affect the corresponding module client Pull requests that update TypeScript code. (Added Automatically!) ready for review server Pull requests that update Java code. (Added Automatically!) tests
Projects
Status: Merged
Status: Done
Development

Successfully merging this pull request may close these issues.