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

Development: Migrate translate/markdown pipes and loading indicator components to standalone #9880

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

Conversation

PaRangger
Copy link
Contributor

@PaRangger PaRangger commented Nov 27, 2024

Checklist

General

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 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.

Motivation and Context

This is an effort to migrate some core components to the new angular apis. The process was covered in the all hands meeting and can be seen here. This PR addresses some core components which are used frequently in the communication module:

ID File Standalone Signals Inject
387 /shared/loading-indicator-container/loading-indicator-container.component.html
388 /shared/loading-indicator-container/loading-indicator-container.component.ts
416 /shared/pipes/html-for-markdown.pipe.ts
417 /shared/pipes/html-for-posting-markdown.pipe.ts
410 /shared/pipes/artemis-translate.pipe.ts

Description

I replaced @Input, @Output, @ViewChilds with their corresponding signal equivalent and made sure to call them as functions in their templates. I replaced constructors with inject() functions. I converted them to standalone: true components. Lastly, I tried to fix the failing tests.

Steps for Testing

Prerequisites:

  • 1 Artemis User

These pipes and components are used frequently throughout artemis. Therefore just observe if any problems occur on the entire platform. In these steps I will just guide you to a single occurence of the corresponding pipe/component.

Loading Indicator

  1. Log into Artemis
  2. Navigate to course with communication enabled
  3. Go to the communication tab
  4. Select a channel
  5. For a brief moment you should be able to see a loading indicator
  6. Afterwards it should display the channel messages

HtmlMarkdownPipe/PostingMarkdownPipe

  1. Log into Artemis
  2. Navigate to course with communication enabled
  3. Go to the communication tab
  4. Write a post in any channel, make sure to format it using the editor
  5. Check if it is rendered properly

Translate Pipe

  1. Log in to Artemis
  2. Navigate to course with communication enabled
  3. Go to the communication tab
  4. In the "All messages" tab, or when searching for a term, hover over the "sorting" arrow
  5. The tooltip should be shown appropriately
  6. Change the language on the top right
  7. Hover again over the arrow, the tooltip should have changed to the accoriding language

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

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Test Coverage

Screenshots

Loading Indicator
Bildschirmfoto 2024-11-27 um 14 57 40

HtmlMarkdownPipe/PostingMarkdownPipe
Bildschirmfoto 2024-11-27 um 14 56 40

Translate Pipe
Bildschirmfoto 2024-11-27 um 14 55 32

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced loading indicator functionality to display based on dynamic loading state.
    • Added new pipes for handling HTML in markdown content, allowing for more flexible content rendering.
  • Bug Fixes

    • Improved test setups for various components to ensure accurate testing of functionality.
  • Documentation

    • Updated module structures to reflect changes in pipe and component declarations.
  • Tests

    • Streamlined test configurations to utilize mock implementations for better isolation and clarity.

@PaRangger PaRangger added client Pull requests that update TypeScript code. (Added Automatically!) chore core Pull requests that affect the corresponding module labels Nov 27, 2024
@github-actions github-actions bot added tests and removed core Pull requests that affect the corresponding module labels Nov 27, 2024
@PaRangger PaRangger temporarily deployed to artemis-test3.artemis.cit.tum.de November 27, 2024 14:17 — with GitHub Actions Inactive
@PaRangger PaRangger marked this pull request as ready for review November 27, 2024 14:28
@PaRangger PaRangger requested a review from a team as a code owner November 27, 2024 14:28
Copy link

coderabbitai bot commented Nov 27, 2024

Walkthrough

The pull request introduces several modifications primarily focused on improving the structure and functionality of Angular components and pipes. Key changes include transitioning components to standalone status, updating method signatures, and modifying how loading states are managed. The isLoading property is now handled as a function, and several pipes are updated to utilize Angular's new dependency injection method. Additionally, changes to test setups emphasize the use of mock implementations, enhancing test isolation.

Changes

