Skip to content

Conversation

luis-gasparschroeder
Copy link

@luis-gasparschroeder luis-gasparschroeder commented Sep 22, 2025

Checklist

General

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 added pre-authorization annotations according to the guidelines and checked the course groups for all new REST Calls (security).
  • 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 and design guidelines.
  • Following the theming guidelines, I specified colors only in the theming variable files and checked that the changes look consistent in both the light and the dark theme.
  • I added multiple integration tests (Jest) related to the features (with a high test coverage), while following the test guidelines.
  • I added authorities to all new routes and checked the course groups for displaying navigation elements (links, buttons).
  • I documented the TypeScript code using JSDoc style.
  • I added multiple screenshots/screencasts of my UI changes.
  • I translated all newly inserted strings into English and German.

Changes affecting Programming Exercises

  • High priority: I tested all changes and their related features with all corresponding user types on a test server configured with the integrated lifecycle setup (LocalVC and LocalCI).
  • I tested all changes and their related features with all corresponding user types on a test server configured with LocalVC and Jenkins.

Motivation and Context

Beforehand, instructors had to implement the solution, template, and test repository themselves. This was error-prone and time-intensive, as instructors have many other relevant tasks besides exercise creation. The code generation supports their workflow by suggesting and concrete and tested repository structured, aligned with the programming exercise.

Description

This PR introduces a comprehensive code generation system that automatically creates solution code, student templates, and test suites for programming exercises.

Key Components:

  • 4-Step Generation Pipeline: Implements solution planning → file structure definition → method signatures → core logic implementation
  • Repository Context Awareness: New RepositoryStructureService provides current codebase structure to inform generation decisions, ensuring generated code integrates properly with existing files
  • Multi-Strategy Support:
    • SolutionRepository: Generates complete working solutions
    • TemplateRepository: Creates student starter code with method stubs
    • TestRepository: Produces comprehensive test suites
  • Iterative Improvement: Integrates with CI system to capture build failures and refine generated code across multiple attempts
  • Currently, code generations supports Java, but is easily extensible to other programming language
  • Smart File Management: Only modifies source files (/src/ for solutions/templates, /test/ for tests) while preserving build configurations and project structure

Technical Implementation:

  • Strategy pattern for efficient code reuse for different code repositories
  • Template-based prompt system with conditional repository structure injection
  • Proper dependency injection with Spring qualifiers for strategy selection
  • Robust error handling, including Hibernate lazy loading exceptions
  • New repository structure reading for each generation iteration

Steps for Testing

  • 1 Instructor
  • 1 Programming Exercise
  1. Log in to Artemis
  2. Navigate to Course Administration
  3. Create an exercise
  4. Click the code generation button in the solution repository
  5. Wait for the build to be completed
  6. Click the code generation button in the test repository
  7. Wait for the build to be completed
  8. Click the code generation button in the template repository
  9. Wait for the build to be completed
  10. You have a complete code repository for your programming exercise

Review Progress

Performance Review

The code generation takes between 1 and 5 minutes, depending on the number of re-iterations. The reason is the build latency and multi-stages LLM pipeline.

Using the OpenAI GPT-5 LLM, the code generation costs approximately $ 0.05 (assuming three reiterations and an already written problem statement).

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Performance Tests

Reviewer note: Generation is slow and expected to take a while, you also need to refresh to see when the code generation creates a commit in the meanwhile. Better UX feedback will be part of a follow-up

Follow-Up PRs

  1. File indexing for better context handling. Currently, all files are being loaded into the context of the LLM. For lower latency and cost reducations, we can add a vector database-based context handling in a RAG pipeline.
  2. File updating and deletion. Currently, the code generation reads the existing context and generates new files. For an even more interactive usage, it should be possible to perform update and delete, in addition to the read and create operations.
  3. Starting with a minimal repository state for generation. Default test cases don't make sense -> We'd need to start blank?
  4. Observability and cost tracking
  5. Double invocation guard (currently you can just press "Generate code" again once you refresh, it also does not reject it). The UI should update accordingly.
  6. Chat-like interaction. Currently, the code changes are based on the problem statement. To make the usage more flexible and interactive, it should be possible to provide change requests in a chat-like interface.

The three follow-ups can utilize the existing infrastructure and should be within a reasonable workload (1-3 days).

Test Coverage

Screenshots

screenshot
Hyperion_Code_Generation_with_Artemis.mp4

Summary by CodeRabbit

  • New Features

    • AI-powered code generation for programming exercises (solution, template, tests) with an instructor-facing "Generate Code" action and REST endpoint; localized UI strings (EN/DE).
  • Improvements

    • More reliable build agent file transfers with automatic retries.
    • Safer repository cleanup before deletion.
    • Exposed default VCS branch configuration for integrations.
  • Documentation

    • Added Hyperion setup and code-generation process guide (costs & operational notes).
  • Tests

    • Expanded unit tests covering generation services, templates, context rendering, and architecture checks.

@github-project-automation github-project-automation bot moved this to Work In Progress in Artemis Development Sep 22, 2025
@github-actions github-actions bot added tests server Pull requests that update Java code. (Added Automatically!) client Pull requests that update TypeScript code. (Added Automatically!) config-change Pull requests that change the config in a way that they require a deployment via Ansible. buildagent Pull requests that affect the corresponding module programming Pull requests that affect the corresponding module hyperion labels Sep 22, 2025
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report205 ran199 passed3 skipped3 failed1h 18m 49s 259ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/quiz-exercise/QuizExerciseManagement.spec.ts
ts.Quiz Exercise Management › Quiz Exercise Creation › Creates a Quiz with Drag and Drop❌ failure2m 3s 745ms
e2e/exercise/quiz-exercise/QuizExerciseParticipation.spec.ts
ts.Quiz Exercise Participation › DnD Quiz participation › Student can participate in DnD Quiz❌ failure2m 5s 56ms
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure2m 38s 362ms

Copy link
Contributor

@FelixTJDietrich FelixTJDietrich left a comment

Choose a reason for hiding this comment

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

Hey @luis-gasparschroeder, looks really good already :)
I found some places for potential improvements.

Some question from my side: How does the previous state of the repository get accounted for? Especially for when build issues arise? Do you just discard all and regenerate? It is not 100% clear to me

@github-project-automation github-project-automation bot moved this from Work In Progress to Ready For Review in Artemis Development Sep 22, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 23, 2025
@luis-gasparschroeder
Copy link
Author

Hey @luis-gasparschroeder, looks really good already :) I found some places for potential improvements.

Some question from my side: How does the previous state of the repository get accounted for? Especially for when build issues arise? Do you just discard all and regenerate? It is not 100% clear to me

