-
Notifications
You must be signed in to change notification settings - Fork 301
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
Exam mode
: Allow submission upon extension
#9833
base: develop
Are you sure you want to change the base?
Exam mode
: Allow submission upon extension
#9833
Conversation
Exam mode
: Allow submission upon extension
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 pmd (7.8.0)src/main/java/de/tum/cit/aet/artemis/exam/web/StudentExamResource.javaThe following rules are missing or misspelled in your ruleset file category/vm/bestpractices.xml: BooleanInstantiation, DontImportJavaLang, DuplicateImports, EmptyFinallyBlock, EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, EmptyStatementNotInLoop, EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, EmptyWhileStmt, ExcessiveClassLength, ExcessiveMethodLength, ImportFromSamePackage, MissingBreakInSwitch, SimplifyBooleanAssertion. Please check your ruleset configuration. src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.javaThe following rules are missing or misspelled in your ruleset file category/vm/bestpractices.xml: BooleanInstantiation, DontImportJavaLang, DuplicateImports, EmptyFinallyBlock, EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, EmptyStatementNotInLoop, EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, EmptyWhileStmt, ExcessiveClassLength, ExcessiveMethodLength, ImportFromSamePackage, MissingBreakInSwitch, SimplifyBooleanAssertion. Please check your ruleset configuration. WalkthroughThe pull request introduces changes to the Changes
Sequence DiagramsequenceDiagram
participant StudentExam
participant StudentExamResource
participant ProgrammingExerciseStudentParticipationRepository
participant ProgrammingExerciseParticipationService
StudentExam->>StudentExamResource: updateWorkingTime()
alt Exam was originally ended
StudentExamResource->>ProgrammingExerciseStudentParticipationRepository: Find student participation
ProgrammingExerciseStudentParticipationRepository-->>StudentExamResource: Return participation
StudentExamResource->>ProgrammingExerciseParticipationService: Check and unlock participation
ProgrammingExerciseParticipationService-->>StudentExamResource: Unlock result
end
Possibly related PRs
Suggested Labels
Suggested Reviewers
Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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: 3
🧹 Outside diff range and nitpick comments (2)
src/main/java/de/tum/cit/aet/artemis/exam/web/StudentExamResource.java (2)
Line range hint
149-171
: Constructor Contains Many Parameters Indicating Potential Class Responsibility OverloadThe
StudentExamResource
constructor now has a large number of parameters (over 20 dependencies), which can make the code harder to maintain and understand. This might indicate that the class is handling too many responsibilities.Consider refactoring the class to adhere to the single responsibility principle by extracting related functionalities into separate services or components. This can improve maintainability and readability.
269-281
: Refactor Logic into a Separate Method for Improved ReadabilityThe logic within the
updateWorkingTime
method, specifically from lines 269 to 281, is complex and involves multiple nested operations. Extracting this block into a separate private method would enhance readability and maintainability.Apply this diff to refactor the code:
if (!studentExam.isEnded() && wasEndedOriginally) { + unlockProgrammingExerciseParticipations(studentExam); } ... + private void unlockProgrammingExerciseParticipations(StudentExam studentExam) { + studentExam.getExercises().stream() + .filter(ProgrammingExercise.class::isInstance) + .forEach(exercise -> { + var participation = programmingExerciseStudentParticipationRepository + .findByExerciseIdAndStudentLogin(exercise.getId(), studentExam.getUser().getLogin()); + var submissionPolicy = ((ProgrammingExercise) exercise).getSubmissionPolicy(); + participation.ifPresent(participationObj -> { + long inTimeSubmissions = participationObj.getSubmissions().stream() + .filter(submission -> !submission.isLate()) + .count(); + if (submissionPolicy == null || inTimeSubmissions < submissionPolicy.getSubmissionLimit()) { + programmingExerciseParticipationService.unlockStudentRepositoryAndParticipation(participationObj); + } + }); + }); + }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (2)
src/main/java/de/tum/cit/aet/artemis/exam/web/StudentExamResource.java
(5 hunks)src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java
(7 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/main/java/de/tum/cit/aet/artemis/exam/web/StudentExamResource.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java (1)
Pattern src/test/java/**/*.java
: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true
📓 Learnings (1)
src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java (1)
Learnt from: valentin-boehm
PR: ls1intum/Artemis#7384
File: src/test/java/de/tum/in/www1/artemis/exam/StudentExamIntegrationTest.java:2836-2846
Timestamp: 2024-11-12T12:51:51.201Z
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.
🔇 Additional comments (2)
src/main/java/de/tum/cit/aet/artemis/exam/web/StudentExamResource.java (2)
131-132
: Dependency Injection Via Constructor Is Correct
The addition of ProgrammingExerciseStudentParticipationRepository
as a private final
member and its injection via the constructor adheres to best practices and the project's dependency injection guidelines.
138-139
: Dependency Injection Via Constructor Is Correct
The addition of ProgrammingExerciseParticipationService
as a private final
member and its injection via the constructor is appropriate and aligns with the project's conventions for dependency management.
src/main/java/de/tum/cit/aet/artemis/exam/web/StudentExamResource.java
Outdated
Show resolved
Hide resolved
src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java
Outdated
Show resolved
Hide resolved
src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java
Outdated
Show resolved
Hide resolved
5d3295b
to
edc9261
Compare
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: 2
🧹 Nitpick comments (1)
src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java (1)
863-902
: Enhance test robustness and readabilityThe test method could be improved in several ways:
- Add assertions to verify the participation lock state before the update
- Add error handling for potential null values
- Extract setup code into helper methods
Consider refactoring the test to:
@Test @WithMockUser(username = TEST_PREFIX + "instructor1", roles = "INSTRUCTOR") void testUpdateWorkingTime_ShouldTriggerUnlock() throws Exception { + // Given + // Set up programming exercise with participation ProgrammingExercise programmingExercise = programmingExerciseUtilService.addCourseExamExerciseGroupWithOneProgrammingExercise(); - ProgrammingExerciseTestRepository.save(programmingExercise); + programmingExerciseTestRepository.save(programmingExercise); Course course = programmingExercise.getCourseViaExerciseGroupOrCourseMember(); - CourseTestRepository.save(course); + courseTestRepository.save(course); userUtilService.addUsers(TEST_PREFIX, NUMBER_OF_STUDENTS, 0, 0, NUMBER_OF_INSTRUCTORS); User student = userUtilService.getUserByLogin(TEST_PREFIX + "student1"); + // Create and save participation ProgrammingExerciseStudentParticipation participation = participationUtilService.addStudentParticipationForProgrammingExercise(programmingExercise, student.getLogin()); + assertThat(participation).isNotNull(); + assertThat(participation.isLocked()).isTrue(); programmingExerciseStudentParticipationTestRepository.save(participation); + // Set up exam and student exam Exam exam = programmingExercise.getExam(); exam.setStartDate(ZonedDateTime.now().minusHours(2)); exam.setEndDate(ZonedDateTime.now().minusHours(1)); examRepository.save(exam); StudentExam studentExam = new StudentExam(); studentExam.setUser(student); studentExam.setExercises(List.of(programmingExercise)); studentExam.setExam(exam); studentExam.setTestRun(false); studentExam.setWorkingTime(1); studentExamRepository.save(studentExam); doNothing().when(programmingExerciseParticipationService).unlockStudentRepositoryAndParticipation(any()); + // When int newWorkingTime = 180 * 60; StudentExam updatedExam = request.patchWithResponseBody( "/api/courses/" + course.getId() + "/exams/" + exam.getId() + "/student-exams/" + studentExam.getId() + "/working-time", newWorkingTime, StudentExam.class, HttpStatus.OK); + // Then assertThat(updatedExam).isNotNull(); assertThat(updatedExam.getWorkingTime()).isEqualTo(newWorkingTime); assertThat(participation.isLocked()).isFalse(); + verify(programmingExerciseParticipationService, times(1)).unlockStudentRepositoryAndParticipation(participation); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/main/java/de/tum/cit/aet/artemis/exam/web/StudentExamResource.java
(5 hunks)src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java
(7 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java (1)
Pattern src/test/java/**/*.java
: test_naming: descriptive; test_size: small_specific; fixed_data: true; junit5_features: true; assert_use: assertThat; assert_specificity: true; archunit_use: enforce_package_rules; db_query_count_tests: track_performance; util_service_factory_pattern: true; avoid_db_access: true; mock_strategy: static_mocks; context_restart_minimize: true
src/main/java/de/tum/cit/aet/artemis/exam/web/StudentExamResource.java (1)
Pattern src/main/java/**/*.java
: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports
📓 Learnings (2)
src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java (2)
Learnt from: julian-christl
PR: ls1intum/Artemis#9322
File: src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseStudentParticipationRepository.java:0-0
Timestamp: 2024-11-12T12:51:51.201Z
Learning: In Artemis, an `ExerciseGroup` always has an associated `Exam`, so `exerciseGroup.exam` is never null.
Learnt from: julian-christl
PR: ls1intum/Artemis#9322
File: src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseStudentParticipationRepository.java:170-172
Timestamp: 2024-11-12T12:51:46.554Z
Learning: In Artemis, `exercise.exerciseGroup` may be null, as not all exercises belong to an `ExerciseGroup`.
src/main/java/de/tum/cit/aet/artemis/exam/web/StudentExamResource.java (2)
Learnt from: julian-christl
PR: ls1intum/Artemis#9322
File: src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseStudentParticipationRepository.java:0-0
Timestamp: 2024-11-12T12:51:51.201Z
Learning: In Artemis, an `ExerciseGroup` always has an associated `Exam`, so `exerciseGroup.exam` is never null.
Learnt from: julian-christl
PR: ls1intum/Artemis#9322
File: src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseStudentParticipationRepository.java:170-172
Timestamp: 2024-11-12T12:51:46.554Z
Learning: In Artemis, `exercise.exerciseGroup` may be null, as not all exercises belong to an `ExerciseGroup`.
⏰ Context from checks skipped due to timeout of 90000ms (7)
- GitHub Check: client-style
- GitHub Check: client-tests
- GitHub Check: server-tests
- GitHub Check: server-style
- GitHub Check: Build .war artifact
- GitHub Check: Analyse
- GitHub Check: Build and Push Docker Image
🔇 Additional comments (1)
src/test/java/de/tum/cit/aet/artemis/exam/StudentExamIntegrationTest.java (1)
159-161
: 🛠️ Refactor suggestionFollow naming conventions for repository fields
The repository field names should follow consistent casing conventions. Some fields use camelCase while others use PascalCase.
Apply this diff to fix the naming:
- private ProgrammingExerciseTestRepository ProgrammingExerciseTestRepository; + private ProgrammingExerciseTestRepository programmingExerciseTestRepository; - private CourseTestRepository CourseTestRepository; + private CourseTestRepository courseTestRepository;Also applies to: 162-164, 219-221, 222-224
⛔ Skipped due to learnings
Learnt from: julian-christl PR: ls1intum/Artemis#9322 File: src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseStudentParticipationRepository.java:0-0 Timestamp: 2024-11-12T12:51:51.201Z Learning: In Artemis, an `ExerciseGroup` always has an associated `Exam`, so `exerciseGroup.exam` is never null.
Learnt from: julian-christl PR: ls1intum/Artemis#9322 File: src/main/java/de/tum/cit/aet/artemis/programming/repository/ProgrammingExerciseStudentParticipationRepository.java:170-172 Timestamp: 2024-11-12T12:51:46.554Z Learning: In Artemis, `exercise.exerciseGroup` may be null, as not all exercises belong to an `ExerciseGroup`.
Checklist
General
Server
Changes affecting Programming Exercises
Motivation and Context
When instructors extend the time of a student after the exam has officially ended, the student can again access the exam, but is unable to push code.
Linked issue
Description
When the instructor extends a student's individual working time after the exam officially ends, student having the extended time should be able to submit their code.
Steps for Testing
Prerequisites:
Test 1 - Without submission policy
Test 2 - With submission policy
Testserver States
Note
These badges show the state of the test servers.
Green = Currently available, Red = Currently locked
Click on the badges to get to the test servers.
Review Progress
Performance Review
Code Review
Manual Tests
Exam Mode Test
Performance Tests
Test Coverage
Screenshots
Summary by CodeRabbit
New Features
Tests
Improvements