File Path Change Summary
src/main/webapp/app/shared/loading-indicator-container/loading-indicator-container.component.html Updated isLoading from a boolean variable to a function call isLoading().
src/main/webapp/app/shared/loading-indicator-container/loading-indicator-container.component.ts Changed @Input() to input<boolean>(false) for isLoading, added standalone: true, and included TranslateDirective in the imports array.
src/main/webapp/app/shared/markdown.module.ts Added HtmlForMarkdownPipe to imports and exports arrays in ArtemisMarkdownModule.
src/main/webapp/app/shared/metis/metis.module.ts Removed HtmlForPostingMarkdownPipe from imports and declarations, added it to exports.
src/main/webapp/app/shared/pipes/artemis-translate.pipe.ts Added standalone: true to @Pipe decorator and removed access modifiers from constructor parameters.
src/main/webapp/app/shared/pipes/html-for-markdown.pipe.ts Added standalone: true to @Pipe decorator and initialized markdownService using inject.
src/main/webapp/app/shared/pipes/html-for-posting-markdown.pipe.ts Added standalone: true to @Pipe decorator and initialized markdownService using inject.
src/main/webapp/app/shared/shared-common.module.ts Moved ArtemisTranslatePipe to imports, removed from declarations, kept in exports.
src/main/webapp/app/shared/shared.module.ts Added LoadingIndicatorContainerComponent to imports, removed from declarations.
src/test/javascript/spec/component/assessment-shared/assessment-header.component.spec.ts Updated test setup to use MockPipe for ArtemisTranslatePipe instead of direct declaration.
src/test/javascript/spec/component/shared/metis/posting-content/posting-content-part.component.spec.ts Modified beforeEach to use async/await and moved HtmlForPostingMarkdownPipe to imports.
src/test/javascript/spec/pipe/reacting-users-on-posting.pipe.spec.ts Replaced direct declaration of HtmlForPostingMarkdownPipe with MockPipe in test setup and made beforeEach asynchronous.

Possibly related PRs

Suggested labels

refactoring, small, ready to merge

Suggested reviewers

  • JohannesWt
  • florian-glombik
  • BBesrour
  • HawKhiem
  • edkaya
  • Feras797

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 701bc14 and 2925c0d.

📒 Files selected for processing (1)
  • src/main/webapp/app/shared/pipes/artemis-translate.pipe.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/webapp/app/shared/pipes/artemis-translate.pipe.ts

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

🧹 Outside diff range and nitpick comments (10)
src/main/webapp/app/shared/pipes/artemis-translate.pipe.ts (1)

15-16: Enhance the documentation about ChangeDetectorRef injection

While the code changes are correct, the comment could be more descriptive about why ChangeDetectorRef can't be injected and what the current workaround achieves.

Consider expanding the comment:

-    // We cannot inject() ChangeDetectorRef here
+    // Note: We cannot use inject(ChangeDetectorRef) here as it's not available
+    // in the context where TranslatePipe is instantiated. Instead, we receive it
+    // through constructor injection.
src/main/webapp/app/shared/pipes/html-for-markdown.pipe.ts (1)

Line range hint 13-21: Consider enhancing JSDoc with version information

While the documentation is comprehensive, consider adding a @since tag to indicate when this API was last modified. This helps track API changes across versions.

Example enhancement:

     /**
      * Converts markdown into html, sanitizes it and then declares it as safe to bypass further security.
+     * @since 5.0.0 - Migrated to standalone pipe
      * @param {string} markdown the original markdown text
      * @param {PluginSimple[]} extensions to use for markdown parsing
      * @param {string[]} allowedHtmlTags to allow during sanitization
      * @param {string[]} allowedHtmlAttributes to allow during sanitization
      * @returns {string} the resulting html as a SafeHtml object that can be inserted into the angular template
      */
src/main/webapp/app/shared/pipes/html-for-posting-markdown.pipe.ts (1)

9-11: Consider leveraging type inference for injected service

The dependency injection implementation is clean and follows best practices. For better type safety, consider letting TypeScript infer the type:

-private readonly markdownService = inject(ArtemisMarkdownService);
+private readonly markdownService = inject(ArtemisMarkdownService) as const;
src/main/webapp/app/shared/shared-common.module.ts (1)

18-18: Consider restructuring imports for better organization

