Skip to content

Conversation

@KonstiAnon
Copy link
Contributor

@KonstiAnon KonstiAnon commented Nov 16, 2025

Checklist

General

  • I tested all changes and their related features with all corresponding user types on a test server.
  • This is a small issue that I tested locally and was confirmed by another developer on a test server.
  • I chose a title conforming to the naming conventions for pull requests.

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 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 guidelines.
  • I documented the TypeScript code using JSDoc style.

Motivation and Context

Currently for submitting preview and practice submissions domain objects are being used. In alignment with the goal of switching to more robust data transfer, this PR migrates the submitForPractice and submitForPreview endpoints to DTOs.

This PR also fixes #11658, by ensuring that for preview submissions, the score gets displayed correctly.

Description

I introduced several new DTOs, for the Client -> Server & Server -> Client communication. These DTOs only contain essential data and make use of validations, to ensure that data received by the server is in the correct format and no important fields are omitted.

Steps for Testing

Prerequisites:

  • 1 Instructor
  • 1 Quiz Exercise
  1. Log in to Artemis
  2. Navigate to Course Administration
  3. Select Preview for the Quiz Exercise
  4. Enter your answers and submit the quiz
  5. Ensure that the correct score is displayed
  6. Navigate back to Course Administration
  7. Open the quiz for practice mode (can be done after the due date has passed)
  8. Enter the practice mode for the quiz
  9. Perform a practice submission
  10. Ensure the correct score is displayed

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

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Test Coverage

Summary by CodeRabbit

  • New Features

    • New submission DTO format and client-side serializer for student quiz answers.
    • Submission endpoints now return combined evaluation + submission details.
  • Bug Fixes

    • Improved null-safety for lazy/uninitialized quiz collections to avoid runtime errors.
    • Validation rejects missing or duplicate submitted answers with clear errors.
  • Refactor

    • Centralized submission creation flow: client DTOs converted into internal submissions for processing.
  • Tests

    • Integration tests updated to exercise the DTO-based submission flow and error cases.

✏️ 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 16, 2025
@github-actions github-actions bot added server Pull requests that update Java code. (Added Automatically!) client Pull requests that update TypeScript code. (Added Automatically!) quiz Pull requests that affect the corresponding module labels Nov 16, 2025
@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report205 ran199 passed3 skipped3 failed1h 16m 29s 696ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/quiz-exercise/QuizExerciseDropLocation.spec.ts
ts.Quiz Exercise Drop Location Spec › DnD Quiz drop locations › Checks drop locations❌ failure2m 3s 583ms
e2e/exam/test-exam/TestExamParticipation.spec.ts
ts.Test exam participation › Early Hand-in › Using exercise overview to navigate within exam❌ failure3m 42s 907ms
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure2m 36s 226ms

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

@github-actions github-actions bot added tests core Pull requests that affect the corresponding module labels Nov 17, 2025
@github-actions
Copy link

End-to-End (E2E) Test Results Summary

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report205 ran199 passed3 skipped3 failed1h 13m 23s 429ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/quiz-exercise/QuizExerciseDropLocation.spec.ts
ts.Quiz Exercise Drop Location Spec › DnD Quiz drop locations › Checks drop locations❌ failure2m 3s 326ms
e2e/exam/test-exam/TestExamParticipation.spec.ts
ts.Test exam participation › Early Hand-in › Using exercise sidebar to navigate within exam❌ failure3m 17s 392ms
ts.Test exam participation › Early Hand-in › Using exercise overview to navigate within exam❌ failure3m 42s 320ms

Copilot finished reviewing on behalf of KonstiAnon November 17, 2025 16:33
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR migrates quiz submission endpoints (submitForPractice and submitForPreview) from using domain objects to DTOs for improved data transfer robustness. The migration includes comprehensive validation to ensure submissions contain answers for all questions without duplicates, and fixes score display for preview submissions.

  • Introduces new DTOs for client-to-server and server-to-client communication with validation
  • Adds validation logic to ensure submissions have answers for all questions and no duplicate answers
  • Updates both Java backend and TypeScript frontend to use the new DTO-based approach

Reviewed Changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
QuizSubmissionResource.java Updated submitForPractice and submitForPreview endpoints to accept DTOs and return structured result DTOs
QuizSubmissionService.java Added conversion methods from DTOs to domain objects with comprehensive validation
QuizSubmissionFromStudentDTO.java New DTO record for quiz submissions from students with validation constraints
SubmittedAnswerFromStudentDTO.java New sealed interface for polymorphic submitted answer DTOs with type discrimination
MultipleChoiceSubmittedAnswerFromStudentDTO.java DTO for multiple choice answers with question ID and selected options
DragAndDropSubmittedAnswerFromStudentDTO.java DTO for drag-and-drop answers with mappings
ShortAnswerSubmittedAnswerFromStudentDTO.java DTO for short answer submissions with submitted texts
ShortAnswerSubmittedTextFromStudentDTO.java DTO for individual short answer text entries
ResultAfterEvaluationWithSubmissionDTO.java New DTO for returning evaluation results with submission data to the client
QuizSubmissionAfterEvaluationDTO.java Updated to handle null results gracefully
quiz-submission-from-student-dto.model.ts TypeScript DTO interfaces and conversion functions for client-side
quiz-participation.service.ts Updated to use DTO conversion instead of domain object serialization
QuizSubmissionIntegrationTest.java Updated tests to use DTOs, removed obsolete test, added validation tests
StudentQuizParticipationWithSolutionsDTO.java Added null-safety check for uninitialized submissions
QuizExerciseWithoutQuestionsDTO.java Added Hibernate initialization check for quiz batches
CourseForQuizExerciseDTO.java Added null-safety check for course parameter

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report205 ran201 passed3 skipped1 failed1h 11m 24s 859ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/quiz-exercise/QuizExerciseDropLocation.spec.ts
ts.Quiz Exercise Drop Location Spec › DnD Quiz drop locations › Checks drop locations❌ failure2m 3s 573ms

coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 17, 2025
…n-dto-migration

