-
Notifications
You must be signed in to change notification settings - Fork 350
Quiz exercises: Migrate practice and preview quiz submissions to data transfer objects
#11654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Quiz exercises: Migrate practice and preview quiz submissions to data transfer objects
#11654
Conversation
End-to-End (E2E) Test Results Summary
|
||||||||||||||||||||||||||||||||||||
End-to-End (E2E) Test Results Summary |
End-to-End (E2E) Test Results Summary |
End-to-End (E2E) Test Results Summary
|
|||||||||||||||||||||||||||||||||
There was a problem hiding this 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.
src/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.java
Show resolved
Hide resolved
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
Show resolved
Hide resolved
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
Outdated
Show resolved
Hide resolved
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.ts
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
Outdated
Show resolved
Hide resolved
End-to-End (E2E) Test Results Summary
|
||||||||||||||||||||||||
…n-dto-migration # Conflicts: # src/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.java
Quiz exercises: Migrate submissions to DTOsQuiz exercises: Migrate practice and preview quiz submissions to data transfer objects
|
Note Other AI code review bot(s) detectedCodeRabbit 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. WalkthroughThe 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ 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)
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.
Example instruction:
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. Comment |
There was a problem hiding this 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: AlignquestionIdnullability with server-side validation contractAll three submitted-answer DTO interfaces (
MultipleChoiceSubmittedAnswerFromStudentDTO,DragAndDropSubmittedAnswerFromStudentDTO,ShortAnswerSubmittedAnswerFromStudentDTO) currently declare:questionId?: number;Whereas, per the Java DTOs used on the server, the corresponding
questionIdis annotated as non-null and is required for validation. KeepingquestionIdoptional 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/idwiring early.Consider making
questionIdrequired 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
quizQuestionoridis 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 DTOYou reuse
DragAndDropMappingReEvaluateDTOformappingshere. 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
DragAndDropMappingReEvaluateDTOis or becomes richer than just the mapping ids, consider introducing a leanDragAndDropMappingFromStudentDTOwith only the minimal fields needed for student submissions and mappingReEvaluateDTOfrom/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 responseThe request payload correctly uses
createQuizSubmissionFromStudentDTO, but the methods still type the HTTP call andResultResponseTypeasResult, while the backendQuizSubmissionResourcenow returnsResultAfterEvaluationWithSubmissionDTOfor both practice and preview.Please double-check that:
- The generic type of
http.postandResultResponseTypematch the actual JSON shape, andsubmissionService.convertResponsestill 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” testsBoth
testQuizSubmitPreview_badRequest_noQuizandtestQuizSubmitPractice_badRequest_noQuizcurrently assertHttpStatus.FORBIDDENrather thanBAD_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 analysisThe 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?.idand similar expressions can evaluate toundefined, and!only silences the compiler, not the runtime value. That means you can silently produce DTOs withundefinedwhere 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
📒 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.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/result/ResultAfterEvaluationWithSubmissionDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedAnswerFromStudentDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/DragAndDropSubmittedAnswerFromStudentDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.javasrc/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/MultipleChoiceSubmittedAnswerFromStudentDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedTextFromStudentDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/exercise/QuizExerciseWithoutQuestionsDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java
src/main/webapp/**/*.ts
⚙️ CodeRabbit configuration file
Files:
src/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.tssrc/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.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/result/ResultAfterEvaluationWithSubmissionDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/ShortAnswerSubmittedAnswerFromStudentDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.javasrc/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.javasrc/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.javasrc/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.javasrc/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.tssrc/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.javasrc/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.javasrc/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.javasrc/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.javasrc/main/webapp/app/quiz/shared/entities/quiz-submission-from-student-dto.model.tssrc/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.javasrc/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionFromStudentDTO.javasrc/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.javasrc/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.javasrc/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.javasrc/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.javasrc/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.javasrc/main/java/de/tum/cit/aet/artemis/quiz/dto/participation/StudentQuizParticipationWithSolutionsDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.javasrc/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.javasrc/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.javasrc/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.javasrc/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.javasrc/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.tssrc/main/java/de/tum/cit/aet/artemis/quiz/web/QuizSubmissionResource.javasrc/main/webapp/app/quiz/overview/service/quiz-participation.service.tssrc/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.tssrc/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.tssrc/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.javasrc/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.javasrc/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.javasrc/main/java/de/tum/cit/aet/artemis/quiz/service/QuizSubmissionService.javasrc/main/webapp/app/quiz/overview/service/quiz-participation.service.tssrc/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.javasrc/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.javasrc/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.javasrc/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.javasrc/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.javasrc/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.javasrc/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.javasrc/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.javasrc/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.javasrc/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.javasrc/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
quizBatchesDTOsvariable 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 correctThe record fields, validation annotations, and the
of(...)mapping fromMultipleChoiceSubmittedAnswertoquestionIdandselectedOptionsare 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 usageThe DTO cleanly exposes only
textandspotIdwith appropriate validation, and theof(...)factory correctly mirrorsShortAnswerSubmittedText→ 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-structuredThe DTO keeps the payload focused on
questionIdandsubmittedTexts, and theof(...)method correctly maps domain texts to DTOs usingStream.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 soundThe record shape matches the submission use case (
questionId+mappings), and theof(...)method cleanly translates the domain mappings usingDragAndDropMappingReEvaluateDTO::ofwith an unmodifiable list fromStream.toList().src/main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java (1)
27-40: Avoid potential NPE inof(SubmittedAnswer)when input is nullIf
submittedAnsweris ever null, thedefaultbranch will execute andsubmittedAnswer.getClass().getName()will throw aNullPointerExceptioninstead of the intendedIllegalArgumentException. This is also inconsistent withgetQuestionId(...), 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 submissionsThe added
Hibernate.isInitializedguard and fallback toSet.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 correctThe new helpers and
createNewSubmissionFromDTOimplement a solid conversion pipeline:
- Use of
Map<Long, QuizQuestion>plus pattern-matchingswitchcleanly 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 withEntityNotFoundExceptionorBadRequestExceptionwhen inconsistent data is received.hasSubmittedAnswersForAllQuestionsandhasNoDuplicateSubmittedAnswersenforce “exactly one submitted answer per question” at the DTO level before any entities are created.createNewSubmissionFromDTObuilds a non-persistedQuizSubmission, wires allSubmittedAnswerback-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 consistentThe
submitForPracticeendpoint now:
- Accepts
QuizSubmissionFromStudentDTOand converts it viaquizSubmissionService.createNewSubmissionFromDTO.- Reuses/creates a
StudentParticipationwithstartPracticeMode, explicitly sets the exercise to avoid lazy issues, and delegates scoring tosubmitForPractice.- Nulls heavy statistics (
quizQuestionStatistic,quizPointStatistic) and result list on the submission before buildingResultAfterEvaluationWithSubmissionDTO.This is a good alignment with the new DTO-based service. Just ensure the client code that calls this endpoint expects
ResultAfterEvaluationWithSubmissionDTO(not a bareResult) 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 participationFor preview:
- The endpoint now takes
QuizSubmissionFromStudentDTO, converts it, and uses a freshStudentParticipationwith the exercise set, without touching the database.- It marks the submission as submitted/manual, calculates scores, constructs a
Result, evaluates it, and then carefully setssubmission.results = nullandsubmission.participation = fakeParticipationbefore mapping toResultAfterEvaluationWithSubmissionDTO.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 invariantsThe record definition and
of(QuizSubmission)factory are lean and appropriate: they reuseSubmittedAnswerFromStudentDTO.of(...), rely on the existing contract thatgetSubmittedAnswers()is non-null, and expose only the minimal data set as aSet, 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,
QuizSubmissionServicealready guarantees non-nullsubmittedAnswerscollections.src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java (3)
17-18: New imports for DTO-based tests are minimal and appropriateThe added imports for
Set,QuizSubmissionFromStudentDTO, andMultipleChoiceSubmittedAnswerFromStudentDTOare 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 consistentAll affected practice/preview tests now construct a
QuizSubmissionfor convenience, convert it once viaQuizSubmissionFromStudentDTO.of(quizSubmission), and use the DTO in the REST calls. The assertions still validate that the evaluated result’sQuizSubmissionhas 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 pathThe
*_badRequest_missingSubmittedAnswertests for practice and preview correctly:
- Create a quiz in the relevant mode.
- Generate a valid submission, then remove one
SubmittedAnswerbefore converting to DTO.- Expect
BAD_REQUESTand 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 responsesThe 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 whereresult.getSubmission()is aQuizSubmissionwith aStudentParticipation, 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-documentedThe
createSubmittedAnswerFromStudentDTOdispatcher cleanly routes bysubmittedAnswer.typeand throws a meaningful error for unknown types, andcreateQuizSubmissionFromStudentDTOprovides a single, well-documented entry point that normalizes aQuizSubmissioninto the transport DTO. This keeps the mapping logic centralized and matches the server-side DTO structure.Also applies to: 94-98
src/main/java/de/tum/cit/aet/artemis/core/dto/CourseForQuizExerciseDTO.java
Show resolved
Hide resolved
src/main/java/de/tum/cit/aet/artemis/quiz/dto/submission/QuizSubmissionAfterEvaluationDTO.java
Show resolved
Hide resolved
...main/java/de/tum/cit/aet/artemis/quiz/dto/submittedanswer/SubmittedAnswerFromStudentDTO.java
Show resolved
Hide resolved
src/test/java/de/tum/cit/aet/artemis/quiz/QuizSubmissionIntegrationTest.java
Show resolved
Hide resolved
End-to-End (E2E) Test Results Summary
|
||||||||||||||||||
End-to-End (E2E) Test Results Summary
|
||||||||||||||||||||||||
HawKhiem
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.


Checklist
General
Server
Client
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
submitForPracticeandsubmitForPreviewendpoints 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:
Previewfor the Quiz ExerciseTestserver 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
Manual Tests
Test Coverage
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Tests
✏️ Tip: You can customize this high-level summary in your review settings.