The imports array mixes a module (ArtemisSharedLibsModule) with standalone components (TranslateDirective, ArtemisTranslatePipe). Consider grouping them separately for better maintainability.

-    imports: [ArtemisSharedLibsModule, TranslateDirective, ArtemisTranslatePipe],
+    imports: [
+        // Modules
+        ArtemisSharedLibsModule,
+        // Standalone Components
+        TranslateDirective,
+        ArtemisTranslatePipe,
+    ],
src/main/webapp/app/shared/shared.module.ts (1)

Line range hint 34-83: Consider migrating additional components to standalone.

Given the project's initiative to migrate to standalone components, consider evaluating other components in the declarations array for potential standalone migration, particularly:

  • CircularProgressBarComponent
  • SecuredImageComponent
  • DeleteDialogComponent
  • ResizeableContainerComponent

These components appear to be good candidates for standalone migration based on their names suggesting focused, single-responsibility components.

src/test/javascript/spec/pipe/reacting-users-on-posting.pipe.spec.ts (1)

Line range hint 15-24: Consider using more specific spy assertions

While the test setup is good, consider using more specific spy assertions as per our guidelines:

- expect(updateReactingUsersStringSpy).toHaveBeenCalledOnce();
+ expect(updateReactingUsersStringSpy).toHaveBeenCalledExactlyOnceWith();

- expect(updateReactingUsersStringSpy).toHaveBeenCalledTimes(2);
+ expect(updateReactingUsersStringSpy).toHaveBeenCalledTimes(2);
+ expect(updateReactingUsersStringSpy).toHaveBeenNthCalledWith(1, expect.any(Array));
+ expect(updateReactingUsersStringSpy).toHaveBeenNthCalledWith(2, expect.any(Array));
src/test/javascript/spec/component/shared/metis/posting-content/posting-content-part.component.spec.ts (2)

34-39: Consider mocking FaIconComponent for better test isolation

While the comment explains why FaIconComponent isn't mocked, consider using a lightweight mock that still allows icon type verification. This would improve test isolation and performance.

imports: [
    ArtemisTestModule,
    MatDialogModule,
    MatMenuModule,
    HtmlForPostingMarkdownPipe,
+   MockComponent(FaIconComponent),
],
-// FaIconComponent, // we want to test the type of rendered icons, therefore we cannot mock the component

60-62: Enhance spy assertions for better specificity

According to coding guidelines, consider using more specific spy assertions:

  • Replace toHaveBeenCalledOnce() with toHaveBeenCalledExactlyOnceWith()
  • Replace not.toHaveBeenCalled() with not.toHaveBeenCalled()

Example usage in test cases:

expect(navigateByUrlSpy).toHaveBeenCalledExactlyOnceWith('/expected/url');
expect(openAttachmentSpy).toHaveBeenCalledExactlyOnceWith(expectedAttachmentURL);
src/test/javascript/spec/component/assessment-shared/assessment-header.component.spec.ts (2)

52-53: LGTM with suggestions for further improvements.

The TestBed configuration correctly uses MockPipe for ArtemisTranslatePipe, which aligns with the migration to standalone components. However, consider these improvements:

  1. Mock other dependencies that aren't directly related to the test scenarios
  2. Consider using MockComponent for AssessmentWarningComponent and AlertOverlayComponent

Example refactor:

 imports: [ArtemisTestModule, NgbTooltipMocksModule, NgbAlertsMocksModule, RouterModule.forRoot([]), MockPipe(ArtemisTranslatePipe)],
-declarations: [AssessmentHeaderComponent, AssessmentWarningComponent, AlertOverlayComponent, MockTranslateValuesDirective],
+declarations: [
+  AssessmentHeaderComponent,
+  MockComponent(AssessmentWarningComponent),
+  MockComponent(AlertOverlayComponent),
+  MockTranslateValuesDirective
+],

Line range hint 86-86: Enhance test assertions with more specific matchers.

According to the coding guidelines for test specificity, replace generic boolean assertions with more specific jest matchers:

  1. Component creation test:
-expect(component).toBeTruthy();
+expect(component).toBeDefined();
  1. Element query tests:
-expect(warningComponent).toBeTruthy();
+expect(warningComponent).not.toBeNull();

-expect(container).toBeTruthy();
+expect(container).not.toBeNull();

-expect(assessmentLocked).toBeFalsy();
+expect(assessmentLocked).toBeNull();

Also applies to: 95-97, 117-119, 134-136, 144-146, 156-158, 182-184, 200-202

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 83ac531 and 701bc14.

📒 Files selected for processing (12)
  • src/main/webapp/app/shared/loading-indicator-container/loading-indicator-container.component.html (1 hunks)
  • src/main/webapp/app/shared/loading-indicator-container/loading-indicator-container.component.ts (1 hunks)
  • src/main/webapp/app/shared/markdown.module.ts (1 hunks)
  • src/main/webapp/app/shared/metis/metis.module.ts (1 hunks)
  • src/main/webapp/app/shared/pipes/artemis-translate.pipe.ts (1 hunks)
  • src/main/webapp/app/shared/pipes/html-for-markdown.pipe.ts (1 hunks)
  • src/main/webapp/app/shared/pipes/html-for-posting-markdown.pipe.ts (1 hunks)
  • src/main/webapp/app/shared/shared-common.module.ts (1 hunks)
  • src/main/webapp/app/shared/shared.module.ts (1 hunks)
  • src/test/javascript/spec/component/assessment-shared/assessment-header.component.spec.ts (2 hunks)
  • src/test/javascript/spec/component/shared/metis/posting-content/posting-content-part.component.spec.ts (1 hunks)
  • src/test/javascript/spec/pipe/reacting-users-on-posting.pipe.spec.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
src/main/webapp/app/shared/loading-indicator-container/loading-indicator-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/shared/loading-indicator-container/loading-indicator-container.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/shared/markdown.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/shared/metis/metis.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/shared/pipes/artemis-translate.pipe.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/shared/pipes/html-for-markdown.pipe.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/shared/pipes/html-for-posting-markdown.pipe.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/shared/shared-common.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/shared/shared.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/test/javascript/spec/component/assessment-shared/assessment-header.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/shared/metis/posting-content/posting-content-part.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/pipe/reacting-users-on-posting.pipe.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 (19)
src/main/webapp/app/shared/loading-indicator-container/loading-indicator-container.component.html (2)

1-1: Great use of the new Angular control flow syntax!

The template correctly implements the new @if syntax instead of the older *ngIf, which aligns with our coding guidelines.

Also applies to: 7-7


Line range hint 1-9: Verify loading state function implementation

The template now calls isLoading() as a function instead of using it as a property. This change suggests a shift in the component's implementation.

Let's verify the implementation:

✅ Verification successful

The loading state implementation has been correctly updated to use Angular signals

The verification confirms that:

  • The LoadingIndicatorContainerComponent correctly implements isLoading as a signal using input<boolean>(false)
  • The template's usage of isLoading() aligns with the signal-based implementation
  • Other components using @Input() isLoading are unrelated to this component and don't need modifications
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the loading state implementation in the component file
# Expected: Should find the isLoading function implementation using input signal

# Search for the isLoading implementation in the component
ast-grep --pattern 'class LoadingIndicatorContainerComponent {
  $$$
  isLoading = input<boolean>($$$)
  $$$
}'

# Also check for any remaining uses of the old @Input decorator for isLoading
rg "@Input\(\)\s+isLoading" 

Length of output: 2075

src/main/webapp/app/shared/loading-indicator-container/loading-indicator-container.component.ts (2)

1-2: LGTM! Proper migration to Angular signals.

The imports correctly reflect the migration from @Input decorator to the new signals-based input function, and the TranslateDirective import follows Angular's style guide.


8-9: Verify template dependencies for standalone component.

The standalone configuration and TranslateDirective import look correct. However, let's verify if the template requires any additional dependencies.

✅ Verification successful

Component dependencies are correctly configured

The template uses:

  • @if/@else control flow (built into Angular 17+, no import needed)
  • jhiTranslate directive (covered by TranslateDirective import)
  • ng-content (built-in, no import needed)

The current imports configuration is complete and correct for this standalone component.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check template for any missing dependencies that need to be imported