The code generation does not delete files at this point in time. Consequently, the pre-existing files remain. This functionality can be added in a follow-up PR

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 24, 2025
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report205 ran200 passed3 skipped2 failed1h 17m 12s 105ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/quiz-exercise/QuizExerciseManagement.spec.ts
ts.Quiz Exercise Management › Quiz Exercise Creation › Creates a Quiz with Drag and Drop❌ failure2m 4s 995ms
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure2m 30s 897ms

Copy link
Contributor

@FelixTJDietrich FelixTJDietrich left a comment

Choose a reason for hiding this comment

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

I'm seeing the "Create Assistance" button even though I set hyperion: false
image

Please also update your PR description. Try to also fill the test coverage report, but it seems that the test checks need to pass for that (which is sometimes flaky). I mentioned on Monday that a discussion / issues section in the PR description would be needed so we can start to track follow-up issues and we know what we are getting into transparently when we merge this PR.

Considerations include:

  • File deletion
  • Starting with a minimal repository state for generation
    • Default tests case don't make sense -> We'd need to start blank?
  • Observability / cost tracking
  • Double invocation guard (currently you can just press "Generate code" again once you refresh, it also does not reject it)
  • UI is not updating except for the build results

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
src/main/webapp/app/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.ts (1)

32-46: Remove duplicate imports.

ArtemisTranslatePipe appears on lines 32 and 46, and NgbTooltip appears on lines 41 and 45. Remove the duplicates to keep the imports clean.

Apply this diff:

     imports: [
         FaIconComponent,
         TranslateDirective,
         ArtemisTranslatePipe,
         CodeEditorContainerComponent,
         IncludedInScoreBadgeComponent,
         ProgrammingExerciseInstructorExerciseStatusComponent,
         NgbDropdown,
         NgbDropdownToggle,
         NgbDropdownMenu,
         NgbDropdownButtonItem,
         NgbDropdownItem,
         NgbTooltip,
         UpdatingResultComponent,
         ProgrammingExerciseStudentTriggerBuildButtonComponent,
         ProgrammingExerciseEditableInstructionComponent,
-        NgbTooltip,
-        ArtemisTranslatePipe,
     ],
♻️ Duplicate comments (3)
src/main/webapp/app/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.html (3)

135-138: Add an accessible name for the spinner-only button.

The spinner button lacks an accessible name for assistive technologies. Add a visually hidden translated label or aria-label.