# Conflicts:
#	src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
@KonstiAnon KonstiAnon marked this pull request as ready for review November 24, 2025 11:39
@KonstiAnon KonstiAnon requested a review from a team as a code owner November 24, 2025 11:39
@KonstiAnon KonstiAnon requested a review from krusche as a code owner November 24, 2025 11:39
@KonstiAnon KonstiAnon changed the title Quiz exercises: Migrate submissions to DTOs Quiz exercises: Migrate practice and preview quiz submissions to data transfer objects Nov 24, 2025
@helios-aet helios-aet bot temporarily deployed to artemis-test1.artemis.cit.tum.de November 24, 2025 11:44 Inactive
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 24, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

The PR replaces direct domain quiz submissions with DTO-based student submission payloads, adds new DTOs and JSON polymorphism for submitted answers, introduces DTO-to-domain conversion in QuizSubmissionService, adds lazy-init guards, changes REST endpoints to accept/return DTOs, updates frontend DTO usage, and adapts integration tests.

Changes

Cohort / File(s) Summary
Submitted-answer DTOs
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/DragAndDropSubmittedAnswerFromStudentDTO.java, src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/MultipleChoiceSubmittedAnswerFromStudentDTO.java, src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedAnswerFromStudentDTO.java, src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedTextFromStudentDTO.java
Added new record DTOs for drag-and-drop, multiple-choice, and short-answer submitted answers (with validation) and static of() factories to map domain objects.
Submitted-answer abstraction
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java
New sealed interface with JsonTypeInfo/JsonSubTypes for polymorphic (de)serialization, static of(SubmittedAnswer) factory, and getQuestionId helper using pattern matching.
Quiz-submission DTO
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.java
New record representing a student submission payload (set of submitted-answer DTOs) with of() factory to convert from domain QuizSubmission.
Result + submission DTO
src/main/java/de/tum/cit/aet/artemis/quiz/dto/result/ResultAfterEvaluationWithSubmissionDTO.java
New composite DTO combining evaluation result DTO and a submission DTO (including nested QuizSubmissionForResultDTO) with static of() factories.
Submission evaluation DTO changes
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
Guarded lazy-loading: only populate submittedAnswers and results when Hibernate collections are initialized; avoid NPEs for uninitialized associations.
Hibernate guards in other DTOs
src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java, src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java, src/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.java
Added null/initialized checks (Hibernate.isInitialized) to avoid accessing uninitialized lazy collections.
Service: DTO → domain conversion
src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java
New public method createNewSubmissionFromDTO(QuizSubmissionFromStudentDTO, QuizExercise) plus private helpers: validates completeness/uniqueness, converts DTO answers into domain SubmittedAnswer instances, and wires back-references.
REST API: accept/return DTOs
src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
submitForPractice and submitForPreview now accept QuizSubmissionFromStudentDTO and return ResultAfterEvaluationWithSubmissionDTO; resource converts DTO→domain before evaluation and composes response DTO.
Frontend DTO model
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
New TypeScript module defining QuizSubmissionFromStudentDTO, per-answer DTO types, converters, and a createQuizSubmissionFromStudentDTO helper used before POST.
Frontend service update
src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts
submitForPractice/submitForPreview now send DTO produced by createQuizSubmissionFromStudentDTO rather than a domain submission object.
Tests updated
src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
Integration tests changed to build/send QuizSubmissionFromStudentDTO, added cases for missing/duplicate answers, and adapted preview/practice tests to expect DTO-based flows.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant QuizSubmissionResource
    participant QuizSubmissionService
    participant EvaluationService

    Note over Client,EvaluationService: Submit for practice/preview (DTO-based)

    Client->>QuizSubmissionResource: POST QuizSubmissionFromStudentDTO
    activate QuizSubmissionResource

    rect rgb(230,240,255)
      QuizSubmissionResource->>QuizSubmissionService: createNewSubmissionFromDTO(dto, exercise)
      activate QuizSubmissionService
      QuizSubmissionService->>QuizSubmissionService: Validate completeness & uniqueness
      QuizSubmissionService->>QuizSubmissionService: Convert DTO answers → domain SubmittedAnswer(s)
      QuizSubmissionService-->>QuizSubmissionResource: domain QuizSubmission (not persisted)
      deactivate QuizSubmissionService
    end

    rect rgb(220,255,230)
      QuizSubmissionResource->>EvaluationService: evaluate(submission)
      activate EvaluationService
      EvaluationService-->>QuizSubmissionResource: Result
      deactivate EvaluationService
    end

    rect rgb(255,245,210)
      QuizSubmissionResource->>QuizSubmissionResource: Build ResultAfterEvaluationWithSubmissionDTO(result, submission)
      QuizSubmissionResource-->>Client: ResultAfterEvaluationWithSubmissionDTO
    end
    deactivate QuizSubmissionResource
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing careful review:
    • QuizSubmissionService.createNewSubmissionFromDTO: validation logic (completeness, duplicates), conversion correctness, back-reference setup.
    • SubmittedAnswerFromStudentDTO sealed interface: polymorphic JSON annotations and factory dispatch correctness.
    • REST endpoints: correct population of ResultAfterEvaluationWithSubmissionDTO to ensure previews without participation work (linked issue #11658).
    • Hibernate.isInitialized guards: consistency and correctness across DTO mappers.
    • Tests: ensure modified integration tests fully cover error/forbidden scenarios and DTO mapping.

Suggested reviewers

  • krusche
  • SamuelRoettgermann
  • MoritzSpengler
  • marlonnienaber
  • LeZhen1105

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.58% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: migrating quiz submission endpoints from domain objects to DTOs for practice and preview modes.
Linked Issues check ✅ Passed The PR addresses issue #11658 by introducing ResultAfterEvaluationWithSubmissionDTO which includes submission and participation data needed for preview results display.
Out of Scope Changes check ✅ Passed All changes are directly related to the DTO migration objective. No unrelated modifications to unrelated systems or refactors outside the scope were introduced.
✨ 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 chore/quiz-exercises/submission-dto-migration

📜 Recent 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 14ee5aa and bb5fd52.

📒 Files selected for processing (2)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java
⏰ 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). (11)
  • GitHub Check: Codacy Static Code Analysis
  • 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: client-tests
  • GitHub Check: client-tests-selected
  • GitHub Check: client-style
  • GitHub Check: server-style
  • GitHub Check: server-tests
  • GitHub Check: bean-instantiation-check
  • GitHub Check: Analyse

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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

♻️ Duplicate comments (1)
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts (1)