# Check the template file for Angular directives/components usage
cat src/main/webapp/app/shared/loading-indicator-container/loading-indicator-container.component.html | grep -E '*ngIf|*ngFor|[(]|[[]' || echo "No additional Angular directives found"

Length of output: 236


Script:

#!/bin/bash
# Let's check the full template content to understand all dependencies
cat src/main/webapp/app/shared/loading-indicator-container/loading-indicator-container.component.html

# Also check the component file for any signal or function declarations
cat src/main/webapp/app/shared/loading-indicator-container/loading-indicator-container.component.ts

Length of output: 951

src/main/webapp/app/shared/pipes/artemis-translate.pipe.ts (1)

7-7: LGTM! Verify module imports for standalone pipe

The migration to a standalone pipe aligns with Angular's recommended architecture.

Let's verify the module imports have been updated correctly:

✅ Verification successful

Based on the search results, I can now generate the final response:

Standalone pipe migration is correctly implemented

The pipe is correctly migrated to standalone mode and all its usages in test files have been updated to use MockPipe(ArtemisTranslatePipe). The pipe is properly imported in shared modules (shared-common.module.ts and shared-pipes.module.ts) where it's needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining module declarations of ArtemisTranslatePipe
rg "ArtemisTranslatePipe.*declarations|declarations.*ArtemisTranslatePipe" -g "*.ts"

# Search for new standalone imports
rg "import.*ArtemisTranslatePipe" -g "*.ts"

Length of output: 100172

src/main/webapp/app/shared/pipes/html-for-markdown.pipe.ts (3)

1-9: LGTM! Clean migration to standalone pipe

The changes follow Angular's style guide and best practices for standalone components. The import organization and type imports are well structured.


11-11: LGTM! Clean migration to inject() pattern

The migration from constructor injection to the inject() function is well implemented. The readonly modifier adds extra safety by preventing accidental reassignment.


8-8: Verify standalone pipe integration

Since this pipe is now standalone, we should verify that all its imports have been updated accordingly.

✅ Verification successful

Let me verify the module integration further by checking the content of the markdown.module.ts file.


Standalone pipe integration is correctly implemented

The pipe's integration is properly handled:

  • It's correctly imported and used in the imports array of ArtemisMarkdownModule (not in declarations)
  • No other module declarations were found
  • The exports array correctly includes the standalone pipe
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential issues with the standalone migration

# Check for any remaining declarations of this pipe in NgModule
echo "Checking for remaining module declarations..."
rg "declarations.*HtmlForMarkdownPipe" src/main/webapp

# Check for imports to ensure they're using standalone import
echo "Checking import patterns..."
rg "import.*HtmlForMarkdownPipe" src/main/webapp

Length of output: 509


Script:

#!/bin/bash
# Check the full content of markdown.module.ts to verify the module setup
echo "Checking markdown.module.ts content..."
cat src/main/webapp/app/shared/markdown.module.ts

Length of output: 622

src/main/webapp/app/shared/pipes/html-for-posting-markdown.pipe.ts (2)

1-8: LGTM! Clean implementation of standalone pipe

The migration to a standalone pipe and the use of the new inject import aligns well with Angular's latest best practices and the PR objectives.


Line range hint 12-27: Verify security implications of HTML sanitization

The implementation looks solid with proper typing and documentation. Since this pipe handles HTML sanitization, let's verify its usage across the codebase to ensure secure implementation.

✅ Verification successful

Let me analyze the security implications based on the results. I can see the complete flow of HTML sanitization:

  1. The pipe delegates to markdownService.safeHtmlForPostingMarkdown
  2. The service uses htmlForMarkdown utility with DOMPurify sanitization
  3. The only place defining custom attributes is posting-content-part.components.ts which only allows 'href' attribute
  4. The sanitization is properly enforced through DOMPurify and Angular's SafeHtml type

Let me verify one more aspect to ensure there are no bypasses of this sanitization:


HTML sanitization implementation is secure