Apply this diff to add a hidden accessible label:

 @if (isGeneratingCode()) {
     <button class="btn btn-outline-primary" disabled>
         <fa-icon [icon]="faSpinner" animation="spin" />
+        <span class="visually-hidden" jhiTranslate="artemisApp.programmingExercise.codeGeneration.creationAssistance"></span>
     </button>

136-138: [Duplicate] Add accessible label for spinner button.

This spinner-only button lacks an accessible name, making it inaccessible to assistive technologies. Previous review comments have already flagged this issue and provided a solution.


150-152: [Duplicate] Missing i18n translation on hardcoded text.

The button contains hardcoded English text "Generate Code" despite having the jhiTranslate directive. The translation key should provide the text content, not duplicate it. Previous reviewers have already flagged missing i18n throughout this section.

🧹 Nitpick comments (4)
src/main/webapp/app/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.ts (4)

75-122: Consider using finalize() to guarantee state reset.

The isGeneratingCode signal is reset in both the next and error callbacks, but if the subscription completes or errors in an unexpected way, the state might not be reset. Using the finalize() operator ensures the flag is always reset regardless of how the observable completes.

Apply this diff to add finalize():

+import { finalize } from 'rxjs';
+
 generateCode(): void {
     if (!this.exercise?.id || this.isGeneratingCode()) {
         return;
     }
 
     // Only allow code generation for supported repository types
     if (this.selectedRepository !== RepositoryType.TEMPLATE && this.selectedRepository !== RepositoryType.SOLUTION && this.selectedRepository !== RepositoryType.TESTS) {
         this.codeGenAlertService.addAlert({
             type: AlertType.WARNING,
             translationKey: 'artemisApp.programmingExercise.codeGeneration.unsupportedRepository',
         });
         return;
     }
 
     this.isGeneratingCode.set(true);
 
     const request: CodeGenerationRequestDTO = {
         repositoryType: this.selectedRepository as CodeGenerationRequestDTO.RepositoryTypeEnum,
     };
 
-    this.codeGenerationService.generateCode(this.exercise.id, request).subscribe({
+    this.codeGenerationService.generateCode(this.exercise.id, request)
+        .pipe(finalize(() => this.isGeneratingCode.set(false)))
+        .subscribe({
         next: (response) => {
-            this.isGeneratingCode.set(false);
-
             if (response.success) {
                 this.codeGenAlertService.addAlert({
                     type: AlertType.SUCCESS,
                     translationKey: 'artemisApp.programmingExercise.codeGeneration.success',
                     translationParams: { repositoryType: this.selectedRepository },
                 });
             } else {
                 this.codeGenAlertService.addAlert({
                     type: AlertType.WARNING,
                     translationKey: 'artemisApp.programmingExercise.codeGeneration.partialSuccess',
                     translationParams: { repositoryType: this.selectedRepository },
                 });
             }
         },
         error: () => {
-            this.isGeneratingCode.set(false);
             this.codeGenAlertService.addAlert({
                 type: AlertType.DANGER,
                 translationKey: 'artemisApp.programmingExercise.codeGeneration.error',
                 translationParams: { repositoryType: this.selectedRepository },
             });
         },
     });
 }

89-94: Consider safer type handling for repository enum.

The type assertion on line 92 assumes this.selectedRepository will always match the CodeGenerationRequestDTO.RepositoryTypeEnum after the validation check. While the validation on lines 81-87 ensures only TEMPLATE, SOLUTION, or TESTS are allowed, the string values must exactly match the enum.

Consider adding explicit mapping or runtime validation to make the contract more explicit:

 const request: CodeGenerationRequestDTO = {
-    repositoryType: this.selectedRepository as CodeGenerationRequestDTO.RepositoryTypeEnum,
+    repositoryType: this.selectedRepository as 'TEMPLATE' | 'SOLUTION' | 'TESTS',
 };

Or verify the enum values match at the validation site to make the relationship explicit.


95-121: Add explicit subscription cleanup or use async patterns.

The observable subscription created on line 95 is not explicitly unsubscribed. While HTTP observables complete automatically after a single emission, consider using declarative patterns for consistency and to avoid potential memory leaks if the subscription is modified in the future.

Consider one of these approaches:

Option 1: Store subscription and clean up in ngOnDestroy

private subscription = new Subscription();

ngOnDestroy() {
    this.subscription.unsubscribe();
}

// In generateCode():
this.subscription.add(
    this.codeGenerationService.generateCode(this.exercise.id, request).subscribe({
        // handlers...
    })
);

Option 2: Use takeUntilDestroyed operator (Angular 16+)

import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

// In generateCode():
this.codeGenerationService
    .generateCode(this.exercise.id, request)
    .pipe(takeUntilDestroyed(this.destroyRef))
    .subscribe({
        // handlers...
    });

95-121: Consider providing more actionable error feedback.

The error handler on lines 113-120 catches all errors and shows a generic danger alert. For better user experience and debugging, consider:

  1. Logging the error details for troubleshooting
  2. Distinguishing between different error types (network, validation, server errors)
  3. Providing more specific guidance based on the error type

Example enhancement:

 error: (error) => {
     this.isGeneratingCode.set(false);
+    console.error('Code generation failed:', error);
+    
+    const translationKey = error.status === 400 
+        ? 'artemisApp.programmingExercise.codeGeneration.validationError'
+        : 'artemisApp.programmingExercise.codeGeneration.error';
+        
     this.codeGenAlertService.addAlert({
         type: AlertType.DANGER,
-        translationKey: 'artemisApp.programmingExercise.codeGeneration.error',
+        translationKey,
         translationParams: { repositoryType: this.selectedRepository },
     });
 },
📜 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 978e204 and c91763a.

📒 Files selected for processing (2)
  • src/main/webapp/app/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.html (4 hunks)
  • src/main/webapp/app/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/main/webapp/**/*.html

⚙️ CodeRabbit configuration file

@if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

Files:

  • src/main/webapp/app/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.html
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/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.ts
🧬 Code graph analysis (1)
src/main/webapp/app/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.ts (2)
src/main/webapp/app/app.constants.ts (1)
  • MODULE_FEATURE_HYPERION (40-40)
src/main/webapp/app/openapi/model/codeGenerationRequestDTO.ts (3)
  • CodeGenerationRequestDTO (15-20)
  • RepositoryTypeEnum (22-26)
  • RepositoryTypeEnum (27-27)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: server-style
  • GitHub Check: client-style
  • GitHub Check: client-tests
  • GitHub Check: Analyse
  • GitHub Check: bean-instantiation-check
🔇 Additional comments (9)
src/main/webapp/app/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.html (4)

132-157: Adjust UI placement per tester feedback.

According to the PR objectives, FelixTJDietrich reported that the "Creation Assistance" dropdown should be placed to the right of the "Create Assignment Repository" button in the same button group (not as a separate btn-group), and the result/feedback progress should appear to the right of that button as previously designed.

Currently, the Hyperion code generation UI is a standalone btn-group that appears after the delete button. Please verify the intended layout with the design and adjust the button placement accordingly to match the expected UX flow.


174-174: LGTM—single-line refactor preserves all bindings.

The trigger-build button has been condensed to a single line while preserving all attributes ([exercise], [participation], [btnSize]). This improves readability without changing functionality.


132-157: Verify UI placement aligns with PR feedback.

According to the PR objectives, FelixTJDietrich reported that the "Creation Assistance" dropdown should be placed to the right of the "Create Assignment Repository" button in the same button group, with results/feedback appearing to the right of that button. The current implementation places the Hyperion controls in a separate btn-group div outside the repository creation/deletion button context. Please verify this matches the intended UX design and tester feedback.

Based on the PR objectives feedback, you may need to adjust the layout so the AI generation controls are visually grouped with the repository action buttons rather than appearing as a separate control cluster.


174-174: LGTM: Multi-line component simplified correctly.

The simplification from multi-line to single-line format maintains all required bindings ([exercise], [participation], [btnSize]) and improves readability.

src/main/webapp/app/programming/manage/code-editor/instructor-and-editor-container/code-editor-instructor-and-editor-container.component.ts (5)

68-68: Good use of signal API for reactive state.

Using signal(false) for isGeneratingCode aligns with Angular's modern signal-based reactivity and prepares the component for zoneless rendering. This addresses the earlier review feedback.


65-70: Approve service injection and feature flag integration.

The use of inject() for dependency injection, the Hyperion feature flag check via ProfileService, and the signal-based state management are all clean and idiomatic. The integration with HyperionCodeGenerationApiService follows Angular best practices.


17-23: LGTM: Clean dependency imports.

The imports are well-organized and include all necessary dependencies for the Hyperion code generation feature. The use of OpenAPI-generated types ensures type safety with the backend contract.


65-70: LGTM: Modern Angular patterns with signal state.

Good use of the inject() function for dependency injection and the signal API for reactive state management. This addresses the previous review feedback and aligns with Angular's direction toward zoneless change detection.


76-87: LGTM: Robust validation guards.

The validation logic correctly:

  • Guards against missing exercise ID or concurrent generation
  • Restricts to supported repository types (TEMPLATE, SOLUTION, TESTS)
  • Provides user feedback for unsupported repositories

The repository type check aligns with the DTO enum definition.

Copy link

End-to-End (E2E) Test Results Summary

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

Copy link
Contributor

@FelixTJDietrich FelixTJDietrich left a comment

Choose a reason for hiding this comment

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

Tested locally and it works, we also need to test on staging before merging.
The "Create Assistance" button is also correctly removed when hyperion is disabled.

Issues to be aware of / follow-ups:

  • The current approach does not clean up / delete (existing) files
  • Idea: Start with a minimal repository state for generation
    • Default tests case don't make sense -> We'd need to start blank?
  • It is a bit intransparent what is going on in the code generation pipeline from the logs alone, we need some better observability and also cost tracking in the future
  • We do not guard agains double invocation (currently you can just press "Generate code" again once you refresh, it also does not reject it)
  • UI is not updating except for the build results so we have to refresh after the code generation does a commit to see the changed files

Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report205 ran201 passed3 skipped1 failed1h 3m 8s 211ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/quiz-exercise/QuizExerciseManagement.spec.ts
ts.Quiz Exercise Management › Quiz Exercise Creation › Creates a Quiz with Drag and Drop❌ failure2m 4s 109ms

@helios-aet helios-aet bot temporarily deployed to artemis-test1.artemis.cit.tum.de September 30, 2025 14:55 Inactive
HawKhiem
HawKhiem previously approved these changes Sep 30, 2025
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. Generation works as expected

- Update HyperionCodeGenerationExecutionServiceTest to use new constructor signature
- Add missing HyperionProgrammingExerciseContextRendererService parameter to template and test repository service tests
- Remove dependency on ApplicationContext in favor of direct strategy injection
- Fix compilation errors that were preventing server test coverage generation
…s1intum/Artemis into feature/hyperion/code-generation-clean
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: 2

♻️ Duplicate comments (2)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionServiceTest.java (1)

138-140: Test name claims "callsGitService" but no interaction is verified; also repository is null.

The test name suggests that GitService interactions are being verified, but:

  • gitService.getOrCheckoutRepository(null, false, "main", false) returns null on an unmocked call
  • No verify() statements assert that GitService methods were invoked
  • The test only ensures no exception is thrown

Options to fix (per previous review):

  1. Rename to reflect actual behavior: cleanupRepository_withRepositoryAndCommitHash_doesNotThrow
  2. Or stub a mock Repository and verify expected GitService interactions inside cleanupRepository

Minimal rename:

-    void cleanupRepository_withValidInputs_callsGitService() throws Exception {
+    void cleanupRepository_withRepositoryAndCommitHash_doesNotThrow() throws Exception {
         ReflectionTestUtils.invokeMethod(service, "cleanupRepository", gitService.getOrCheckoutRepository(null, false, "main", false), "commit-hash");
     }
src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java (1)

158-165: Repository-access exception test still expects RuntimeException.

We still stub the chat model to throw a generic RuntimeException and assert the same, even though the production code converts repository/network failures into NetworkingException via the context renderer path. Please trigger the failure through contextRenderer.getExistingSolutionCode(...) (or the corresponding collaborator) and assert that a NetworkingException is emitted, as flagged in the earlier review.

Apply this diff to align the set-up and expectation:

-        when(chatModel.call(any(Prompt.class))).thenThrow(new RuntimeException("Repository access failed"));
-
-        assertThatThrownBy(() -> templateRepository.generateSolutionPlan(user, exercise, "logs", "structure")).isInstanceOf(RuntimeException.class)
-                .hasMessageContaining("Repository access failed");
+        when(contextRenderer.getExistingSolutionCode(eq(exercise), eq(gitService)))
+                .thenThrow(new NetworkingException("Repository access failed"));
+
+        assertThatThrownBy(() -> templateRepository.generateSolutionPlan(user, exercise, "logs", "structure")).isInstanceOf(NetworkingException.class)
+                .hasMessageContaining("Repository access failed");
🧹 Nitpick comments (2)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionServiceTest.java (2)

62-63: Remove unused mock.

The mockStrategy mock is declared but never used in any test. Remove it to keep the test class clean.

-    @Mock
-    private HyperionCodeGenerationService mockStrategy;
-
     private HyperionCodeGenerationExecutionService service;

27-151: Consider adding tests for the main generation orchestration flow.

The current tests cover strategy resolution, null handling, and delegation, but don't test the core orchestration logic in generateAndCompileCode with valid inputs. Consider adding tests for:

  • Valid repository URI with successful generation
  • Iteration/retry logic with CI feedback
  • Strategy invocation and response handling
  • Build log extraction with actual Result objects

These may be better suited as integration tests if they require complex setup or external dependencies.

📜 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 2cb1ca4 and 620a048.

📒 Files selected for processing (3)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionServiceTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryTest.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryTest.java
🧰 Additional context used
📓 Path-based instructions (1)
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/hyperion/service/codegeneration/HyperionCodeGenerationExecutionServiceTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java
🧬 Code graph analysis (1)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java (2)
src/main/java/de/tum/cit/aet/artemis/programming/domain/Repository.java (1)
  • Repository (19-102)
src/main/java/de/tum/cit/aet/artemis/programming/domain/VcsRepositoryUri.java (1)
  • VcsRepositoryUri (11-180)
⏰ 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). (10)
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: client-style
  • GitHub Check: server-style
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: bean-instantiation-check
  • GitHub Check: Analyse
  • GitHub Check: Mend Security Check
🔇 Additional comments (6)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionServiceTest.java (6)

71-85: LGTM! Constructor issue from past review is resolved.

The setup correctly instantiates HyperionCodeGenerationExecutionService with the three strategy service mocks (solutionStrategy, templateStrategy, testStrategy) instead of the deprecated ApplicationContext approach. The test fixtures are clean and follow the coding guidelines.


87-112: LGTM! Strategy resolution tests are well-structured.

The four tests comprehensively cover strategy resolution for supported repository types (SOLUTION, TEMPLATE, TESTS) and unsupported types (AUXILIARY). Each test is focused, uses descriptive naming, and properly verifies the injected strategy mocks.


114-121: LGTM! Delegation to GitService is properly verified.

The test correctly stubs gitService.getDefaultBranch() and verifies the private method returns the expected value.


123-128: LGTM! Null repository URI handling is verified.

The test correctly validates that generateAndCompileCode returns null when the exercise has no repository URI configured.


130-135: LGTM! Null result handling is verified.

The test properly validates the default error message returned when the build result is null.


143-150: LGTM! Null-input handling tests are appropriately named and focused.

These two tests correctly verify that cleanupRepository handles null repository and null commit hash without throwing exceptions. The test names accurately reflect their intent.

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

♻️ Duplicate comments (3)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationService.java (1)

45-49: Make ChatClient mandatory or fail fast

chatClient is injected with required = false, yet every subclass calls callChatClient(...) unconditionally. When Hyperion is enabled but Spring AI is misconfigured or missing, this becomes a guaranteed NullPointerException during generation. Either require a bean (remove the optional injection and Objects.requireNonNull it) or throw a descriptive NetworkingException up front when it is absent. This was raised earlier and remains unresolved.

src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionServiceTest.java (1)

138-140: Test still never exercises cleanupRepository

gitService.getOrCheckoutRepository(...) on a mock returns null, so you end up calling cleanupRepository(null, "commit-hash"). The method exits without touching gitService.resetToOriginHead, yet the test name claims it verifies that call. Please stub a real Repository (or just pass a mock) and assert that resetToOriginHead is invoked, or rename the test to match the no-op behavior. This was flagged earlier but remains unresolved.

src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionService.java (1)

402-405: Don’t swallow InterruptedException while polling CI

The catch (Exception e) block also absorbs InterruptedException, clears the interrupt flag, and even calls Thread.sleep again. That breaks shutdown and cancellation semantics. Handle interrupts explicitly and rethrow:

-            catch (Exception e) {
-                log.warn("Exception while polling for build result for commit {}: {}. Continuing...", commitHash, e.getMessage());
-                Thread.sleep(POLL_INTERVAL);
-            }
+            catch (InterruptedException ie) {
+                Thread.currentThread().interrupt();
+                throw ie;
+            }
+            catch (Exception e) {
+                log.warn("Exception while polling for build result for commit {}: {}. Continuing...", commitHash, e.getMessage());
+            }
+
+            Thread.sleep(POLL_INTERVAL);

Also move the final Thread.sleep outside the try/catch so we still respect the poll interval on the happy path.

📜 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 620a048 and 595252a.

📒 Files selected for processing (17)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/ArtifactLocationDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/ArtifactTypeDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/CodeGenerationResponseDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/ConsistencyIssueCategoryDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/ConsistencyIssueDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/GeneratedFileDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/SeverityDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/service/HyperionConsistencyCheckService.java (5 hunks)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationService.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/architecture/HyperionCodeStyleArchitectureTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionConsistencyCheckServiceTest.java (2 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionServiceTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationStrategyTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionSolutionRepsitoryTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryTest.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryTest.java
🧰 Additional context used
📓 Path-based instructions (2)
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/hyperion/dto/ArtifactTypeDTO.java
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/ArtifactLocationDTO.java
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/GeneratedFileDTO.java
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/ConsistencyIssueDTO.java
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/SeverityDTO.java
  • src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionService.java
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/ConsistencyIssueCategoryDTO.java
  • src/main/java/de/tum/cit/aet/artemis/hyperion/service/HyperionConsistencyCheckService.java
  • src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationService.java
  • src/main/java/de/tum/cit/aet/artemis/hyperion/dto/CodeGenerationResponseDTO.java
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/hyperion/service/HyperionConsistencyCheckServiceTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionSolutionRepsitoryTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionServiceTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/architecture/HyperionCodeStyleArchitectureTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationStrategyTest.java
🧬 Code graph analysis (3)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionService.java (4)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationService.java (1)
  • Service (32-157)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/HyperionProgrammingExerciseContextRendererService.java (1)
  • Service (93-371)
src/main/java/de/tum/cit/aet/artemis/programming/domain/Repository.java (1)
  • Repository (19-102)
src/main/java/de/tum/cit/aet/artemis/programming/service/localvc/LocalVCRepositoryUri.java (1)
  • LocalVCRepositoryUri (17-318)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/HyperionConsistencyCheckService.java (2)
src/main/webapp/app/openapi/model/consistencyIssue.ts (1)
  • ConsistencyIssue (16-37)
src/main/webapp/app/openapi/model/artifactLocation.ts (1)
  • ArtifactLocation (15-32)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationService.java (5)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationExecutionService.java (1)
  • Service (46-410)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryService.java (1)
  • Service (28-94)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryService.java (1)
  • Service (28-94)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/HyperionProgrammingExerciseContextRendererService.java (1)
  • Service (93-371)
src/main/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionSolutionRepositoryService.java (1)
  • Service (24-69)
⏰ 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). (10)
  • 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-style
  • GitHub Check: server-tests
  • GitHub Check: server-style
  • GitHub Check: Analyse
  • GitHub Check: bean-instantiation-check
  • GitHub Check: Mend Security Check

Copy link

github-actions bot commented Oct 2, 2025

End-to-End (E2E) Test Results Summary

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

Copy link

github-actions bot commented Oct 2, 2025

End-to-End (E2E) Test Results Summary

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (8)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java (3)

108-120: Still not asserting solution-code propagation

This test keeps passing even if the solution snippet never reaches the prompt variables—exactly the gap we flagged earlier. Please capture the Map passed to renderObject(...) and assert it contains the sentinel returned by contextRenderer.getExistingSolutionCode(...).


122-185: Failure-path tests remain false positives

All four scenario-specific tests still execute the happy path: no checkout failure, no multi-file concatenation, no IO exception, no empty result. They will never catch regressions in those branches. Please stub the relevant collaborators to reproduce each condition (or drop redundant tests) and assert the expected warnings/errors.


163-171: Wrong collaborator mocked for repository-access failure

generateSolutionPlan_withRepositoryAccessException_throwsNetworkingException still stubs chatModel.call(...) to throw RuntimeException, so we are not exercising repository access at all. Instead, make contextRenderer.getExistingSolutionCode(...) throw the NetworkingException you expect and assert that propagation. This aligns the test with the production failure path.

src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryTest.java (5)

95-107: Test name implies verifying template variables; assertion currently doesn't check them.

This test only verifies that render() was invoked. Per previous review feedback, capture the variables and assert expected keys/values (e.g., language, repositoryStructure, buildLogs, solutionCode).

Based on past review comments.


109-120: Test name is misleading; no failure is simulated and no warning is asserted.

The test name claims withFailedRepositoryCheckout_usesWarningMessage, but all mocks return successful responses and no warning message is asserted. Either simulate a repository checkout failure (e.g., stub contextRenderer.getExistingSolutionCode to throw an exception or return an error indicator) and assert the warning message in template variables, or rename the test to reflect current behavior.

Based on past review comments.


122-134: Test name is misleading; no multi-file input is provided and no concatenation is asserted.

The test name claims withMultipleJavaFiles_concatenatesContent, but the mock returns a single solution code and no concatenation is verified. Either stub contextRenderer.getExistingSolutionCode to return multiple concatenated files and assert the concatenated content in template variables, or rename the test to reflect current behavior.

Based on past review comments.


136-148: Test name is misleading; no IOException is induced and no error message is asserted.

The test name claims withIOExceptionDuringWalk_returnsErrorMessage, but all mocks return successful responses and no error message is asserted. Either stub contextRenderer.getExistingSolutionCode to throw an IOException and assert the error message in the template variables or result, or rename the test to reflect current behavior.

Based on past review comments.


160-172: Test name is misleading; no "no files" condition is simulated and no message is asserted.

The test name claims withNoJavaFiles_returnsNoFilesMessage, but the mock returns "public class Solution {}" (indicating a Java file is present) and no "no files" message is asserted. Either stub contextRenderer.getExistingSolutionCode to return an empty string or specific message and assert that message in the template variables or result, or rename the test to reflect current behavior.

Based on past review comments.

🧹 Nitpick comments (5)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationStrategyTest.java (1)

86-92: Assert the intended invocation order explicitly

The comment claims we verify the four steps execute “in correct order”, yet times(4) only checks call count. If the production pipeline ever shuffled the sequence, this test would stay green. Please switch to an InOrder verification (plan → structure → headers → logic) so the test fails when the orchestration regresses.

src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionSolutionRepsitoryTest.java (1)

35-35: Rename the file to match the class.

The file is named HyperionSolutionRepsitoryTest.java while the class is HyperionSolutionRepositoryServiceTest. Please rename the file to match the class to avoid confusion during navigation and future maintenance.

src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryTest.java (3)

77-93: Consider capturing and asserting template variables.

While this test validates the happy path, it doesn't capture the Map passed to templates.renderObject to verify the template variables contain expected keys like "language", "repositoryStructure", "buildLogs", and "solutionCode". This would strengthen confidence that the correct context is passed to the template.

Example:

var captor = ArgumentCaptor.forClass(Map.class);
verify(templates).renderObject(eq("/prompts/hyperion/test/1_plan.st"), captor.capture());
Map<String, Object> vars = captor.getValue();
assertThat(vars).containsKeys("language", "repositoryStructure", "buildLogs", "solutionCode");

241-253: Consider capturing template variables to verify empty string usage.

While this test validates that null buildLogs doesn't cause an exception, it doesn't capture the template variables to confirm that an empty string is actually passed to the template. Consider using an ArgumentCaptor to verify the "buildLogs" key in the template variables contains an empty string.

Example:

var captor = ArgumentCaptor.forClass(Map.class);
verify(templates).renderObject(eq("/prompts/hyperion/test/1_plan.st"), captor.capture());
Map<String, Object> vars = captor.getValue();
assertThat(vars).containsEntry("buildLogs", "");

255-267: Consider capturing template variables to verify empty string usage.

While this test validates that null repositoryStructure doesn't cause an exception, it doesn't capture the template variables to confirm that an empty string is actually passed to the template. Consider using an ArgumentCaptor to verify the "repositoryStructure" key in the template variables contains an empty string.

Example:

var captor = ArgumentCaptor.forClass(Map.class);
verify(templates).renderObject(eq("/prompts/hyperion/test/1_plan.st"), captor.capture());
Map<String, Object> vars = captor.getValue();
assertThat(vars).containsEntry("repositoryStructure", "");
📜 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 3416a0f and f1a1316.

📒 Files selected for processing (4)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationStrategyTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionSolutionRepsitoryTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryTest.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
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/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionCodeGenerationStrategyTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionSolutionRepsitoryTest.java
🧬 Code graph analysis (1)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTemplateRepositoryTest.java (2)
src/main/java/de/tum/cit/aet/artemis/programming/domain/Repository.java (1)
  • Repository (19-107)
src/main/java/de/tum/cit/aet/artemis/programming/domain/VcsRepositoryUri.java (1)
  • VcsRepositoryUri (11-180)
⏰ 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). (12)
  • GitHub Check: client-tests
  • GitHub Check: client-compilation
  • GitHub Check: client-tests-selected
  • GitHub Check: client-style
  • GitHub Check: server-style
  • GitHub Check: server-tests
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: bean-instantiation-check
  • GitHub Check: Analyse
🔇 Additional comments (7)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/codegeneration/HyperionTestRepositoryTest.java (7)

62-75: LGTM: Test setup is complete and correct.

The setup method properly initializes all mocks and dependencies, including the contextRenderer that was previously missing. The test fixtures (user and exercise) are appropriately minimal for unit testing.


174-188: LGTM: Test validates file structure generation correctly.

The test properly verifies that defineFileStructure returns the expected file structure with correct path and content. Assertions are specific and use assertThat as per guidelines.


190-204: LGTM: Test validates multi-step prompting correctly.

The test properly verifies that generateClassAndMethodHeaders calls both file structure and headers generation, and asserts the expected method signature in the result. Interaction verification ensures both prompts are invoked.


206-222: LGTM: Test validates full generation pipeline correctly.

The test properly verifies that generateCoreLogic orchestrates all three steps (file structure, headers, logic) and asserts the expected test implementation in the result. Interaction verification ensures all prompts are invoked in sequence.


224-229: LGTM: Test validates repository type correctly.

Simple and clear test that verifies the service returns the correct repository type.


231-239: LGTM: Test validates exception mapping correctly.

The test properly verifies that NonTransientAiException from the AI service is mapped to NetworkingException with an appropriate error message.


269-273: LGTM: Helper method improves test readability.

This private helper encapsulates ChatResponse creation, making test setup cleaner and more maintainable.

Copy link

github-actions bot commented Oct 2, 2025

End-to-End (E2E) Test Results Summary

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

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 2, 2025
Copy link

github-actions bot commented Oct 2, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report205 ran201 passed3 skipped1 failed1h 6m 41s 524ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/quiz-exercise/QuizExerciseManagement.spec.ts
ts.Quiz Exercise Management › Quiz Exercise Creation › Creates a Quiz with Drag and Drop❌ failure2m 5s 290ms

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

🧹 Nitpick comments (7)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionProgrammingExerciseContextRendererServiceTest.java (4)

17-24: Consider using static mocks per coding guidelines.

The coding guidelines specify mock_strategy: static_mocks for this path. Consider replacing @Mock annotations with explicit Mockito.mock() calls in the @BeforeEach method for consistency with project conventions.

Apply this diff:

-    @Mock
-    private RepositoryService repositoryService;
-
-    @Mock
-    private HyperionProgrammingLanguageContextFilterService languageFilter;
-
-    @Mock
-    private GitService gitService;
+    private RepositoryService repositoryService;
+    private HyperionProgrammingLanguageContextFilterService languageFilter;
+    private GitService gitService;

And update the setup method:

     @BeforeEach
     void setup() {
-        MockitoAnnotations.openMocks(this);
+        repositoryService = Mockito.mock(RepositoryService.class);
+        languageFilter = Mockito.mock(HyperionProgrammingLanguageContextFilterService.class);
+        gitService = Mockito.mock(GitService.class);
         contextRendererService = new HyperionProgrammingExerciseContextRendererService(repositoryService, languageFilter);

As per coding guidelines.


56-63: Strengthen assertion for null problem statement test.

The test verifies graceful handling but only asserts isNotNull(), which doesn't validate the actual behavior. Consider verifying that the rendered context either contains a placeholder/default message or follows the expected format even with a null problem statement.

Example enhancement:

     @Test
     void renderContext_withNullProblemStatement_handlesGracefully() {
         exercise.setProblemStatement(null);
 
         String result = contextRendererService.renderContext(exercise);
 
-        assertThat(result).isNotNull();
+        assertThat(result).isNotNull().isNotEmpty();
+        // Or verify it contains expected structure/placeholder

As per coding guidelines: assert_specificity: true.


66-66: Remove or specify exception in test signature.

The throws Exception declaration is too broad and likely unnecessary. If the method can throw specific checked exceptions, declare them explicitly; otherwise, remove the throws clause entirely to improve test clarity.

-    void getExistingSolutionCode_withNullRepositoryUri_returnsWarningMessage() throws Exception {
+    void getExistingSolutionCode_withNullRepositoryUri_returnsWarningMessage() {

As per coding guidelines: tests should be specific and clear about expected behavior.


72-88: Strengthen assertions for edge-case tests.

Tests renderContext_withNullProgrammingLanguage_handlesGracefully and renderContext_withEmptyProblemStatement_handlesGracefully only assert isNotNull(), which merely confirms no exception was thrown. Consider verifying the actual rendered output structure, default values, or expected placeholders to ensure correct behavior under these edge cases.

Example enhancement:

     @Test
     void renderContext_withNullProgrammingLanguage_handlesGracefully() {
         exercise.setProgrammingLanguage(null);
 
         String result = contextRendererService.renderContext(exercise);
 
-        assertThat(result).isNotNull();
+        assertThat(result).isNotNull().isNotEmpty();
+        // Verify expected format or default behavior
     }
 
     @Test
     void renderContext_withEmptyProblemStatement_handlesGracefully() {
         exercise.setProblemStatement("");
 
         String result = contextRendererService.renderContext(exercise);
 
-        assertThat(result).isNotNull();
+        assertThat(result).isNotNull().isNotEmpty();
+        // Verify expected handling of empty vs null problem statements
     }

As per coding guidelines: assert_specificity: true — assertions should verify actual behavior, not just absence of errors.

src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionProgrammingLanguageContextFilterServiceTest.java (2)

70-86: Consider adding absence assertions for excluded files.

The test properly validates inclusion of Java source files but could be more explicit by also asserting the absence of excluded files (e.g., target/classes, build.gradle, .idea, node_modules). This matches the pattern in filter_withJavaLanguage_filtersCorrectly (lines 36-38) and makes the test intent clearer.

Apply this diff:

     assertThat(result).hasSize(2);
     assertThat(result).containsKey("src/main/java/com/example/Service.java");
     assertThat(result).containsKey("src/main/java/com/example/Controller.java");
+    assertThat(result).doesNotContainKey("target/classes/Service.class");
+    assertThat(result).doesNotContainKey("build.gradle");
+    assertThat(result).doesNotContainKey(".idea/workspace.xml");
+    assertThat(result).doesNotContainKey("node_modules/package/index.js");
 }

88-103: Consider adding absence assertions for excluded files.

Similar to the previous test, explicitly asserting the absence of non-Java files would make the filtering behavior more obvious and align with the pattern in filter_withJavaLanguage_filtersCorrectly.

Apply this diff:

     assertThat(result).hasSize(2);
     assertThat(result).containsKey("src/main/java/Main.java");
     assertThat(result).containsKey("src/test/java/Test.java");
+    assertThat(result).doesNotContainKey("style.css");
+    assertThat(result).doesNotContainKey("script.js");
+    assertThat(result).doesNotContainKey("data.json");
+    assertThat(result).doesNotContainKey("config.xml");
 }
src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionPromptTemplateServiceTest.java (1)

10-10: Add explicit package-private visibility modifier.

The test class should explicitly declare package-private visibility (/* package */) to align with Java coding conventions and make the intended visibility clear.

Apply this diff:

-class HyperionPromptTemplateServiceTest {
+/* package */ class HyperionPromptTemplateServiceTest {
📜 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 f1a1316 and 433d89c.

📒 Files selected for processing (3)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionProgrammingExerciseContextRendererServiceTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionProgrammingLanguageContextFilterServiceTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionPromptTemplateServiceTest.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
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/hyperion/service/HyperionProgrammingExerciseContextRendererServiceTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionProgrammingLanguageContextFilterServiceTest.java
  • src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionPromptTemplateServiceTest.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). (9)
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: Analyse
  • GitHub Check: client-style
  • GitHub Check: client-tests
  • GitHub Check: server-style
  • GitHub Check: server-tests
  • GitHub Check: bean-instantiation-check
🔇 Additional comments (6)
src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionProgrammingLanguageContextFilterServiceTest.java (6)

1-11: LGTM!

Package declaration and imports are clean and follow coding guidelines. Correctly uses assertj's assertThat for assertions.


13-20: LGTM!

Test class structure is clean and follows best practices. Direct instantiation of the service in @BeforeEach is appropriate for a stateless utility, avoiding unnecessary Spring context overhead.


22-39: LGTM!

Test properly validates Java source file filtering with realistic paths. Assertions are specific and comprehensive, correctly verifying both inclusion and exclusion.


41-52: LGTM!

Test correctly validates fallback behavior for unsupported languages. Using containsExactlyInAnyOrderEntriesOf is an appropriate assertion to verify all files pass through unfiltered.


54-61: LGTM!

Edge case test for empty input is simple, focused, and uses the appropriate assertion.


63-68: LGTM!

Null input edge case is properly tested, documenting the service's null-safety behavior.

Comment on lines +10 to +69
class HyperionPromptTemplateServiceTest {

private HyperionPromptTemplateService templateService;

@BeforeEach
void setup() {
templateService = new HyperionPromptTemplateService();
}

@Test
void render_withValidTemplateAndVariables_replacesPlaceholders() throws Exception {
String templateContent = "Hello {{name}}, your score is {{score}}!";

Map<String, String> variables = Map.of("name", "John", "score", "95");

Map<String, Object> objectVariables = Map.of("name", "John", "score", 95);

assertThatThrownBy(() -> templateService.renderObject("/nonexistent/template.st", objectVariables)).isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}

@Test
void render_withStringVariables_replacesCorrectly() {
String template = "Programming language: {{language}}, Problem: {{problem}}";
Map<String, String> variables = Map.of("language", "Java", "problem", "Implement sorting");

assertThatThrownBy(() -> templateService.render("/nonexistent/template.st", variables)).isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}

@Test
void renderObject_withObjectVariables_handlesConversion() {
Map<String, Object> variables = Map.of("exerciseId", 123L, "language", "JAVA", "enabled", true);

assertThatThrownBy(() -> templateService.renderObject("/nonexistent/template.st", variables)).isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}

@Test
void render_withNullResourcePath_throwsException() {
Map<String, String> variables = Map.of("key", "value");

assertThatThrownBy(() -> templateService.render(null, variables)).isInstanceOf(RuntimeException.class);
}

@Test
void renderObject_withNullResourcePath_throwsException() {
Map<String, Object> variables = Map.of("key", "value");

assertThatThrownBy(() -> templateService.renderObject(null, variables)).isInstanceOf(RuntimeException.class);
}

@Test
void render_withEmptyVariables_processesTemplate() {
Map<String, String> variables = Map.of();

assertThatThrownBy(() -> templateService.render("/nonexistent/template.st", variables)).isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add positive test cases for successful template rendering.

The test class currently only validates error scenarios (nonexistent templates, null inputs, empty variables). Critical functionality—successful template rendering and correct variable substitution—is not tested. This leaves core behavior unvalidated and could allow bugs in the primary use case to go undetected.

Add test cases that:

  1. Load an actual template resource from src/test/resources/ (e.g., src/test/resources/prompts/test-template.st)
  2. Verify successful variable substitution for both render() and renderObject()
  3. Validate edge cases such as:
    • Templates with multiple placeholders
    • Missing variables (what's the expected behavior?)
    • Special characters in variable values
    • Numeric and boolean conversion in renderObject()

Example test structure:

@Test
void render_withValidTemplate_replacesPlaceholders() throws Exception {
    // Arrange: create test template in src/test/resources/prompts/test-template.st
    // Content: "Hello {{name}}, your score is {{score}}!"
    Map<String, String> variables = Map.of("name", "John", "score", "95");
    
    // Act
    String result = templateService.render("/prompts/test-template.st", variables);
    
    // Assert
    assertThat(result).isEqualTo("Hello John, your score is 95!");
}

@Test
void renderObject_withMixedTypes_convertsAndReplacesCorrectly() throws Exception {
    // Test numeric and boolean conversion
    Map<String, Object> variables = Map.of("id", 123L, "enabled", true, "name", "Test");
    
    String result = templateService.renderObject("/prompts/test-template-objects.st", variables);
    
    assertThat(result).contains("123", "true", "Test");
}
🤖 Prompt for AI Agents
In
src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionPromptTemplateServiceTest.java
around lines 10 to 69, add positive unit tests that load real template files
from src/test/resources/prompts (e.g. create test-template.st and
test-template-objects.st) and assert successful rendering: (1) a test that calls
templateService.render("/prompts/test-template.st",
Map.of("name","John","score","95")) and asserts the exact substituted output
"Hello John, your score is 95!"; (2) a test that calls
templateService.renderObject("/prompts/test-template-objects.st",
Map.of("id",123L,"enabled",true,"name","Test")) and asserts the numeric and
boolean values are converted and present ("123", "true", "Test"); also add short
tests for multiple placeholders, special characters in variable values, and one
asserting the service's documented behavior for missing variables (either
preserved placeholder or replaced with empty string) so the expected behavior is
explicitly asserted.

Comment on lines +19 to +29
@Test
void render_withValidTemplateAndVariables_replacesPlaceholders() throws Exception {
String templateContent = "Hello {{name}}, your score is {{score}}!";

Map<String, String> variables = Map.of("name", "John", "score", "95");

Map<String, Object> objectVariables = Map.of("name", "John", "score", 95);

assertThatThrownBy(() -> templateService.renderObject("/nonexistent/template.st", objectVariables)).isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove unused variables and align test with its name.

The test method name render_withValidTemplateAndVariables_replacesPlaceholders suggests a positive test case for successful template rendering, but the implementation only tests the failure path with a nonexistent template. Additionally, lines 21-25 declare templateContent, variables, and objectVariables that are never used in the test.

Either:

  1. Remove the unused variables and rename the test to reflect its actual behavior (e.g., renderObject_withNonexistentTemplate_throwsException), OR
  2. Add a positive test case that validates successful template rendering with the declared variables.

Apply this diff to remove unused variables and rename appropriately:

     @Test
-    void render_withValidTemplateAndVariables_replacesPlaceholders() throws Exception {
-        String templateContent = "Hello {{name}}, your score is {{score}}!";
-
-        Map<String, String> variables = Map.of("name", "John", "score", "95");
-
+    void renderObject_withNonexistentTemplate_throwsException() {
         Map<String, Object> objectVariables = Map.of("name", "John", "score", 95);
 
         assertThatThrownBy(() -> templateService.renderObject("/nonexistent/template.st", objectVariables)).isInstanceOf(RuntimeException.class)

Alternatively, add a separate positive test case using an actual template resource.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Test
void render_withValidTemplateAndVariables_replacesPlaceholders() throws Exception {
String templateContent = "Hello {{name}}, your score is {{score}}!";
Map<String, String> variables = Map.of("name", "John", "score", "95");
Map<String, Object> objectVariables = Map.of("name", "John", "score", 95);
assertThatThrownBy(() -> templateService.renderObject("/nonexistent/template.st", objectVariables)).isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}
@Test
void renderObject_withNonexistentTemplate_throwsException() {
Map<String, Object> objectVariables = Map.of("name", "John", "score", 95);
assertThatThrownBy(() -> templateService.renderObject("/nonexistent/template.st", objectVariables))
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}
🤖 Prompt for AI Agents
In
src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionPromptTemplateServiceTest.java
around lines 19-29, remove the unused local variables templateContent,
variables, and objectVariables, and rename the test method from
render_withValidTemplateAndVariables_replacesPlaceholders to
renderObject_withNonexistentTemplate_throwsException so the method name matches
the asserted behavior (assertThatThrownBy(...) checking for "Failed to load
template"); keep the existing assertion and exception expectation unchanged.

Comment on lines +31 to +38
@Test
void render_withStringVariables_replacesCorrectly() {
String template = "Programming language: {{language}}, Problem: {{problem}}";
Map<String, String> variables = Map.of("language", "Java", "problem", "Implement sorting");

assertThatThrownBy(() -> templateService.render("/nonexistent/template.st", variables)).isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove unused variables and align test with its name.

Similar to the previous test, the method name render_withStringVariables_replacesCorrectly suggests a positive scenario, but the implementation only tests failure. Lines 33-34 declare template and variables that are never used.

Apply this diff to remove unused variables and rename appropriately:

     @Test
-    void render_withStringVariables_replacesCorrectly() {
-        String template = "Programming language: {{language}}, Problem: {{problem}}";
-        Map<String, String> variables = Map.of("language", "Java", "problem", "Implement sorting");
-
+    void render_withNonexistentTemplate_throwsException() {
+        Map<String, String> variables = Map.of("key", "value");
+
         assertThatThrownBy(() -> templateService.render("/nonexistent/template.st", variables)).isInstanceOf(RuntimeException.class)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Test
void render_withStringVariables_replacesCorrectly() {
String template = "Programming language: {{language}}, Problem: {{problem}}";
Map<String, String> variables = Map.of("language", "Java", "problem", "Implement sorting");
assertThatThrownBy(() -> templateService.render("/nonexistent/template.st", variables)).isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}
@Test
void render_withNonexistentTemplate_throwsException() {
Map<String, String> variables = Map.of("key", "value");
assertThatThrownBy(() -> templateService.render("/nonexistent/template.st", variables)).isInstanceOf(RuntimeException.class)
.hasMessageContaining("Failed to load template");
}
🤖 Prompt for AI Agents
In
src/test/java/de/tum/cit/aet/artemis/hyperion/service/HyperionPromptTemplateServiceTest.java
around lines 31 to 38, remove the unused local variables `template` and
`variables` and rename the test method to reflect that it verifies failure when
loading a non-existent template (for example rename to
`render_nonexistentTemplate_throwsRuntimeException`), leaving the existing
assertion that calling templateService.render("/nonexistent/template.st",
variables) throws a RuntimeException with a message containing "Failed to load
template" (adjust the variables argument to a minimal empty or null map if
needed).

Copy link

github-actions bot commented Oct 2, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report205 ran201 passed3 skipped1 failed1h 11m 14s 794ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/quiz-exercise/QuizExerciseManagement.spec.ts
ts.Quiz Exercise Management › Quiz Exercise Creation › Creates a Quiz with Drag and Drop❌ failure2m 5s 161ms

Copy link

github-actions bot commented Oct 3, 2025

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report205 ran200 passed3 skipped2 failed1h 12m 32s 991ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/quiz-exercise/QuizExerciseManagement.spec.ts
ts.Quiz Exercise Management › Quiz Exercise Creation › Creates a Quiz with Drag and Drop❌ failure2m 3s 761ms
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure2m 35s 454ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
buildagent Pull requests that affect the corresponding module client Pull requests that update TypeScript code. (Added Automatically!) config-change Pull requests that change the config in a way that they require a deployment via Ansible. documentation hyperion programming 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.

4 participants