Skip to content

Conversation

@HawKhiem
Copy link
Contributor

@HawKhiem HawKhiem commented Nov 24, 2025

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 principle of data economy for all client-server REST calls.
  • I strictly followed the client coding guidelines.
  • I strictly followed the AET UI-UX 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 documented the TypeScript code using JSDoc style.
  • I added multiple screenshots/screencasts of my UI changes.

Motivation and Context

Fixes an issue where markdown code blocks (using triple backticks ```) were not rendering correctly in quiz short answer questions. Code blocks were displaying as plain text instead of being properly formatted with syntax highlighting. This issue only affected short answer questions, while multiple choice and drag-and-drop questions rendered code blocks correctly.

Description

This PR fixes the code block rendering issue in quiz short answer questions by refactoring the markdown processing pipeline:

Steps for Testing

Prerequisites:

  • 1 Instructor
  • 1 Quiz Exercise with Short Answer, Multiple Choice, and Drag-and-Drop questions
  1. Log in to Artemis as an instructor
  2. Navigate to Course Management → Exercises → Create Quiz
  3. Create a Short Answer Question and try to add a clock block. Example (you can simply copy and paste this into the markdown editor). But do try to mess around to see if code block works in general:
Enter your long question if needed
```java
System.out.println("Hello");
```
Select a part of the text and click on Add Spot to automatically create an input field and the corresponding mapping
You can define a input field like this: This [-spot 1] an [-spot 2] field.
To define the solution for the input fields you need to create a mapping (multiple mapping also possible):
[-option 1] is
[-option 2] input
[-option 1,2] correctInBothFields
  1. Create a Multiple Choice Question with a code block in the question text. Example (you can simply copy and paste this into the markdown editor). But do try to mess around to see if code block works in general:
```java
System.out.println("Hello");
```
Enter your long question if needed
	[hint] Add a hint here (visible during the quiz via ?-Button)

[correct] Enter a correct answer option here
	[hint] Add a hint here (visible during the quiz via ?-Button)
	[exp] Add an explanation here (only visible in feedback after quiz has ended)
[wrong] Enter a wrong answer option here
  1. Create a Drag-and-Drop Question with a code block in the question text. Example (you can simply copy and paste this into the markdown editor). But do try to mess around to see if code block works in general:
```java
System.out.println("Hello");
```
Enter your long question if needed
	[hint] Add a hint here (visible during the quiz via ?-Button)
  1. Save and start the quiz
  2. Verify as a student:
    • Code blocks render with syntax highlighting in all question types

Testserver States

You can manage test servers using Helios. Check environment statuses in the environment list. To deploy to a test server, go to the CI/CD page, find your PR or branch, and trigger the deployment.

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.

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Test Coverage

Screenshots

Before (Code block not rendering):

After (Fixed):

Summary by CodeRabbit

  • Style

    • Improved alignment and spacing of short-answer displays; elements handle code blocks and preformatted content responsively; inputs vertically aligned for consistent layout.
  • Bug Fixes

    • Markdown in question text is now converted/rendered to HTML consistently (bold, lists, code blocks), improving display in editors, preview, and statistics.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-project-automation github-project-automation bot moved this to Work In Progress in Artemis Development Nov 24, 2025
@github-actions github-actions bot added client Pull requests that update TypeScript code. (Added Automatically!) quiz Pull requests that affect the corresponding module labels Nov 24, 2025
@HawKhiem HawKhiem linked an issue Nov 24, 2025 that may be closed by this pull request
@HawKhiem HawKhiem marked this pull request as ready for review November 24, 2025 19:12
@HawKhiem HawKhiem requested a review from a team as a code owner November 24, 2025 19:12
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 24, 2025

Walkthrough

Refactors short-answer question text processing to produce both plain and HTML tokenizations and updates all call sites to use the new structured return. UI styling for short-answer display was adjusted (inline/block swaps, baseline alignment, code-block responsive rules). Tests and components were updated to consume the new { plain, html } shape.

Changes

Cohort / File(s) Summary
Styling
src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.scss
Adjusted layout: align-items: baseline; changed .short-answer-question-display__element from inline-flex to inline-block; nested child div set to display: inline; added responsive rules for elements containing pre to use full width and block children; replaced input container margin-bottom with vertical-align: middle.
Short-answer text utility (implementation)
src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts
Changed divideQuestionTextIntoTextParts to return { plain: string[][]; html: string[][] } (converts entire question to HTML first, then splits for html tokens while retaining plain tokens for indentation detection). Updated transformTextPartsIntoHTML to accept the new structured object and to apply indentation using plain tokens while using html tokens for output.
Short-answer edit component (calls/usage)
src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.ts
Updated call sites to read .html[...] or .plain from divideQuestionTextIntoTextParts return and to call transformTextPartsIntoHTML with the structured data object.
Short-answer display component (calls/usage)
src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts
Renamed local variable textPartstextPartsData and passed the structured data into transformTextPartsIntoHTML.
Statistics component (calls/usage)
src/main/webapp/app/quiz/manage/statistics/short-answer-question-statistic/short-answer-question-statistic.component.ts
Renamed local variable to textPartsData and passed structured data to transformation function; logic otherwise unchanged.
Unit tests — util
src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.spec.ts
Updated tests to expect divideQuestionTextIntoTextParts to return { plain, html }; adjusted assertions to validate html content (markdown→HTML conversions) and updated transformTextPartsIntoHTML test inputs and expectations to use the structured object.
Unit tests — edit component
src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
Adjusted mocks and expectations: divideQuestionTextIntoTextParts mock returns { plain, html }; assertions relaxed/changed to account for HTML-wrapped tokens and markdown conversion effects.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Component as Component (Edit / Display / Stats)
participant Util as ShortAnswerQuestionUtil
Note over Component,Util #DDDDFF: New flow uses structured text parts object
Component->>Util: divideQuestionTextIntoTextParts(questionText)
Util-->>Component: { plain: plainParts, html: htmlParts }
Component->>Util: transformTextPartsIntoHTML({ plain, html })
Util-->>Component: transformedHtmlParts
Component->>UI: render transformedHtmlParts

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to:
    • short-answer-question-util.service.ts — correctness of HTML conversion order and preservation of markdown (code blocks, lists).
    • Call-site updates in short-answer-question-edit.component.ts, short-answer-question.component.ts, and statistics component — ensure correct selection of .html vs .plain.
    • Unit tests in *.spec.ts — verify mocks and assertions align with HTML output changes.
    • SCSS changes for code block responsiveness and inline/inline-block behavior across breakpoints.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: fixing code blocks not rendering in markdown editor for quiz exercises, which aligns with the primary objective of refactoring the markdown processing pipeline.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/quiz-exercises/code-blocks-markdown-rendering

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts (1)

304-310: The indentation detection will break with HTML-wrapped content.

The concern is valid. When htmlForMarkdown converts markdown, it wraps content in HTML tags like <p>, <b>, etc. For example, plain text " some text" becomes "<p> some text</p>".

The issue: The getIndentation method looks for spaces at the string start using while (text[index] === ' '). When leading spaces are inside HTML tags, this fails. For input "<p> text</p>", it returns '' instead of detecting the 4 spaces.

The same problem affects getFirstWord, which uses text.trim().split(' ') and will incorrectly parse HTML tag content.

At line 378 in addIndentationToTextParts, the code calls getIndentation(originalTextParts[i][0]) expecting plain text, but originalTextParts now contains HTML from the modified divideQuestionTextIntoTextParts. The existing tests only cover plain text inputs, so this regression is not caught.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 466bb2c and aaa60e6.

📒 Files selected for processing (2)
  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.scss (2 hunks)
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/webapp/**/*.ts

⚙️ CodeRabbit configuration file

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

Files:

  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: magaupp
Repo: ls1intum/Artemis PR: 8802
File: src/main/resources/templates/rust/exercise/src/context.rs:1-1
Timestamp: 2024-10-08T15:35:42.972Z
Learning: Code inside the `exercise` directories in the Artemis platform is provided to students and is intended for them to implement. TODO comments in these directories are meant to guide students and should not be addressed in the PR.
Learnt from: magaupp
Repo: ls1intum/Artemis PR: 8802
File: src/main/resources/templates/rust/exercise/src/context.rs:1-1
Timestamp: 2024-08-05T00:11:50.650Z
Learning: Code inside the `exercise` directories in the Artemis platform is provided to students and is intended for them to implement. TODO comments in these directories are meant to guide students and should not be addressed in the PR.
📚 Learning: 2025-08-19T20:07:18.114Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts:76-78
Timestamp: 2025-08-19T20:07:18.114Z
Learning: In ShortAnswerQuestion components (src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts), the text, hint, and explanation properties are required fields for short answer questions and do not need null safety checks when accessing them from shortAnswerQuestion().

Applied to files:

  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.scss
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts
📚 Learning: 2025-08-19T19:56:34.228Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts:40-40
Timestamp: 2025-08-19T19:56:34.228Z
Learning: In the ShortAnswerQuestionComponent (src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts), the fnOnSubmittedTextUpdate input should remain typed as "any" rather than being changed to a more specific function type like "(() => void) | undefined". This is an intentional design decision.

Applied to files:

  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.scss
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts
📚 Learning: 2025-08-19T19:56:07.618Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/multiple-choice-question/visual-question/multiple-choice-visual-question.component.ts:84-86
Timestamp: 2025-08-19T19:56:07.618Z
Learning: In Angular signals migration for MultipleChoiceVisualQuestionComponent, when adding new answer options, it's preferred to create a copy of the answerOptions array rather than directly mutating it, maintaining immutability principles while working with signal-returned objects.

Applied to files:

  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.scss
📚 Learning: 2025-08-21T17:30:20.530Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/drag-and-drop-question/drag-and-drop-question.component.spec.ts:34-34
Timestamp: 2025-08-21T17:30:20.530Z
Learning: FitTextDirective in src/main/webapp/app/quiz/shared/fit-text/fit-text.directive.ts is a standalone directive marked with standalone: true, so it should be imported in TestBed imports array, not declarations array.

Applied to files:

  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.scss
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts
🧬 Code graph analysis (1)
src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts (1)
src/main/webapp/app/shared/util/markdown.conversion.util.ts (1)
  • htmlForMarkdown (44-97)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Analyse
🔇 Additional comments (2)
src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.scss (2)

14-31: Well-designed responsive handling for code blocks.

The CSS changes properly support the new HTML structure from the service layer:

  1. align-items: baseline ensures proper alignment between text and input fields
  2. inline-block with nested inline divs allows text to flow naturally within the flex container
  3. The :has(pre) selector cleverly handles code blocks by giving them full width (flex-basis: 100%, width: 100%) and making nested divs block-level for proper formatting

This approach ensures code blocks render on their own line with proper spacing while keeping regular text inline.

Note: The :has() pseudo-class is well-supported in modern browsers as of 2025, so compatibility should not be a concern.


43-43: Better vertical alignment approach.

Changing from margin-bottom to vertical-align: middle is a more semantic way to align inline-block input fields with surrounding text content, especially given the new align-items: baseline on the parent container.

@github-project-automation github-project-automation bot moved this from Work In Progress to Ready For Review in Artemis Development Nov 24, 2025
@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ✅Skipped ⚠️FailedTime ⏱
End-to-End (E2E) Test Report215 ran212 passed3 skipped0 failed1h 10m 30s 186ms
TestResultTime ⏱
No test annotations available

Copy link
Contributor

@MarcosOlivaKaczmarek MarcosOlivaKaczmarek 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 TS2. Everything worked as far as I can tell.

Image

Copy link
Contributor

@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

🧹 Nitpick comments (3)
src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts (2)

95-108: Hardcoded HTML expectations may be fragile.

The test at lines 104-107 expects specific HTML structure including <p> tags wrapping words like <p>This and question.</p>. This couples the test to markdown-it's specific rendering behavior. Consider using a more flexible assertion similar to what's done in later test cases:

-        const expectedTextParts = [
-            ['<p>This', 'is', 'a', '[-spot 12]', 'regarding', 'this', 'question.</p>'],
-            ['<p>Another', '[-spot 8]', 'is', 'in', 'the', 'line', 'above</p>'],
-        ];
-        expect(component.textParts).toEqual(expectedTextParts);
+        // Verify spot tags are preserved
+        const allSpots = component.textParts.flat().filter((part) => part && part.includes('[-spot'));
+        expect(allSpots).toContain('[-spot 12]');
+        expect(allSpots).toContain('[-spot 8]');
+        // Verify content is preserved
+        const allText = component.textParts.flat().join(' ');
+        expect(allText).toContain('regarding this question');
+        expect(allText).toContain('Another');

This would make the test more resilient to minor markdown rendering changes while still verifying the core functionality.


540-546: Consider flexible assertion for consistency.

Similar to the earlier comment, this test has hardcoded HTML structure expectations. While it currently works, consider using flexible assertions:

-        const splitString = ['<p>This', 'is', 'a', 'text', 'for', 'a', 'test</p>'];
-        expect(component.textParts.pop()).toEqual(splitString);
+        const lastPart = component.textParts.pop()!;
+        const joinedText = lastPart.join(' ');
+        expect(joinedText).toContain('This is a text for a test');

This is a minor suggestion for test maintainability.

src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.spec.ts (1)

210-223: Tests could better verify indentation application.

The tests pass { plain, html } objects but expect the exact htmlParts arrays as output. Since addIndentationToTextParts modifies formattedTextParts in place (adding &nbsp; for indentation), these tests work by coincidence because the test data doesn't have significant indentation differences.

Consider adding a test that verifies indentation is actually applied:

it('should apply indentation from plain text to HTML', () => {
    const plainParts = [['    indented text']];
    const htmlParts = [['indented text']];
    const result = service.transformTextPartsIntoHTML({ plain: plainParts, html: htmlParts });
    expect(result[0][0]).toContain('&nbsp;');
    expect(result[0][0]).toContain('indented text');
});

This would ensure the indentation preservation logic is explicitly tested.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aaa60e6 and b69db1a.

📒 Files selected for processing (6)
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts (9 hunks)
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.ts (3 hunks)
  • src/main/webapp/app/quiz/manage/statistics/short-answer-question-statistic/short-answer-question-statistic.component.ts (1 hunks)
  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts (1 hunks)
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.spec.ts (1 hunks)
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/webapp/**/*.ts

⚙️ CodeRabbit configuration file

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

Files:

  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts
  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.spec.ts
  • src/main/webapp/app/quiz/manage/statistics/short-answer-question-statistic/short-answer-question-statistic.component.ts
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.ts
🧠 Learnings (14)
📓 Common learnings
Learnt from: magaupp
Repo: ls1intum/Artemis PR: 8802
File: src/main/resources/templates/rust/exercise/src/context.rs:1-1
Timestamp: 2024-10-08T15:35:42.972Z
Learning: Code inside the `exercise` directories in the Artemis platform is provided to students and is intended for them to implement. TODO comments in these directories are meant to guide students and should not be addressed in the PR.
Learnt from: magaupp
Repo: ls1intum/Artemis PR: 8802
File: src/main/resources/templates/rust/exercise/src/context.rs:1-1
Timestamp: 2024-08-05T00:11:50.650Z
Learning: Code inside the `exercise` directories in the Artemis platform is provided to students and is intended for them to implement. TODO comments in these directories are meant to guide students and should not be addressed in the PR.
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts:76-78
Timestamp: 2025-08-19T20:07:18.114Z
Learning: In ShortAnswerQuestion components (src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts), the text, hint, and explanation properties are required fields for short answer questions and do not need null safety checks when accessing them from shortAnswerQuestion().
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts:40-40
Timestamp: 2025-08-19T19:56:34.228Z
Learning: In the ShortAnswerQuestionComponent (src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts), the fnOnSubmittedTextUpdate input should remain typed as "any" rather than being changed to a more specific function type like "(() => void) | undefined". This is an intentional design decision.
📚 Learning: 2025-08-19T19:56:34.228Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts:40-40
Timestamp: 2025-08-19T19:56:34.228Z
Learning: In the ShortAnswerQuestionComponent (src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts), the fnOnSubmittedTextUpdate input should remain typed as "any" rather than being changed to a more specific function type like "(() => void) | undefined". This is an intentional design decision.

Applied to files:

  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts
  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.spec.ts
  • src/main/webapp/app/quiz/manage/statistics/short-answer-question-statistic/short-answer-question-statistic.component.ts
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.ts
📚 Learning: 2025-08-19T20:07:18.114Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts:76-78
Timestamp: 2025-08-19T20:07:18.114Z
Learning: In ShortAnswerQuestion components (src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts), the text, hint, and explanation properties are required fields for short answer questions and do not need null safety checks when accessing them from shortAnswerQuestion().

Applied to files:

  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts
  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.spec.ts
  • src/main/webapp/app/quiz/manage/statistics/short-answer-question-statistic/short-answer-question-statistic.component.ts
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.ts
📚 Learning: 2025-08-19T19:56:07.618Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/multiple-choice-question/visual-question/multiple-choice-visual-question.component.ts:84-86
Timestamp: 2025-08-19T19:56:07.618Z
Learning: In Angular signals migration for MultipleChoiceVisualQuestionComponent, when adding new answer options, it's preferred to create a copy of the answerOptions array rather than directly mutating it, maintaining immutability principles while working with signal-returned objects.

Applied to files:

  • src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
  • src/main/webapp/app/quiz/manage/statistics/short-answer-question-statistic/short-answer-question-statistic.component.ts
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.ts
📚 Learning: 2024-10-13T12:03:02.430Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9463
File: src/test/javascript/spec/component/shared/monaco-editor/monaco-editor.service.spec.ts:50-55
Timestamp: 2024-10-13T12:03:02.430Z
Learning: In `src/test/javascript/spec/component/shared/monaco-editor/monaco-editor.service.spec.ts`, when a function is called multiple times in a test, use `toHaveBeenCalledTimes` and `toHaveBeenNthCalledWith` assertions instead of `toHaveBeenCalledExactlyOnceWith`.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.spec.ts
📚 Learning: 2024-10-10T11:42:23.069Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9443
File: src/test/javascript/spec/component/hestia/git-diff-report/git-diff-modal.component.spec.ts:55-60
Timestamp: 2024-10-10T11:42:23.069Z
Learning: In `git-diff-report-modal.component.spec.ts`, using `fakeAsync` and `tick` does not work for handling asynchronous operations in the tests; alternative methods are needed.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
📚 Learning: 2025-08-21T17:30:20.530Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/drag-and-drop-question/drag-and-drop-question.component.spec.ts:34-34
Timestamp: 2025-08-21T17:30:20.530Z
Learning: FitTextDirective in src/main/webapp/app/quiz/shared/fit-text/fit-text.directive.ts is a standalone directive marked with standalone: true, so it should be imported in TestBed imports array, not declarations array.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
  • src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.spec.ts
  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.ts
📚 Learning: 2025-09-01T10:20:40.706Z
Learnt from: Michael-Breu-UIbk
Repo: ls1intum/Artemis PR: 10989
File: src/main/webapp/app/programming/manage/detail/programming-exercise-detail.component.with-sharing.spec.ts:132-149
Timestamp: 2025-09-01T10:20:40.706Z
Learning: In the Artemis codebase, Angular component test files for ProgrammingExerciseDetailComponent follow a pattern where the component is imported but not explicitly declared in TestBed.configureTestingModule(), yet TestBed.createComponent() still works successfully. This pattern is consistently used across test files like programming-exercise-detail.component.spec.ts and programming-exercise-detail.component.with-sharing.spec.ts.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
📚 Learning: 2024-10-20T22:00:52.335Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9505
File: src/test/javascript/spec/integration/code-editor/code-editor-container.integration.spec.ts:179-181
Timestamp: 2024-10-20T22:00:52.335Z
Learning: In `src/test/javascript/spec/integration/code-editor/code-editor-container.integration.spec.ts`, `ResizeObserver` is mocked within the `beforeEach` block.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
📚 Learning: 2025-02-16T16:00:38.131Z
Learnt from: iyannsch
Repo: ls1intum/Artemis PR: 10344
File: src/test/javascript/spec/component/shared/code-button.component.spec.ts:0-0
Timestamp: 2025-02-16T16:00:38.131Z
Learning: In test cases, prefer removing unnecessary type assertions over adding mock properties that aren't relevant to what's being tested. This keeps tests focused and reduces maintenance burden.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
📚 Learning: 2024-10-08T15:35:52.595Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9407
File: src/test/javascript/spec/component/programming-exercise/programming-exercise-custom-aeolus-build-plan.component.spec.ts:172-175
Timestamp: 2024-10-08T15:35:52.595Z
Learning: When testing components that use `MonacoEditorComponent`, it's acceptable not to test `MonacoEditorComponent` functionality within those tests, as dedicated tests already exist for it.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
📚 Learning: 2024-07-09T19:09:49.666Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8858
File: src/test/javascript/spec/component/shared/sidebar/sidebar-accordion.component.spec.ts:88-89
Timestamp: 2024-07-09T19:09:49.666Z
Learning: For the PR ls1intum/Artemis#8858, avoid suggesting to change `expect(component.expandAll).toHaveBeenCalledOnce()` to `expect(component.expandAll).toHaveBeenCalledTimes(1)`.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
📚 Learning: 2024-07-09T19:09:58.572Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8858
File: src/test/javascript/spec/component/shared/sidebar/sidebar-accordion.component.spec.ts:115-115
Timestamp: 2024-07-09T19:09:58.572Z
Learning: For the PR ls1intum/Artemis#8858, avoid suggesting to change `expect(component.setStoredCollapseState).toHaveBeenCalledOnce()` to `expect(component.setStoredCollapseState).toHaveBeenCalledTimes(1)`.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts
📚 Learning: 2025-08-19T19:53:56.451Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11297
File: src/main/webapp/app/quiz/shared/questions/multiple-choice-question/multiple-choice-question.component.ts:26-37
Timestamp: 2025-08-19T19:53:56.451Z
Learning: In the MultipleChoiceQuestionComponent (src/main/webapp/app/quiz/shared/questions/multiple-choice-question/multiple-choice-question.component.ts), the fnOnSelection input should remain typed as "any" rather than being changed to a more specific function type like "(() => void) | undefined". This is an intentional design decision.

Applied to files:

  • src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.ts
🧬 Code graph analysis (1)
src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts (1)
src/main/webapp/app/shared/util/markdown.conversion.util.ts (1)
  • htmlForMarkdown (44-97)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: server-style
  • GitHub Check: client-style
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: Analyse
🔇 Additional comments (10)
src/main/webapp/app/quiz/manage/statistics/short-answer-question-statistic/short-answer-question-statistic.component.ts (1)

60-63: LGTM!

The adaptation to the new divideQuestionTextIntoTextParts API is correct. The structured object is properly passed to transformTextPartsIntoHTML, which returns the HTML-formatted string[][] for assignment to this.textParts.

src/main/webapp/app/quiz/shared/questions/short-answer-question/short-answer-question.component.ts (1)

82-91: LGTM!

The watchCollection method correctly uses the new structured return from divideQuestionTextIntoTextParts and passes it to transformTextPartsIntoHTML. This is consistent with changes in other components. Based on learnings, the non-null assertion on text is acceptable as it's a required field for short answer questions.

src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts (2)

289-320: LGTM! Good fix for the code blocks rendering issue.

The refactored approach correctly separates concerns:

  1. plainTextParts preserves original whitespace for indentation detection
  2. htmlTextParts uses htmlForMarkdown to render markdown features like code blocks with syntax highlighting

This addresses the prior review feedback about indentation logic being broken when HTML was passed for both parameters.


351-361: Clean implementation with clear documentation.

The updated method properly delegates indentation detection to plain text while preserving HTML formatting in the output. The JSDoc comments accurately describe the new behavior.

src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.spec.ts (1)

379-383: LGTM!

The mock correctly returns the new structured object format expected by divideQuestionTextIntoTextParts.

src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.spec.ts (1)

188-208: Good test coverage for the new API structure.

The test properly verifies:

  1. The new return structure with plain and html properties
  2. HTML conversion of markdown (e.g., **bold**<strong>bold</strong>)
  3. Spot tag preservation in the HTML output
  4. Paragraph wrapping behavior from markdown-it

The assertions correctly access textPartsData.html to verify the rendered output.

src/main/webapp/app/quiz/manage/short-answer-question/short-answer-question-edit.component.ts (4)

170-195: LGTM - Correct use of the new API for HTML rendering context.

The change correctly accesses .html[0] from the new structured return type, which is appropriate since this method parses text for visual display purposes.


431-433: LGTM - Correct use of plain text for position-based manipulation.

Using .plain here is appropriate since the subsequent substring operations (lines 432-433) require raw text positions that would be incorrect if HTML entities were present.


437-438: LGTM - Proper integration with refactored utility API.

The pattern of capturing the full data object and passing it to transformTextPartsIntoHTML correctly follows the new API design that separates plain and HTML representations.


605-606: LGTM - Consistent pattern with the other call sites.

The implementation correctly mirrors the pattern used in addSpotAtCursorVisualMode, maintaining consistency across the component. Based on learnings, the non-null assertion on text is acceptable since it's a required field.

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ✅SkippedFailedTime ⏱
End-to-End (E2E) Test Report1 ran1 passed0 skipped0 failed1s 422ms
TestResultTime ⏱
No test annotations available

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!) quiz Pull requests that affect the corresponding module

Projects

Status: Ready For Review

Development

Successfully merging this pull request may close these issues.

Quiz: Unable to create code block

3 participants