The security analysis reveals a robust sanitization chain:

  • All markdown-to-HTML conversions go through DOMPurify sanitization before being marked as SafeHtml
  • Direct bypassSecurityTrustHtml usage is properly gated behind sanitization
  • The only custom attribute allowlist is in posting-content-part.components.ts which safely allows only 'href'
  • The pipe correctly delegates to the service which enforces consistent sanitization through DOMPurify
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for potentially unsafe usages of the pipe where sanitization might be bypassed
rg -A 3 "htmlForPostingMarkdown.*allowedHtmlTags|allowedHtmlAttributes" --type ts

# Check if there are any direct calls to markdownService.safeHtmlForPostingMarkdown
# that might bypass the pipe's sanitization
ast-grep --pattern 'markdownService.safeHtmlForPostingMarkdown($$$)'

Length of output: 6567


Script:

#!/bin/bash
# Check for any direct usage of bypassSecurityTrustHtml that might bypass the sanitization
rg -A 3 "bypassSecurityTrustHtml" --type ts

# Check for any DOMPurify usage to ensure consistent configuration
rg -A 3 "DOMPurify.sanitize" --type ts

Length of output: 3880

src/main/webapp/app/shared/shared-common.module.ts (2)

18-18: Verify standalone component migration

The migration of ArtemisTranslatePipe to imports indicates it's now a standalone component. Let's verify the implementation is complete.


Line range hint 18-45: Review consistency of standalone migrations

Since ArtemisTranslatePipe has been migrated to standalone, consider evaluating other components in this module for similar migration opportunities. This would align with the PR's objective of improving the application's architecture.

src/main/webapp/app/shared/shared.module.ts (1)

32-32: LGTM! Correct migration to standalone component.

The LoadingIndicatorContainerComponent has been properly moved from declarations to imports, which is the correct approach for standalone components while maintaining its availability through exports.

src/test/javascript/spec/pipe/reacting-users-on-posting.pipe.spec.ts (2)

7-7: LGTM! Good use of NgMocks

The addition of MockPipe from ng-mocks aligns with our testing guidelines and provides better test isolation.


Line range hint 15-24: LGTM! Well-structured async test setup

The test setup follows best practices:

  • Proper async/await usage
  • Correct use of MockPipe
  • Appropriate dependency injection
src/main/webapp/app/shared/metis/metis.module.ts (1)

67-67: LGTM! Change aligns with standalone component migration.

The addition of HtmlForPostingMarkdownPipe to the imports array correctly reflects its new standalone status, improving modularity as intended in the PR objectives.

src/test/javascript/spec/component/shared/metis/posting-content/posting-content-part.component.spec.ts (2)

Line range hint 66-249: Test implementation looks good!

The test suite is well-structured with:

  • Comprehensive coverage of different scenarios
  • Good use of parameterized tests
  • Proper test isolation
  • Clear test descriptions

35-35: Verify the necessity of full ArtemisTestModule import

According to coding guidelines, we should avoid full module imports. Consider importing only the necessary components and services from ArtemisTestModule.

src/test/javascript/spec/component/assessment-shared/assessment-header.component.spec.ts (1)

10-10: LGTM! Import changes align with testing guidelines.

The addition of MockPipe from ng-mocks follows the coding guidelines for test files and supports the migration to standalone components.

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 27, 2024
HawKhiem
HawKhiem previously approved these changes Nov 27, 2024
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 TS5. Works as described

Screenshot 2024-11-27 195214
Screenshot 2024-11-27 195228

Copy link
Contributor

@SimonEntholzer SimonEntholzer left a comment

Choose a reason for hiding this comment

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

Nice changes, I added one small comment

Comment on lines 15 to 16
// We cannot inject() ChangeDetectorRef here
constructor(translateService: TranslateService, changeDetectorRef: ChangeDetectorRef) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You could improve the comment here, by explaining why we cannot do that here (or maybe even find a work around to make it work?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the feedback! 😄 I tried to extend the comment in this commit. Unfortunately, I already tried some ways to get around it, but I could not find a good solution. 😅 But I am open for suggestions, if anyone could think of something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore client Pull requests that update TypeScript code. (Added Automatically!) ready for review tests
Projects
Status: Ready For Review
Development

Successfully merging this pull request may close these issues.

3 participants