13-34: Align questionId nullability with server-side validation contract

All three submitted-answer DTO interfaces (MultipleChoiceSubmittedAnswerFromStudentDTO, DragAndDropSubmittedAnswerFromStudentDTO, ShortAnswerSubmittedAnswerFromStudentDTO) currently declare:

questionId?: number;

Whereas, per the Java DTOs used on the server, the corresponding questionId is annotated as non-null and is required for validation. Keeping questionId optional on the client:

  • Allows constructing DTOs that will only fail at runtime with a 400 due to bean validation.
  • Prevents TypeScript from helping catch missing quizQuestion/id wiring early.

Consider making questionId required in the TS interfaces and tightening the mapper accordingly, e.g. by either:

  • Using a non-null assertion with an explicit domain invariant comment:
questionId: submittedAnswer.quizQuestion!.id!,

or

  • Guarding and throwing a clear error if the quizQuestion or id is unexpectedly missing.

This keeps client and server contracts in sync and surfaces problems earlier.

🧹 Nitpick comments (5)
src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java (1)

31-35: Excellent guard implementation to prevent lazy loading!

The Hibernate initialization check correctly avoids triggering lazy loading during DTO construction, which aligns with the data-economy objectives of this PR. The logic handles all cases properly (null, uninitialized proxy, initialized collection).

As an optional minor improvement, consider reversing the condition order for slightly better readability:

-        if (Hibernate.isInitialized(quizBatches) && quizBatches != null) {
+        if (quizBatches != null && Hibernate.isInitialized(quizBatches)) {

This makes the intent clearer (check null first, then initialization) and follows a more conventional null-check pattern, though both orders work correctly.

src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/DragAndDropSubmittedAnswerFromStudentDTO.java (1)

14-19: Consider decoupling student submission mappings from re-evaluation DTO

You reuse DragAndDropMappingReEvaluateDTO for mappings here. If that DTO ever grows re-evaluation-specific fields (e.g. correctness flags, invalidation metadata), this type will then mix concerns (student submissions vs. instructor re-evaluation) and may expose more data than necessary for the submission flow.

If DragAndDropMappingReEvaluateDTO is or becomes richer than just the mapping ids, consider introducing a lean DragAndDropMappingFromStudentDTO with only the minimal fields needed for student submissions and mapping ReEvaluateDTO from/to it where needed.

src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts (1)

8-8: Align frontend response typing with new DTO-based backend response

The request payload correctly uses createQuizSubmissionFromStudentDTO, but the methods still type the HTTP call and ResultResponseType as Result, while the backend QuizSubmissionResource now returns ResultAfterEvaluationWithSubmissionDTO for both practice and preview.

Please double-check that:

  • The generic type of http.post and ResultResponseType match the actual JSON shape, and
  • submissionService.convertResponse still behaves correctly with the new wrapper DTO.

If the backend response type has changed structurally, consider introducing a dedicated TS DTO (e.g. ResultAfterEvaluationWithSubmissionDTO) and updating the method signatures accordingly to avoid silent type mismatches.

Also applies to: 19-22, 25-29

src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java (1)

525-537: Method names vs. expected status codes in “no quiz” tests

Both testQuizSubmitPreview_badRequest_noQuiz and testQuizSubmitPractice_badRequest_noQuiz currently assert HttpStatus.FORBIDDEN rather than BAD_REQUEST. This is just a naming mismatch, but it can be confusing when reading/maintaining the tests. Consider renaming the methods (e.g. to ..._forbidden_noQuiz) or adjusting the expected status if the endpoint is actually supposed to return 400.

src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts (1)

49-59: Avoid ?.id! on nested fields; prefer explicit guards to match static analysis

The mappings for drag-and-drop and short-answer answers currently rely on optional chaining combined with non-null assertions:

dragItemId: mapping.dragItem?.id!,
dropLocationId: mapping.dropLocation?.id!,
...
text: submittedText.text!,
spotId: submittedText.spot?.id!,

Static analysis correctly points out that mapping.dragItem?.id and similar expressions can evaluate to undefined, and ! only silences the compiler, not the runtime value. That means you can silently produce DTOs with undefined where the types (and Java side) expect non-null numbers/strings.

To make this safer and clearer, consider a small guard-based refactor, e.g.:

function createDragAndDropSubmittedAnswerFromStudentDTO(submittedAnswer: DragAndDropSubmittedAnswer): DragAndDropSubmittedAnswerFromStudentDTO {
    const mappings =
        submittedAnswer.mappings?.map((mapping) => {
            const dragItem = mapping.dragItem;
            const dropLocation = mapping.dropLocation;
            if (!dragItem?.id || !dropLocation?.id) {
                throw new Error('Found drag-and-drop mapping without dragItem/dropLocation id');
            }
            return {
                dragItemId: dragItem.id,
                dropLocationId: dropLocation.id,
            };
        }) ?? [];

    return {
        type: 'drag-and-drop',
        questionId: submittedAnswer.quizQuestion?.id,
        mappings,
    };
}

function createShortAnswerSubmittedAnswerFromStudentDTO(submittedAnswer: ShortAnswerSubmittedAnswer): ShortAnswerSubmittedAnswerFromStudentDTO {
    const submittedTexts =
        submittedAnswer.submittedTexts?.map((submittedText) => {
            if (!submittedText.text || !submittedText.spot?.id) {
                throw new Error('Found short-answer text without text or spot id');
            }
            return {
                text: submittedText.text,
                spotId: submittedText.spot.id,
            };
        }) ?? [];

    return {
        type: 'short-answer',
        questionId: submittedAnswer.quizQuestion?.id,
        submittedTexts,
    };
}

This both satisfies the static analysis warnings and encodes the domain invariants explicitly.

Also applies to: 61-71

📜 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 14ee5aa.

📒 Files selected for processing (16)
  • src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/result/ResultAfterEvaluationWithSubmissionDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java (2 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/DragAndDropSubmittedAnswerFromStudentDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/MultipleChoiceSubmittedAnswerFromStudentDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedAnswerFromStudentDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedTextFromStudentDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java (3 hunks)
  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java (5 hunks)
  • src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts (2 hunks)
  • src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java (10 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/main/java/**/*.java

⚙️ CodeRabbit configuration file

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

Files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/result/ResultAfterEvaluationWithSubmissionDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedAnswerFromStudentDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/DragAndDropSubmittedAnswerFromStudentDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/MultipleChoiceSubmittedAnswerFromStudentDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedTextFromStudentDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java
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/entities/quiz-submission-from-student-dto.model.ts
  • src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts
src/test/java/**/*.java

⚙️ CodeRabbit configuration file

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

Files:

  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
🧠 Learnings (33)
📓 Common learnings
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11351
File: src/main/java/de/tum/cit/aet/artemis/versioning/dto/QuizExerciseSnapshotDTO.java:52-53
Timestamp: 2025-09-25T11:25:54.261Z
Learning: In the Artemis versioning system, quiz questions processed by QuizExerciseSnapshotDTO should always have valid IDs (non-null getId()) since versioning works with persisted entities, making null filtering unnecessary according to Elfari1028.
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: 11382
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizTrainingService.java:43-54
Timestamp: 2025-09-20T16:47:54.380Z
Learning: In QuizTrainingService.submitForTraining, cross-course mismatch protection is handled through PreAuthorize("hasAccessToCourse(#courseId)") authorization at the REST layer, ensuring users can only submit for courses they have access to, rather than through explicit courseId validation in the service method.
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11419
File: src/main/java/de/tum/cit/aet/artemis/exam/domain/ExamUser.java:16-17
Timestamp: 2025-09-25T20:28:36.905Z
Learning: In the Artemis codebase, ExamUser entity uses ExamSeatDTO as a transient field for performance reasons. SamuelRoettgermann tested domain value objects but they caused 60x slower performance. This architectural exception is approved by maintainers due to significant performance benefits and Artemis naming convention requirements.
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11055
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizQuestionProgressService.java:47-61
Timestamp: 2025-07-11T15:43:56.099Z
Learning: In QuizQuestionProgressService.retrieveProgressFromResultAndSubmission method, input validation is not necessary because getSubmittedAnswers() always returns a non-null set and the method receives non-null objects by contract when called from QuizSubmissionService.
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8597
File: src/main/webapp/app/exercises/programming/manage/repositories-checkout-directories-dto.ts:8-8
Timestamp: 2024-06-10T19:44:09.116Z
Learning: DTOs are typically defined in the `src/main/webapp/app/entities` folder on the client side in the Artemis project.
📚 Learning: 2025-08-08T08:50:28.791Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 11248
File: src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseParticipationService.java:401-402
Timestamp: 2025-08-08T08:50:28.791Z
Learning: In src/main/java/de/tum/cit/aet/artemis/programming/service/ProgrammingExerciseParticipationService.java, method findStudentParticipationWithLatestSubmissionResultAndFeedbacksElseThrow(long), using List.of() for latestSubmission.setResults(...) is acceptable because the results list is not mutated afterward and is only returned to the client; no follow-up code appends to it.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/result/ResultAfterEvaluationWithSubmissionDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedAnswerFromStudentDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java
📚 Learning: 2025-09-25T11:25:54.261Z
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11351
File: src/main/java/de/tum/cit/aet/artemis/versioning/dto/QuizExerciseSnapshotDTO.java:52-53
Timestamp: 2025-09-25T11:25:54.261Z
Learning: In the Artemis versioning system, quiz questions processed by QuizExerciseSnapshotDTO should always have valid IDs (non-null getId()) since versioning works with persisted entities, making null filtering unnecessary according to Elfari1028.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
📚 Learning: 2025-07-11T15:43:56.099Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11055
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizQuestionProgressService.java:47-61
Timestamp: 2025-07-11T15:43:56.099Z
Learning: In QuizQuestionProgressService.retrieveProgressFromResultAndSubmission method, input validation is not necessary because getSubmittedAnswers() always returns a non-null set and the method receives non-null objects by contract when called from QuizSubmissionService.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java
📚 Learning: 2025-09-20T16:12:57.735Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11382
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizQuestionProgressService.java:0-0
Timestamp: 2025-09-20T16:12:57.735Z
Learning: In QuizQuestionProgressService.areQuestionsDue, MoritzSpengler confirmed that defensive null/empty guards are unnecessary because the method is only called from getQuestionsForSession, which already handles null/empty questionIds by adding a sentinel value (-1L) before the call.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java
📚 Learning: 2025-09-25T20:28:36.905Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11419
File: src/main/java/de/tum/cit/aet/artemis/exam/domain/ExamUser.java:16-17
Timestamp: 2025-09-25T20:28:36.905Z
Learning: In the Artemis codebase, ExamUser entity uses ExamSeatDTO as a transient field for performance reasons. SamuelRoettgermann tested domain value objects but they caused 60x slower performance. This architectural exception is approved by maintainers due to significant performance benefits and Artemis naming convention requirements.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
📚 Learning: 2025-06-17T12:31:09.178Z
Learnt from: jfr2102
Repo: ls1intum/Artemis PR: 10983
File: src/main/java/de/tum/cit/aet/artemis/exercise/repository/StudentParticipationRepository.java:110-126
Timestamp: 2025-06-17T12:31:09.178Z
Learning: The query `findByExamIdWithEagerLatestLegalSubmissionsRatedResultAndIgnoreTestRunParticipation` in StudentParticipationRepository fetches all rated results (not just the latest) because the second correction round feature requires access to multiple assessment results per submission for proper correction round management.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
📚 Learning: 2025-02-11T12:05:49.151Z
Learnt from: janthoXO
Repo: ls1intum/Artemis PR: 9406
File: src/main/java/de/tum/cit/aet/artemis/programming/web/ProgrammingExerciseParticipationResource.java:209-209
Timestamp: 2025-02-11T12:05:49.151Z
Learning: In ProgrammingExerciseParticipationResource, exam-related authorization checks and sensitive information filtering for results and feedbacks are handled by resultService.filterSensitiveInformationIfNecessary().

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
📚 Learning: 2025-08-14T21:30:54.314Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11111
File: src/main/java/de/tum/cit/aet/artemis/exam/service/ExamRoomService.java:373-386
Timestamp: 2025-08-14T21:30:54.314Z
Learning: Jackson automatically serializes Java Set collections to JSON arrays, which are then properly handled by TypeScript/JavaScript frontends. There's no need to change Set to List just for frontend compatibility.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.java
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: JohannesStoehr
Repo: ls1intum/Artemis PR: 8679
File: src/main/java/de/tum/in/www1/artemis/web/rest/tutorialgroups/TutorialGroupSessionResource.java:37-37
Timestamp: 2024-06-10T19:44:09.116Z
Learning: The DTOs `CompetencyProgressForLearningPathDTO`, `ProgrammingExerciseResetOptionsDTO`, and `CourseWithIdDTO` do not contain nullable values or `Optional` types, making the `JsonInclude` annotation unnecessary for them.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/result/ResultAfterEvaluationWithSubmissionDTO.java
  • src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
📚 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/entities/quiz-submission-from-student-dto.model.ts
📚 Learning: 2024-07-07T13:57:07.670Z
Learnt from: JohannesStoehr
Repo: ls1intum/Artemis PR: 8976
File: src/main/webapp/app/entities/quiz/quiz-exercise.model.ts:0-0
Timestamp: 2024-07-07T13:57:07.670Z
Learning: When defining the `resetQuizForImport` function in `src/main/webapp/app/entities/quiz/quiz-exercise.model.ts`, ensure to directly refer to the `exercise` parameter instead of using `this`.

Applied to files:

  • src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
📚 Learning: 2025-02-11T15:40:53.440Z
Learnt from: Wallenstein61
Repo: ls1intum/Artemis PR: 9909
File: src/main/webapp/app/sharing/search-result-dto.model.ts:57-65
Timestamp: 2025-02-11T15:40:53.440Z
Learning: The ProjectDTO interface in src/main/webapp/app/sharing/search-result-dto.model.ts uses snake_case property names to maintain compatibility with the external sharing platform's API contract, which is an intentional deviation from Angular's camelCase convention.

Applied to files:

  • src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
  • src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts
📚 Learning: 2025-02-11T15:46:08.133Z
Learnt from: Wallenstein61
Repo: ls1intum/Artemis PR: 9909
File: src/main/webapp/app/sharing/search-result-dto.model.ts:17-42
Timestamp: 2025-02-11T15:46:08.133Z
Learning: The types in `UserProvidedMetadataDTO` interface in `search-result-dto.model.ts` must match the sharing platform's contract exactly to maintain compatibility. Avoid modifying these types even if they don't follow internal TypeScript conventions.

Applied to files:

  • src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.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/entities/quiz-submission-from-student-dto.model.ts
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedTextFromStudentDTO.java
📚 Learning: 2024-07-10T11:39:26.373Z
Learnt from: iyannsch
Repo: ls1intum/Artemis PR: 8965
File: src/main/java/de/tum/in/www1/artemis/domain/ProgrammingExercise.java:97-98
Timestamp: 2024-07-10T11:39:26.373Z
Learning: For the Artemis project, the field `allowOnlineIde` in the `ProgrammingExercise` class should use the primitive type `boolean` to ensure it is non-nullable.

Applied to files:

  • src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: undernagruzez
Repo: ls1intum/Artemis PR: 8498
File: src/main/webapp/app/entities/result.model.ts:62-64
Timestamp: 2024-06-10T19:44:09.116Z
Learning: When checking the type of an arbitrary object in TypeScript, use `unknown` instead of `any` for better type safety.

Applied to files:

  • src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
📚 Learning: 2025-10-22T21:31:54.240Z
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11491
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ExerciseResource.java:376-378
Timestamp: 2025-10-22T21:31:54.240Z
Learning: In Artemis, ExerciseVersionService.createExerciseVersion(...) (src/main/java/de/tum/cit/aet/artemis/exercise/service/ExerciseVersionService.java) eagerly re-fetches the target exercise (via type-specific findForVersioningById) before building the ExerciseSnapshotDTO. Controllers (e.g., ExerciseResource.toggleSecondCorrectionEnabled) do not need to reload the exercise before invoking createExerciseVersion.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java
  • src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: valentin-boehm
Repo: ls1intum/Artemis PR: 7384
File: src/test/java/de/tum/in/www1/artemis/exam/StudentExamIntegrationTest.java:988-993
Timestamp: 2024-06-10T19:44:09.116Z
Learning: The `testSubmitStudentExam_differentUser` method does not require additional checks to verify the state of `studentExam1` after receiving a `HttpStatus.FORBIDDEN` because the control flow in the `StudentExamResource` is straightforward and ensures no state change occurs.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
📚 Learning: 2025-09-20T16:47:54.380Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11382
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizTrainingService.java:43-54
Timestamp: 2025-09-20T16:47:54.380Z
Learning: In QuizTrainingService.submitForTraining, cross-course mismatch protection is handled through PreAuthorize("hasAccessToCourse(#courseId)") authorization at the REST layer, ensuring users can only submit for courses they have access to, rather than through explicit courseId validation in the service method.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
📚 Learning: 2025-08-26T13:23:05.331Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 11318
File: src/main/java/de/tum/cit/aet/artemis/exercise/web/ParticipationResource.java:549-552
Timestamp: 2025-08-26T13:23:05.331Z
Learning: The method findGradeScoresForAllExercisesForCourseAndStudent in StudentParticipationRepository handles both individual and team exercises by combining results from separate queries for individual grades, individual quiz grades, and team grades.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
📚 Learning: 2025-09-05T15:11:31.588Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11345
File: src/main/java/de/tum/cit/aet/artemis/quiz/domain/QuizTrainingLeaderboard.java:10-11
Timestamp: 2025-09-05T15:11:31.588Z
Learning: In the QuizTrainingLeaderboard domain class, validation is handled by the service class logic rather than using bean validation annotations at the entity level.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
📚 Learning: 2025-09-20T16:47:54.380Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11382
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizTrainingService.java:43-54
Timestamp: 2025-09-20T16:47:54.380Z
Learning: In QuizTrainingService.submitForTraining, cross-course validation is handled by the REST layer through authCheckService.checkHasAtLeastRoleInCourseElseThrow() which validates user access to the course before the service method is called, eliminating the need for additional courseId validation in the service layer.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: valentin-boehm
Repo: ls1intum/Artemis PR: 7384
File: src/test/java/de/tum/in/www1/artemis/exam/StudentExamIntegrationTest.java:975-980
Timestamp: 2024-06-10T19:44:09.116Z
Learning: The `testSubmitStudentExam_notInTime` method does not require additional checks to verify the state of `studentExam1` after receiving a `HttpStatus.FORBIDDEN` because the control flow in the `StudentExamResource` is straightforward and ensures no state change occurs.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
📚 Learning: 2024-10-20T18:37:45.365Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 9303
File: src/main/java/de/tum/in/www1/artemis/service/exam/StudentExamService.java:296-300
Timestamp: 2024-10-20T18:37:45.365Z
Learning: When reviewing code changes in `StudentExamService.saveSubmission`, if the PR aims to improve readability without changing logic, avoid suggesting changes that alter logic, such as adding exceptions in the default case of switch statements.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
  • src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts
📚 Learning: 2024-10-15T11:33:17.915Z
Learnt from: alexjoham
Repo: ls1intum/Artemis PR: 9455
File: src/test/java/de/tum/cit/aet/artemis/iris/IrisTextExerciseChatMessageIntegrationTest.java:401-401
Timestamp: 2024-10-15T11:33:17.915Z
Learning: In the Artemis project, when new fields are added to classes like `PyrisChatStatusUpdateDTO`, corresponding tests may be implemented in separate integration test classes such as `IrisChatTokenTrackingIntegrationTest`.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
📚 Learning: 2024-11-26T20:43:17.588Z
Learnt from: magaupp
Repo: ls1intum/Artemis PR: 9751
File: src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseFactory.java:143-148
Timestamp: 2024-11-26T20:43:17.588Z
Learning: In `src/test/java/de/tum/cit/aet/artemis/programming/util/ProgrammingExerciseFactory.java`, the test package name assigned in `populateUnreleasedProgrammingExercise` does not need to adhere to naming conventions.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
📚 Learning: 2024-10-08T15:35:48.767Z
Learnt from: jakubriegel
Repo: ls1intum/Artemis PR: 8050
File: src/test/java/de/tum/in/www1/artemis/plagiarism/PlagiarismUtilService.java:125-136
Timestamp: 2024-10-08T15:35:48.767Z
Learning: The `createTeamTextExerciseAndSimilarSubmissions` method in `PlagiarismUtilService.java` uses fixed inputs as it is designed to be a test helper method for simplifying the setup of team exercises and submissions in tests.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
  • src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java
📚 Learning: 2024-10-08T15:35:42.972Z
Learnt from: valentin-boehm
Repo: ls1intum/Artemis PR: 7384
File: src/test/java/de/tum/in/www1/artemis/exam/StudentExamIntegrationTest.java:2804-2810
Timestamp: 2024-10-08T15:35:42.972Z
Learning: The `postWithoutLocation` method used in the `testAbandonStudentExam` test case already checks the response status, ensuring that the abandonment of the exam is accepted.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: valentin-boehm
Repo: ls1intum/Artemis PR: 7384
File: src/test/java/de/tum/in/www1/artemis/exam/StudentExamIntegrationTest.java:2836-2846
Timestamp: 2024-06-10T19:44:09.116Z
Learning: The `testAbandonStudentExamNotInTime` method does not require additional checks to verify the state of `studentExam1` after receiving a `HttpStatus.FORBIDDEN` because the control flow in the `StudentExamResource` is straightforward and ensures no state change occurs.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
📚 Learning: 2025-02-11T15:46:35.616Z
Learnt from: Wallenstein61
Repo: ls1intum/Artemis PR: 9909
File: src/main/webapp/app/sharing/search-result-dto.model.ts:50-55
Timestamp: 2025-02-11T15:46:35.616Z
Learning: The `IExerciseType` enum in `src/main/webapp/app/sharing/search-result-dto.model.ts` must maintain its current naming (with 'I' prefix) and lowercase string values to ensure compatibility with the external sharing platform connector interface. This is an intentional exception to our TypeScript naming conventions.

Applied to files:

  • src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts
📚 Learning: 2025-07-15T20:58:06.751Z
Learnt from: KonstiAnon
Repo: ls1intum/Artemis PR: 11163
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizExerciseService.java:677-690
Timestamp: 2025-07-15T20:58:06.751Z
Learning: In QuizExerciseService.copyFieldsForUpdate(), shallow copying using BeanUtils.copyProperties is intentional and sufficient because the update logic overwrites references without modifying the instances in-place, making deep copying unnecessary.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
📚 Learning: 2025-09-20T16:43:32.823Z
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11382
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizQuestionProgressService.java:130-137
Timestamp: 2025-09-20T16:43:32.823Z
Learning: The findAllDueQuestions method exists in QuizQuestionRepository and accepts Set<Long> ids, Long courseId, and Pageable parameters, returning Page<QuizQuestion>. The method has a Query annotation that filters by courseId, isOpenForPractice = TRUE, and excludes questions with IDs in the provided set using NOT IN.

Applied to files:

  • src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java
🧬 Code graph analysis (6)
src/main/java/de/tum/cit/aet/artemis/quiz/dto/result/ResultAfterEvaluationWithSubmissionDTO.java (1)
src/main/webapp/app/exercise/shared/entities/result/result.model.ts (1)
  • Result (10-50)
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/DragAndDropSubmittedAnswerFromStudentDTO.java (2)
src/main/webapp/app/quiz/manage/re-evaluate/services/quiz-re-evaluate.service.ts (1)
  • reevaluate (14-22)
src/test/playwright/support/pageobjects/exercises/quiz/QuizExerciseParticipationPage.ts (1)
  • getQuizQuestion (44-46)
src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java (2)
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts (1)
  • QuizSubmissionFromStudentDTO (7-9)
src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts (2)
  • submitForPractice (18-23)
  • submitForPreview (25-30)
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.java (1)
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts (1)
  • QuizSubmissionFromStudentDTO (7-9)
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedTextFromStudentDTO.java (1)
src/main/webapp/app/quiz/shared/service/short-answer-question-util.service.ts (1)
  • getSpot (336-338)
src/main/webapp/app/quiz/overview/service/quiz-participation.service.ts (1)
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts (1)
  • createQuizSubmissionFromStudentDTO (94-98)
🪛 GitHub Actions: Test
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java

[error] 21-21: Checkstyle: Missing a Javadoc comment. [MissingJavadocMethod]

src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java

[error] 18-18: Checkstyle: Missing a Javadoc comment. [MissingJavadocMethod]


[error] 27-27: Checkstyle: Missing a Javadoc comment. [MissingJavadocMethod]

🪛 GitHub Check: Codacy Static Code Analysis
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts

[warning] 55-55: src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts#L55
Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong.


[warning] 56-56: src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts#L56
Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong.


[warning] 68-68: src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts#L68
Optional chain expressions can return undefined by design - using a non-null assertion is unsafe and wrong.

⏰ 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). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (17)
src/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.java (2)

7-7: LGTM! Appropriate imports for the initialization guard.

The imports are necessary for the Hibernate initialization check and entity-to-DTO mapping, and comply with the no-star-imports guideline.

Also applies to: 13-13


40-40: LGTM! Correct usage of the computed DTO collection.

The computed quizBatchesDTOs variable is properly used in the record constructor, ensuring the DTO contains only initialized data or an empty set when the collection is not loaded.

src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/MultipleChoiceSubmittedAnswerFromStudentDTO.java (1)

11-17: DTO shape and factory mapping look correct

The record fields, validation annotations, and the of(...) mapping from MultipleChoiceSubmittedAnswer to questionId and selectedOptions are minimal and consistent with the new submission DTO flow.

src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedTextFromStudentDTO.java (1)

10-15: Short-answer text DTO and mapping are consistent with domain usage

The DTO cleanly exposes only text and spotId with appropriate validation, and the of(...) factory correctly mirrors ShortAnswerSubmittedText → DTO without additional concerns.

src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedAnswerFromStudentDTO.java (1)

12-19: Short-answer submitted-answer DTO is well-structured

The DTO keeps the payload focused on questionId and submittedTexts, and the of(...) method correctly maps domain texts to DTOs using Stream.toList() for an unmodifiable collection.

src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/DragAndDropSubmittedAnswerFromStudentDTO.java (1)

13-20: Drag-and-drop submission DTO and mapping logic are sound

The record shape matches the submission use case (questionId + mappings), and the of(...) method cleanly translates the domain mappings using DragAndDropMappingReEvaluateDTO::of with an unmodifiable list from Stream.toList().

src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java (1)

27-40: Avoid potential NPE in of(SubmittedAnswer) when input is null

If submittedAnswer is ever null, the default branch will execute and submittedAnswer.getClass().getName() will throw a NullPointerException instead of the intended IllegalArgumentException. This is also inconsistent with getQuestionId(...), which explicitly guards against null.

Consider explicitly handling null in the switch, similar to getQuestionId(...):

     static SubmittedAnswerFromStudentDTO of(SubmittedAnswer submittedAnswer) {
         switch (submittedAnswer) {
             case MultipleChoiceSubmittedAnswer mcAnswer -> {
                 return MultipleChoiceSubmittedAnswerFromStudentDTO.of(mcAnswer);
             }
             case DragAndDropSubmittedAnswer dndAnswer -> {
                 return DragAndDropSubmittedAnswerFromStudentDTO.of(dndAnswer);
             }
             case ShortAnswerSubmittedAnswer saAnswer -> {
                 return ShortAnswerSubmittedAnswerFromStudentDTO.of(saAnswer);
             }
+            case null -> throw new IllegalArgumentException("Submitted answer cannot be null");
             default -> throw new IllegalArgumentException("Unknown submitted answer type: " + submittedAnswer.getClass().getName());
         }
     }
⛔ Skipped due to learnings
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 9303
File: src/main/java/de/tum/in/www1/artemis/service/exam/StudentExamService.java:296-300
Timestamp: 2024-10-20T18:37:45.365Z
Learning: When reviewing code changes in `StudentExamService.saveSubmission`, if the PR aims to improve readability without changing logic, avoid suggesting changes that alter logic, such as adding exceptions in the default case of switch statements.
Learnt from: valentin-boehm
Repo: ls1intum/Artemis PR: 7384
File: src/main/java/de/tum/in/www1/artemis/service/exam/StudentExamService.java:295-303
Timestamp: 2024-10-14T10:30:20.109Z
Learning: The `abandonStudentExam` method in `StudentExamService` should not include a null check for the `studentExam` parameter as per the project's coding practices. It is expected that the `studentExam` will never be null at this point in the code, and a `NullPointerException` would indicate a significant issue elsewhere in the codebase.
Learnt from: valentin-boehm
Repo: ls1intum/Artemis PR: 7384
File: src/main/java/de/tum/in/www1/artemis/service/exam/StudentExamService.java:295-303
Timestamp: 2024-06-10T19:44:09.116Z
Learning: The `abandonStudentExam` method in `StudentExamService` should not include a null check for the `studentExam` parameter as per the project's coding practices. It is expected that the `studentExam` will never be null at this point in the code, and a `NullPointerException` would indicate a significant issue elsewhere in the codebase.
Learnt from: MoritzSpengler
Repo: ls1intum/Artemis PR: 11055
File: src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizQuestionProgressService.java:47-61
Timestamp: 2025-07-11T15:43:56.099Z
Learning: In QuizQuestionProgressService.retrieveProgressFromResultAndSubmission method, input validation is not necessary because getSubmittedAnswers() always returns a non-null set and the method receives non-null objects by contract when called from QuizSubmissionService.
Learnt from: Elfari1028
Repo: ls1intum/Artemis PR: 11351
File: src/main/java/de/tum/cit/aet/artemis/versioning/dto/QuizExerciseSnapshotDTO.java:52-53
Timestamp: 2025-09-25T11:25:54.261Z
Learning: In the Artemis versioning system, quiz questions processed by QuizExerciseSnapshotDTO should always have valid IDs (non-null getId()) since versioning works with persisted entities, making null filtering unnecessary according to Elfari1028.
src/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.java (1)

6-7: Robust handling of potentially uninitialized submissions

The added Hibernate.isInitialized guard and fallback to Set.of() before streaming submissions correctly protects against null or lazily-uninitialized collections, while keeping the filtering semantics intact.

Looks good as-is.

Also applies to: 31-40

src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java (1)

11-15: DTO→domain conversion and validation logic for quiz submissions looks correct

The new helpers and createNewSubmissionFromDTO implement a solid conversion pipeline:

  • Use of Map<Long, QuizQuestion> plus pattern-matching switch cleanly dispatches to the appropriate conversion method per DTO subtype.
  • Each converter (createMultipleChoiceSubmittedAnswerFromDTO, createShortAnswerSubmittedAnswerFromDTO, createDragAndDropSubmittedAnswerFromDTO) validates:
    • Presence of the referenced question,
    • Correct question subtype,
    • Existence of referenced inner elements (answer options, spots, drag items, drop locations),
      and fails fast with EntityNotFoundException or BadRequestException when inconsistent data is received.
  • hasSubmittedAnswersForAllQuestions and hasNoDuplicateSubmittedAnswers enforce “exactly one submitted answer per question” at the DTO level before any entities are created.
  • createNewSubmissionFromDTO builds a non-persisted QuizSubmission, wires all SubmittedAnswer back-references, and leaves persistence and additional flags to the existing submit/preview/practice flows.

I don’t see correctness issues here; the design aligns well with the DTO migration goals.

Also applies to: 39-47, 50-56, 58-65, 422-593

src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java (2)

45-47: Practice submission endpoint: DTO usage and response construction look consistent

The submitForPractice endpoint now:

  • Accepts QuizSubmissionFromStudentDTO and converts it via quizSubmissionService.createNewSubmissionFromDTO.
  • Reuses/creates a StudentParticipation with startPracticeMode, explicitly sets the exercise to avoid lazy issues, and delegates scoring to submitForPractice.
  • Nulls heavy statistics (quizQuestionStatistic, quizPointStatistic) and result list on the submission before building ResultAfterEvaluationWithSubmissionDTO.

This is a good alignment with the new DTO-based service. Just ensure the client code that calls this endpoint expects ResultAfterEvaluationWithSubmissionDTO (not a bare Result) and correctly reads the nested submission/participation/exercise fields when displaying scores.

Also applies to: 130-175


186-211: Preview submission endpoint correctly avoids persistence and fixes missing participation

For preview:

  • The endpoint now takes QuizSubmissionFromStudentDTO, converts it, and uses a fresh StudentParticipation with the exercise set, without touching the database.
  • It marks the submission as submitted/manual, calculates scores, constructs a Result, evaluates it, and then carefully sets submission.results = null and submission.participation = fakeParticipation before mapping to ResultAfterEvaluationWithSubmissionDTO.

This should address the original bug where preview results lacked a participation/exercise chain, enabling the frontend to resolve the quiz exercise for score display, while still avoiding any persistent side effects.

Looks good.

src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.java (1)

14-20: DTO shape and mapping look correct and align with existing invariants

The record definition and of(QuizSubmission) factory are lean and appropriate: they reuse SubmittedAnswerFromStudentDTO.of(...), rely on the existing contract that getSubmittedAnswers() is non-null, and expose only the minimal data set as a Set, which serializes cleanly to the TS-side array type. No extra null/size validation seems required here, as those checks are handled downstream in the quiz submission service logic.

Based on learnings, QuizSubmissionService already guarantees non-null submittedAnswers collections.

src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java (3)

17-18: New imports for DTO-based tests are minimal and appropriate

The added imports for Set, QuizSubmissionFromStudentDTO, and MultipleChoiceSubmittedAnswerFromStudentDTO are scoped to the new DTO-based tests and keep dependencies focused on the quiz submission domain. No further changes needed here.

Also applies to: 68-69


384-387: Migration of practice/preview tests to use QuizSubmissionFromStudentDTO is consistent

All affected practice/preview tests now construct a QuizSubmission for convenience, convert it once via QuizSubmissionFromStudentDTO.of(quizSubmission), and use the DTO in the REST calls. The assertions still validate that the evaluated result’s QuizSubmission has the expected number of submitted answers, so behavior remains covered while exercising the new DTO pipeline.

Also applies to: 463-468, 479-486, 493-496, 506-510, 520-523, 557-565


596-614: New tests for missing submitted answers cover important validation path

The *_badRequest_missingSubmittedAnswer tests for practice and preview correctly:

  • Create a quiz in the relevant mode.
  • Generate a valid submission, then remove one SubmittedAnswer before converting to DTO.
  • Expect BAD_REQUEST and assert that no websocket message is sent.

This accurately exercises the server-side requirement that every quiz question must have exactly one submitted answer in these modes.

Also applies to: 616-632

src/main/java/de/tum/cit/aet/artemis/quiz/dto/result/ResultAfterEvaluationWithSubmissionDTO.java (1)

12-27: Composite result+submission DTO is well-structured for quiz responses

The two records cleanly flatten the quiz result (ResultAfterEvaluationDTO) together with the evaluated submission and its student participation (QuizSubmissionAfterEvaluationDTO + StudentQuizParticipationWithSolutionsDTO) using @JsonUnwrapped, which keeps the JSON shape straightforward for the client. The static factory methods are concise; they do assume that they are only called for quiz results where result.getSubmission() is a QuizSubmission with a StudentParticipation, which matches the intended usage in the quiz submission resource.

src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts (1)

73-82: Dispatcher and top-level DTO builder are clear and well-documented

The createSubmittedAnswerFromStudentDTO dispatcher cleanly routes by submittedAnswer.type and throws a meaningful error for unknown types, and createQuizSubmissionFromStudentDTO provides a single, well-documented entry point that normalizes a QuizSubmission into the transport DTO. This keeps the mapping logic centralized and matches the server-side DTO structure.

Also applies to: 94-98

@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 20m 34s 901ms
TestResultTime ⏱
No test annotations available

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report215 ran211 passed3 skipped1 failed1h 19m 6s 192ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exam/test-exam/TestExamParticipation.spec.ts
ts.Test exam participation › Early Hand-in › Using exercise overview to navigate within exam❌ failure4m 46s 197ms

@helios-aet helios-aet bot temporarily deployed to artemis-test1.artemis.cit.tum.de November 24, 2025 13:26 Inactive
Copy link
Contributor

@HawKhiem HawKhiem left a comment

Choose a reason for hiding this comment

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

Tested on TS1. Works as expected. Also code lgtm 👍

Preview:

Image

Practice:

Image

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!) core Pull requests that affect the corresponding module quiz Pull requests that affect the corresponding module ready for review server Pull requests that update Java code. (Added Automatically!) tests

Projects

Status: Ready For Review

Development

Successfully merging this pull request may close these issues.

Quiz preview does not display score

3 participants