Skip to content

Conversation

@Anishyou
Copy link
Contributor

@Anishyou Anishyou commented Nov 23, 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 documented the Java code using JavaDoc style.

Client

  • Important: I implemented the changes with a very good performance, prevented too many (unnecessary) REST calls and made sure the UI is responsive, even with large data (e.g. using paging).
  • I strictly followed the principle of data economy for all client-server REST calls.
  • I strictly followed the client coding guidelines.
  • I strictly followed the AET UI-UX guidelines.
  • Following the theming guidelines, I specified colors only in the theming variable files and checked that the changes look consistent in both the light and the dark theme.
  • I added multiple integration tests (Jest) related to the features (with a high test coverage), while following the test guidelines.
  • I documented the TypeScript code using JSDoc style.
  • I added multiple screenshots/screencasts of my UI changes.
  • I translated all newly inserted strings into English and German.

Motivation and Context

Instructors and editors sometimes need to cancel ongoing transcription jobs for lecture videos, for example when:
-A transcription was started by mistake
-The wrong video was uploaded and needs to be replaced
-The transcription is taking too long or appears to be stuck
-The video content needs to be updated before transcription

Description

1. LectureTranscriptionService.java

  • Added cancelNebulaTranscription(Long lectureUnitId) method
  • Validates transcription status (only PENDING/PROCESSING can be canceled)
  • Calls Nebula service to cancel the job via REST API
  • Deletes the transcription record from the database
  • Includes comprehensive error handling and logging

2. NebulaTranscriptionResource.java

  • Added DELETE /api/nebula/lecture-unit/{lectureUnitId}/transcriber/cancel endpoint
  • Protected with @EnforceAtLeastEditorInLectureUnit authorization
  • Returns 200 OK on success, appropriate error codes on failure

3. Integration Tests

  • Added tests in LectureTranscriptionServiceIntegrationTest.java
  • Added tests in NebulaTranscriptionResourceIntegrationTest.java
  • Covers success cases, validation failures, authorization checks, and error scenarios

Client side Changes

1. LectureTranscriptionService

  • Added cancelTranscription(lectureUnitId: number): Observable<boolean> method
  • Handles HTTP errors gracefully

2. AttachmentVideoUnitComponent (student/instructor view)

  • Added "Cancel Transcription" button in the transcription status alert
  • Button only visible for PENDING/PROCESSING transcriptions
  • Button only shown to editors, instructors, and admins
  • Opens ConfirmAutofocusModalComponent for user confirmation
  • Displays success/error alerts after cancellation attempt
  • Button disabled during cancellation operation

3. AttachmentVideoUnitFormComponent (edit mode)

  • Same cancel functionality as above
  • Integrated into the form's transcription status display

Steps for Testing

Prerequisites

  • 1 Instructor and 1 Student account
  • 1 Course with a lecture containing an attachment video unit
  • Nebula transcription service configured

Warning

This PR can only be tested together with the corresponding PR on edutelligence.

  1. Test case 1

    • Log in as instructor → Navigate to lecture with video unit
    • Start transcription → Click "Cancel Transcription" button
    • Confirm in modal → Verify success alert and status cleared
  2. Test case 2

    • Log in as instructor → Edit lecture → Edit video unit with pending transcription
    • Click "Cancel Transcription" → Confirm → Verify success
  3. Test case 3

    • Verify cancel button only appears for PENDING/PROCESSING transcriptions
    • Verify no cancel button for COMPLETED or FAILED transcriptions
    • Test modal dismissal (click "Cancel" in modal → status unchanged)

Testserver States

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

Review Progress

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Test Coverage

Screenshots

Summary by CodeRabbit

  • New Features

    • Editors can cancel pending/processing transcriptions via a confirmation modal; cancel buttons added to management and overview UIs with loading/disabled states and success/error feedback
    • Backend cancellation endpoint added to cancel and remove ongoing transcription jobs
  • Localization

    • Added English and German strings for cancel button, confirmation, success, and error messages
  • Tests

    • Added unit and integration tests covering cancellation success, failure, authorization, and various error paths

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

@github-project-automation github-project-automation bot moved this to Work In Progress in Artemis Development Nov 23, 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!) lecture Pull requests that affect the corresponding module labels Nov 23, 2025
@Anishyou Anishyou changed the title Add cancel of transcript Lectures: Allow Cancellation of Transcript Requests Nov 23, 2025
@github-actions
Copy link

End-to-End (E2E) Test Results Summary

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

@Anishyou Anishyou marked this pull request as ready for review November 23, 2025 16:38
@Anishyou Anishyou requested review from a team and krusche as code owners November 23, 2025 16:38
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 23, 2025

Walkthrough

Adds a transcription cancellation feature: backend service method and DELETE endpoint to cancel Nebula jobs and remove records; frontend UI/components to confirm and invoke cancellation, loading/alert handling and template bindings; tests and i18n entries for English and German.

Changes

Cohort / File(s) Summary
Backend service & controller
src/main/java/de/tum/cit/aet/artemis/nebula/service/LectureTranscriptionService.java, src/main/java/de/tum/cit/aet/artemis/nebula/web/NebulaTranscriptionResource.java
Added cancelNebulaTranscription(Long lectureUnitId) and new DELETE /lecture-unit/{lectureUnitId}/transcriber/cancel endpoint. Validates transcription existence/state/jobId, calls Nebula cancel endpoint with auth, deletes transcription on success, logs progress, and maps errors to appropriate HTTP statuses.
Backend integration tests
src/test/java/de/tum/cit/aet/artemis/lecture/LectureTranscriptionServiceIntegrationTest.java, src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java
Added comprehensive tests for cancel flows: success, not-found, completed/failed state rejection, missing jobId, Nebula 4xx/5xx errors, RestClientException, and authorization scenarios.
Frontend services
src/main/webapp/app/lecture/manage/services/lecture-transcription.service.ts, src/main/webapp/app/lecture/manage/services/lecture-transcription.service.spec.ts
Added cancelTranscription(lectureUnitId: number): Observable<boolean> issuing DELETE to backend and mapping responses/errors to boolean; unit tests for success and error cases.
Frontend — edit form component
src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.ts, ...component.html, ...component.spec.ts
Added lectureUnitId input, cancelTranscription() that opens confirmation modal, isCancelling lifecycle flag, calls FE service, shows alerts, clears transcriptionStatus on success; template includes cancel button for PENDING/PROCESSING; tests for confirm/dismiss/error flows updated.
Frontend — overview component
src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts, ...component.html, ...component.spec.ts
Added transcriptionStatus signal, shouldShowTranscriptionStatus computed, cancelTranscription() modal flow with isCancelling state, UI status alerts and editor-only cancel button; tests for cancellation scenarios.
Frontend — parent bindings
src/main/webapp/app/lecture/manage/lecture-units/edit-attachment-video-unit/edit-attachment-video-unit.component.html, src/main/webapp/app/lecture/manage/lecture-units/lecture-units.component.html
Parent templates pass [lectureUnitId] into the attachment video unit form component.
Localization
src/main/webapp/i18n/en/lectureUnit.json, src/main/webapp/i18n/de/lectureUnit.json
Added translation keys: artemisApp.lectureUnit.attachmentVideoUnit.transcription.cancelButton, cancelSuccess, cancelError, cancelConfirm.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as Frontend Component
    participant Modal as Confirm Modal
    participant FESvc as LectureTranscriptionService (FE)
    participant API as NebulaTranscriptionResource (REST)
    participant BE as LectureTranscriptionService (BE)
    participant Nebula as Nebula Service

    User->>UI: Click "Cancel" button
    UI->>Modal: open confirmation
    alt user confirms
        Modal-->>UI: confirmed
        UI->>FESvc: cancelTranscription(lectureUnitId)
        FESvc->>API: DELETE /lecture-unit/{id}/transcriber/cancel
        API->>BE: cancelNebulaTranscription(id)
        BE->>BE: validate transcription & jobId/state
        BE->>Nebula: POST /transcribe/cancel/{jobId} (auth header)
        Nebula-->>BE: 200 OK
        BE->>BE: delete transcription record & flush
        BE-->>API: 200 OK
        API-->>FESvc: 200 OK
        FESvc-->>UI: Observable true
        UI->>UI: show success alert, update UI state
    else user dismisses
        Modal-->>UI: dismissed
        UI->>UI: no-op
    end
    alt Nebula/API error
        Nebula-->>BE: error (4xx/5xx) or RestClientException
        BE-->>API: mapped error (4xx/5xx/500)
        API-->>FESvc: error response
        FESvc-->>UI: Observable false/error
        UI->>UI: show error alert
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to focus:
    • Correct mapping of Nebula error responses and exceptions to HTTP status codes thrown by backend.
    • Authorization annotation on the new DELETE endpoint and integration test expectations for different roles.
    • Transactional behavior: ensure transcription deletion and flush only occur on confirmed Nebula success.
    • Frontend modal lifecycle, isCancelling handling, and UI disabling of the cancel button during requests.
    • Tests: mocked modal behavior, HTTP response observables, and repository state assertions in integration tests.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.05% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Lectures: Allow Cancellation of Transcript Requests' accurately summarizes the primary change: enabling cancellation of transcription jobs for lecture video units. It is specific, clear, and directly reflects the main objective across both server and client implementations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/lecture/transcript/add-cancel-option

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

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
src/main/java/de/tum/cit/aet/artemis/nebula/service/LectureTranscriptionService.java (1)

289-292: Improve exception handling specificity.

The catch block at line 289 catches all exceptions and wraps them in a 500 error. This loses information about the actual failure type. Consider catching specific exceptions (e.g., RestClientException for HTTP errors) to provide more precise error codes and messages.

+catch (RestClientException e) {
+    log.error("Nebula service error cancelling transcription for lectureUnitId: {}, jobId: {} → {}", lectureUnitId, jobId, e.getMessage(), e);
+    throw new ResponseStatusException(HttpStatus.BAD_GATEWAY, "Failed to communicate with Nebula service: " + e.getMessage(), e);
+}
 catch (Exception e) {
     log.error("Error cancelling transcription for lectureUnitId: {}, jobId: {} → {}", lectureUnitId, jobId, e.getMessage(), e);
     throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to cancel transcription: " + e.getMessage(), e);
 }
src/test/java/de/tum/cit/aet/artemis/lecture/LectureTranscriptionServiceIntegrationTest.java (1)

248-322: Good negative coverage; consider extracting shared setup helper

The not‑found, completed, failed, and no‑job‑ID tests clearly document the expected error conditions and messages. The repeated lecture/unit + transcription setup is quite similar across these tests, so you could optionally extract a small factory/helper (e.g. createUnitWithTranscription(status) returning both) to keep tests shorter and easier to tweak later.

src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.ts (1)

385-421: Cancel flow is correct; consider sharing logic and aligning RxJS usage

The modal‑driven cancel flow, isCancelling flag, finalize cleanup, and success/error alerts are all wired correctly and match the intended UX (only acting on confirm, bailing out when no lectureUnitId, resetting state afterward).

Two optional improvements you might consider:

  • This logic is almost identical to cancelTranscription() in AttachmentVideoUnitComponent; factoring a small helper (e.g. in a shared service or a private utility that takes the unit id and a Signal<TranscriptionStatus | undefined>) would reduce duplication and keep copy‑paste bugs at bay.
  • If this component ever starts doing longer‑lived work in this subscription, adding takeUntilDestroyed (with a DestroyRef injection) would bring it in line with the rest of the codebase’s memory‑leak‑prevention pattern, although for a one‑shot HTTP call the practical risk is already very low.
src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts (2)

70-77: Status loading behavior works; consider clearing stale status on reopen

Fetching the transcription status on each expand in toggleCollapse and driving shouldShowTranscriptionStatus from the TranscriptionStatus signal correctly enables the badge/cancel UI for PENDING/PROCESSING/FAILED.

One small refinement you might consider: when opening the unit, you already reset transcriptSegments, playlistUrl, and isLoading. Resetting transcriptionStatus there as well (e.g. this.transcriptionStatus.set(undefined);) would avoid briefly showing a stale status from a previous open while the new getTranscriptionStatus call is in flight or fails.

Also applies to: 110-139


295-326: Cancel flow is correct but duplicated; consider DRY + optional RxJS cleanup

The cancel logic here cleanly mirrors the backend contract and the form component: ask for confirmation, set isCancelling, call cancelTranscription on the current unit id, reset the flag via finalize, show success/error alerts, and clear transcriptionStatus on success so the UI updates.

Two optional follow‑ups:

  • The implementation is nearly identical to AttachmentVideoUnitFormComponent.cancelTranscription(). Extracting a shared helper (or at least centralizing the alert/isCancelling handling) would reduce maintenance overhead.
  • As with the form, you could add takeUntilDestroyed(this.destroyRef) before finalize in the pipe to ensure the subscription is auto‑cleaned if the component is destroyed mid‑request. It’s not critical for a single HTTP call but would align with the rest of the component’s use of takeUntilDestroyed.
📜 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 c0bc19d and aa010f6.

📒 Files selected for processing (16)
  • src/main/java/de/tum/cit/aet/artemis/nebula/service/LectureTranscriptionService.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/nebula/web/NebulaTranscriptionResource.java (2 hunks)
  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.html (1 hunks)
  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts (4 hunks)
  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.ts (3 hunks)
  • src/main/webapp/app/lecture/manage/lecture-units/edit-attachment-video-unit/edit-attachment-video-unit.component.html (1 hunks)
  • src/main/webapp/app/lecture/manage/lecture-units/lecture-units.component.html (1 hunks)
  • src/main/webapp/app/lecture/manage/services/lecture-transcription.service.spec.ts (1 hunks)
  • src/main/webapp/app/lecture/manage/services/lecture-transcription.service.ts (1 hunks)
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.html (1 hunks)
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts (5 hunks)
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts (6 hunks)
  • src/main/webapp/i18n/de/lectureUnit.json (1 hunks)
  • src/main/webapp/i18n/en/lectureUnit.json (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureTranscriptionServiceIntegrationTest.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java (3 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
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/nebula/service/LectureTranscriptionService.java
  • src/main/java/de/tum/cit/aet/artemis/nebula/web/NebulaTranscriptionResource.java
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/lecture/manage/lecture-units/lecture-units.component.html
  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.html
  • src/main/webapp/app/lecture/manage/lecture-units/edit-attachment-video-unit/edit-attachment-video-unit.component.html
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.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/lecture/manage/services/lecture-transcription.service.spec.ts
  • src/main/webapp/app/lecture/manage/services/lecture-transcription.service.ts
  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts
  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.ts
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts
src/main/webapp/i18n/de/**/*.json

⚙️ CodeRabbit configuration file

German language translations should be informal (dutzen) and should never be formal (sietzen). So the user should always be addressed with "du/dein" and never with "sie/ihr".

Files:

  • src/main/webapp/i18n/de/lectureUnit.json
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/lecture/NebulaTranscriptionResourceIntegrationTest.java
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureTranscriptionServiceIntegrationTest.java
🧠 Learnings (17)
📚 Learning: 2024-11-02T22:57:57.717Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 9656
File: src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.ts:69-71
Timestamp: 2024-11-02T22:57:57.717Z
Learning: In the `src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.ts`, the `isFormValid` computed property intentionally uses a logical OR between `this.statusChanges() === 'VALID'` and `this.fileName()` to mirror the original `isSubmitPossible` getter, ensuring consistent form validation behavior.

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-units/lecture-units.component.html
  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.html
  • src/main/webapp/app/lecture/manage/lecture-units/edit-attachment-video-unit/edit-attachment-video-unit.component.html
  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts
  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.ts
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.html
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts
📚 Learning: 2025-10-10T17:12:35.471Z
Learnt from: marlonnienaber
Repo: ls1intum/Artemis PR: 11436
File: src/main/webapp/app/lecture/manage/lecture-series-create/lecture-series-create.component.ts:356-361
Timestamp: 2025-10-10T17:12:35.471Z
Learning: In the LectureSeriesCreateComponent (src/main/webapp/app/lecture/manage/lecture-series-create/lecture-series-create.component.ts), the rawExistingLectures input contains only persisted Lecture entities from the database, so their id field is guaranteed to be non-null despite the Lecture type having id?: number. The cast to ExistingLecture at line 359 is therefore safe.

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-units/lecture-units.component.html
  • src/main/webapp/app/lecture/manage/lecture-units/edit-attachment-video-unit/edit-attachment-video-unit.component.html
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts
📚 Learning: 2025-04-01T17:19:55.677Z
Learnt from: tobias-lippert
Repo: ls1intum/Artemis PR: 10610
File: src/test/javascript/spec/service/guided-tour.service.spec.ts:193-193
Timestamp: 2025-04-01T17:19:55.677Z
Learning: In the guide tour service tests, the `router.navigateByUrl` mock should remain synchronous (returning boolean) rather than returning a Promise to maintain compatibility with existing test logic that depends on synchronous behavior.

Applied to files:

  • src/main/webapp/app/lecture/manage/services/lecture-transcription.service.spec.ts
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts
📚 Learning: 2024-10-10T11:42:23.069Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9443
File: src/test/javascript/spec/component/hestia/git-diff-report/git-diff-modal.component.spec.ts:55-60
Timestamp: 2024-10-10T11:42:23.069Z
Learning: In `git-diff-report-modal.component.spec.ts`, using `fakeAsync` and `tick` does not work for handling asynchronous operations in the tests; alternative methods are needed.

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts
📚 Learning: 2024-11-07T00:36:51.500Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 9694
File: src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts:29-29
Timestamp: 2024-11-07T00:36:51.500Z
Learning: In the Angular `FormDateTimePickerComponent` in `src/main/webapp/app/shared/date-time-picker/date-time-picker.component.ts`, the `value` model property may sometimes be a `string` because the component is used in multiple places where a `string` is passed. Therefore, changing its type from `any` to a more specific type could cause issues.

Applied to files:

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

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts
📚 Learning: 2025-09-03T11:25:50.530Z
Learnt from: marlonnienaber
Repo: ls1intum/Artemis PR: 11308
File: src/main/webapp/app/core/calendar/shared/util/calendar-util.ts:4-4
Timestamp: 2025-09-03T11:25:50.530Z
Learning: The Artemis project uses a centralized dayjs configuration approach. All dayjs plugins, including isoWeek, are configured globally in `src/main/webapp/app/core/config/dayjs.ts`, so local plugin imports and dayjs.extend() calls in individual files are redundant and should be removed.

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts
📚 Learning: 2024-10-08T15:35:48.767Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9407
File: src/test/javascript/spec/component/shared/monaco-editor/monaco-editor-communication-action.integration.spec.ts:46-46
Timestamp: 2024-10-08T15:35:48.767Z
Learning: In integration tests, it's acceptable to import the actual `MonacoEditorComponent` instead of mocking it.

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts
📚 Learning: 2024-10-08T15:35:52.595Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8597
File: src/main/webapp/app/exercises/programming/shared/build-details/programming-exercise-repository-and-build-plan-details.component.ts:52-59
Timestamp: 2024-10-08T15:35:52.595Z
Learning: When handling errors in Angular components, ensure to integrate with the alert service for consistent error display across the application.

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts
  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts
📚 Learning: 2024-10-13T12:03:02.430Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9463
File: src/test/javascript/spec/component/shared/monaco-editor/monaco-editor.service.spec.ts:50-55
Timestamp: 2024-10-13T12:03:02.430Z
Learning: In `src/test/javascript/spec/component/shared/monaco-editor/monaco-editor.service.spec.ts`, when a function is called multiple times in a test, use `toHaveBeenCalledTimes` and `toHaveBeenNthCalledWith` assertions instead of `toHaveBeenCalledExactlyOnceWith`.

Applied to files:

  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts
📚 Learning: 2025-08-15T02:30:19.063Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11111
File: src/main/webapp/app/core/admin/exam-rooms/exam-rooms.component.ts:148-152
Timestamp: 2025-08-15T02:30:19.063Z
Learning: In Artemis Angular components, the DeleteDialogService uses an EventEmitter-based pattern rather than direct Observable subscription. The correct usage is: 1) Create an EventEmitter<{ [key: string]: boolean }>, 2) Subscribe to the emitter to perform the actual delete operation, 3) Call deleteDialogService.openDeleteDialog() with a configuration object containing the emitter, deleteQuestion translation key, buttonType, actionType, dialogError observable, and other options. The service handles the dialog lifecycle and emits through the provided emitter when the user confirms the deletion.

Applied to files:

  • src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.ts
📚 Learning: 2025-08-11T13:22:05.140Z
Learnt from: Wallenstein61
Repo: ls1intum/Artemis PR: 10989
File: src/test/java/de/tum/cit/aet/artemis/programming/service/sharing/ExerciseSharingResourceImportTest.java:128-131
Timestamp: 2025-08-11T13:22:05.140Z
Learning: In the ExerciseSharingResourceImportTest class in Artemis, mockServer.verify() is not needed in the tearDown method as the test design doesn't require strict verification of all mocked HTTP expectations. The mockServer field is managed differently in this test class.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java
📚 Learning: 2024-10-20T21:59:11.630Z
Learnt from: pzdr7
Repo: ls1intum/Artemis PR: 9505
File: src/main/webapp/app/exercises/programming/shared/code-editor/monaco/code-editor-monaco.component.html:9-9
Timestamp: 2024-10-20T21:59:11.630Z
Learning: In Angular templates within the Artemis project (e.g., `src/main/webapp/app/exercises/programming/shared/code-editor/monaco/code-editor-monaco.component.html`), properties like `selectedFile()`, `readOnlyManualFeedback()`, `highlightDifferences()`, and `course()` are signals. It is appropriate to call these signals directly in the template.

Applied to files:

  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts
📚 Learning: 2025-08-08T22:22:20.043Z
Learnt from: SamuelRoettgermann
Repo: ls1intum/Artemis PR: 11111
File: src/main/webapp/app/core/admin/exam-rooms/exam-rooms.component.ts:70-79
Timestamp: 2025-08-08T22:22:20.043Z
Learning: In the Artemis Angular components (such as `exam-rooms.component.ts`), error handling for data loading failures can be implemented by setting the data signal to `undefined`. The template then automatically displays appropriate error messages through conditional rendering with if/else blocks and translation keys, without requiring explicit error status management in the component logic.

Applied to files:

  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts
📚 Learning: 2024-06-10T19:44:09.116Z
Learnt from: florian-glombik
Repo: ls1intum/Artemis PR: 8451
File: src/main/webapp/app/exercises/programming/shared/lifecycle/programming-exercise-lifecycle.component.html:187-187
Timestamp: 2024-06-10T19:44:09.116Z
Learning: Use `artemisTranslate` for handling translations in Angular templates within the Artemis platform, as per the project-specific requirements.

Applied to files:

  • src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts
🧬 Code graph analysis (4)
src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts (1)
src/test/playwright/support/baseFixtures.ts (1)
  • expect (40-40)
src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts (1)
src/test/javascript/spec/helpers/mocks/service/mock-account.service.ts (1)
  • MockAccountService (8-46)
src/test/java/de/tum/cit/aet/artemis/lecture/LectureTranscriptionServiceIntegrationTest.java (2)
src/test/playwright/support/pageobjects/course/CourseMessagesPage.ts (1)
  • setName (85-89)
src/main/webapp/app/lecture/manage/services/lecture-transcription.service.ts (1)
  • createTranscription (27-36)
src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts (4)
src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.ts (1)
  • Component (114-422)
src/main/webapp/app/lecture/shared/transcript-viewer/transcript-viewer.component.ts (1)
  • Component (11-179)
src/main/webapp/app/lecture/manage/lecture-units/lecture-units.component.ts (1)
  • Component (29-378)
src/main/webapp/app/lecture/shared/models/transcript-segment.model.ts (1)
  • TranscriptSegment (4-9)
🪛 GitHub Check: Junit Results
src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java

[failure] 213-213: cancelNebulaTranscription_notFound()
Junit test cancelNebulaTranscription_notFound() failed java.lang.AssertionError: Status expected:<404> but was:<403>

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (19)
src/main/webapp/i18n/de/lectureUnit.json (1)

190-193: LGTM! German translations follow informal addressing.

The new German translations correctly use informal addressing ("du") as required by the coding guidelines, and the phrasing is natural and consistent with existing entries.

src/main/webapp/i18n/en/lectureUnit.json (1)

190-193: LGTM! English translations are clear and consistent.

The new English translation keys are grammatically correct and provide clear, user-friendly messages for the cancellation flow.

src/main/webapp/app/lecture/manage/services/lecture-transcription.service.spec.ts (1)

84-102: LGTM! Cancellation tests provide good coverage.

The two new test cases properly validate both success and error scenarios for the cancellation flow, checking the HTTP DELETE method, endpoint, and boolean return values.

src/main/webapp/app/lecture/manage/lecture-units/edit-attachment-video-unit/edit-attachment-video-unit.component.html (1)

7-7: LGTM! Lecture unit ID binding is correctly implemented.

The new [lectureUnitId] binding properly passes the attachment video unit's ID to the form component, with appropriate optional chaining to handle undefined values during initialization.

src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.html (1)

168-177: LGTM! Cancel button UI is well-implemented.

The restructured alert provides a clean two-column layout with the cancel button properly positioned. The disabled state binding prevents race conditions, and the danger button styling appropriately signals a destructive action.

src/main/webapp/app/lecture/manage/lecture-units/lecture-units.component.html (1)

45-45: LGTM! Lecture unit ID binding is correctly propagated.

The new binding properly passes the lecture unit ID from the parent component to the form, maintaining consistency with the edit flow and using appropriate optional chaining.

src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.html (1)

45-68: LGTM! Transcription status UI with proper authorization.

The new transcription status block is well-structured with:

  • Clear visual states for PENDING/PROCESSING/FAILED
  • Proper authorization check ensuring only editors can access the cancel button (line 53)
  • Loading state management with isCancelling() to prevent race conditions
  • Appropriate icon usage for different states
src/main/java/de/tum/cit/aet/artemis/nebula/service/LectureTranscriptionService.java (1)

281-281: The code is correct as written—HTTP POST is required by the Nebula API specification.

The integration tests in NebulaTranscriptionResourceIntegrationTest.java (lines 201, 267) confirm that the Nebula cancellation endpoint at /transcribe/cancel/{jobId} expects POST, not DELETE. The code at line 281 correctly uses HttpMethod.POST. While DELETE is a common RESTful convention for cancellation operations, the Nebula API explicitly requires POST, and the current implementation aligns with that specification.

Likely an incorrect or invalid review comment.

src/main/webapp/app/lecture/manage/services/lecture-transcription.service.ts (1)

66-75: cancelTranscription implementation is consistent and clear

The endpoint path, status handling, and error mapping to false align with the existing methods in this service and the new backend DELETE route; no issues from my side here.

src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.spec.ts (2)

9-11: Test DI setup for modal/transcription/alert services looks correct

Mocking NgbModal, LectureTranscriptionService, and AlertService via MockProvider and injecting them in beforeEach matches how the component under test will use these dependencies; no issues here.

Also applies to: 22-23, 29-31, 49-51, 58-60


760-838: Cancellation flow tests comprehensively cover modal outcomes

The four new specs exercise confirm, dismiss, boolean-false, and thrown-error branches, correctly asserting modal usage, service invocation (or lack thereof), alert calls, and transcriptionStatus updates. This gives good confidence in the cancel flow behavior.

src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.spec.ts (2)

2-2: New test wiring for transcription/cancellation dependencies is appropriate

The added mocks (mockLectureTranscriptionService, MockAccountService, MockProvider for modal and alert) and providers for AttachmentVideoUnitService and LectureTranscriptionService are consistent with the component’s dependencies and allow focused testing of the cancel flow.

Also applies to: 14-17, 34-37, 61-62, 64-68, 77-83, 90-91


411-493: AttachmentVideoUnit cancel-transcription specs are well‑structured

The four new tests correctly simulate modal resolve/reject, success/failure/error responses from cancelTranscription, and assert alerts and transcriptionStatus updates accordingly. Behavior mirrors the form component tests and gives solid coverage of the UI cancel flow.

src/main/java/de/tum/cit/aet/artemis/nebula/web/NebulaTranscriptionResource.java (1)

17-24: DELETE endpoint for cancelling transcriptions is aligned with client and service

The new @DeleteMapping path, security annotation, logging, and delegation to lectureTranscriptionService.cancelNebulaTranscription are consistent with the existing start endpoint and the Angular client URL; no issues here.

Also applies to: 72-85

src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java (1)

8-8: Cancel integration tests exercise the main happy/error paths well

The new tests for successful cancel, completed/failed-status bad requests, student forbidden, and Nebula error cover the important behaviors of the DELETE endpoint and validate repository state where relevant; overall structure and mocking strategy look good.

Also applies to: 35-35, 190-209, 217-272

src/test/java/de/tum/cit/aet/artemis/lecture/LectureTranscriptionServiceIntegrationTest.java (2)

219-246: Success-path integration test looks solid

Creating a persisted lecture/unit, mocking the Nebula cancel call with the concrete URL, and asserting the transcription is removed gives good end‑to‑end coverage of the happy path. No issues spotted.


324-349: Nebula error handling test is precise

Mocking nebulaRestTemplate.exchange(..) to throw and asserting a ResponseStatusException with the “Failed to cancel transcription” message validates the wrapping/error translation nicely. This gives good confidence that upstream Nebula failures surface correctly.

src/main/webapp/app/lecture/manage/lecture-units/attachment-video-unit-form/attachment-video-unit-form.component.ts (1)

13-22: New dependencies and state wiring are consistent

Injecting LectureTranscriptionService, NgbModal, and AlertService, adding lectureUnitId as an input, and tracking isCancelling via a signal all fit well with the existing signal‑based design. The early if (!unitId) return; check in the cancel flow ensures you won’t accidentally call the backend without a valid unit id, assuming the template only shows the button when a unit id is actually available.

Also applies to: 128-139

src/main/webapp/app/lecture/overview/course-lectures/attachment-video-unit/attachment-video-unit.component.ts (1)

4-43: Transcription-related imports, DI, and state exposure look well integrated

Bringing in TranscriptionStatus, faTimes, FaIconComponent, and injecting AccountService, AlertService, and NgbModal, plus exposing transcriptionStatus/isCancelling signals and the TranscriptionStatus enum for the template, all line up with the new UI requirements and existing patterns in this module.

Also applies to: 55-57, 63-66, 70-72

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

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report215 ran207 passed3 skipped5 failed1h 21m 50s 648ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/atlas/CompetencyManagement.spec.ts
ts.Competency Management › Creates a competency❌ failure2m 3s 456ms
ts.Prerequisite Management › Creates a prerequisite❌ failure2m 3s 412ms
ts.Prerequisite Management › Prerequisite editing › Edits a prerequisite❌ failure2m 4s 3ms
e2e/exam/test-exam/TestExamStudentExams.spec.ts
ts.Test Exam - student exams › Check exam participants and their submissions › Open the list of exam students❌ failure6m 10s 18ms
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure2m 36s 788ms

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

🧹 Nitpick comments (3)
src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java (3)

192-209: Add test coverage for PROCESSING status.

The success test only covers TranscriptionStatus.PENDING, but according to the PR objectives, cancellation is allowed for both PENDING and PROCESSING statuses. Consider adding a similar test case for PROCESSING to ensure complete coverage of valid cancellation scenarios.

Additionally, line 201 hardcodes the Nebula URL "http://localhost:8080/transcribe/cancel/job-123". If this URL is configurable or might change, consider using anyString() or extracting the base URL from configuration for more maintainable tests.


201-201: Use consistent mock matching patterns.

Line 201 uses eq("http://localhost:8080/transcribe/cancel/job-123") to match the URL, while line 268 uses anyString() for the same parameter. For consistency and maintainability, consider using anyString() in both places unless you specifically need to verify the exact URL construction.

Also applies to: 268-268


190-271: Consider database query count tracking.

As per coding guidelines, integration tests should track database query performance (db_query_count_tests: track_performance). While these tests primarily verify REST endpoint behavior and authorization, consider adding query count assertions for the success path (lines 192-209) to ensure the cancellation operation doesn't inadvertently trigger N+1 queries or excessive database hits.

This is particularly relevant for the findByLectureUnit_Id call at line 207 and any queries triggered by the authorization checks.

As per coding guidelines, database query performance tracking is recommended for integration tests.

📜 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 aa010f6 and 49acbd8.

📒 Files selected for processing (1)
  • src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java (3 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/lecture/NebulaTranscriptionResourceIntegrationTest.java
🧠 Learnings (1)
📚 Learning: 2025-08-11T13:22:05.140Z
Learnt from: Wallenstein61
Repo: ls1intum/Artemis PR: 10989
File: src/test/java/de/tum/cit/aet/artemis/programming/service/sharing/ExerciseSharingResourceImportTest.java:128-131
Timestamp: 2025-08-11T13:22:05.140Z
Learning: In the ExerciseSharingResourceImportTest class in Artemis, mockServer.verify() is not needed in the tearDown method as the test design doesn't require strict verification of all mocked HTTP expectations. The mockServer field is managed differently in this test class.

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Build and Push Docker Image / Build linux/arm64 Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: client-tests
  • GitHub Check: client-style
  • GitHub Check: client-tests-selected
  • GitHub Check: server-style
  • GitHub Check: server-tests
  • GitHub Check: bean-instantiation-check
  • GitHub Check: Analyse
🔇 Additional comments (1)
src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java (1)

8-8: LGTM!

The new imports are necessary for the cancellation test methods.

Also applies to: 34-34

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

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

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report215 ran210 passed3 skipped2 failed1h 23m 19s 527ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exam/test-exam/TestExamStudentExams.spec.ts
ts.Test Exam - student exams › Check exam participants and their submissions › Open the list of exam students❌ failure6m 9s 15ms
ts.Test Exam - student exams › Check exam participants and their submissions › Search for a student in exams❌ failure6m 6s 348ms

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java (4)

34-34: Use imported LectureTranscription consistently

Now that LectureTranscription is imported, you can simplify the earlier declaration at line 119 from

var existingTranscription = new de.tum.cit.aet.artemis.lecture.domain.LectureTranscription();

to

var existingTranscription = new LectureTranscription();

for consistency and to avoid mixing FQNs with imports.


190-209: Successful cancel path is well covered; URL matcher could be less brittle

The test correctly seeds a PENDING transcription, stubs Nebula to return 200, and asserts the record is removed from the repository — this validates the happy path nicely.

Minor optional improvement: hard‑coding the full cancel URL (http://localhost:8080/...) in the stub couples the test to the exact base URL configuration. Matching only on the job id (e.g. via anyString() or a custom matcher that checks endsWith("/transcribe/cancel/job-123")) would make the test more resilient to configuration changes while still asserting the correct job id is used.


225-249: Terminal states (COMPLETED/FAILED) correctly rejected

The two tests for COMPLETED and FAILED transcriptions ensure that cancellation attempts return 400 BAD_REQUEST, which captures the intended “do not cancel finished jobs” behavior.

If you want slightly stronger regression protection, you could additionally assert that the transcription is still present after the DELETE, e.g.:

assertThat(lectureTranscriptionRepository.findByLectureUnit_Id(lectureUnit.getId())).hasSize(1);

to guard against accidental deletion in these error cases.


264-277: Nebula error mapped to 500; consider asserting transcription is retained

The test correctly simulates a RestClientException from Nebula and asserts 500 INTERNAL_SERVER_ERROR, which matches the intended error propagation.

For extra safety, you might also assert that the transcription still exists after the failed cancel attempt to ensure the service never deletes the record when Nebula fails:

assertThat(lectureTranscriptionRepository.findByLectureUnit_Id(lectureUnit.getId())).hasSize(1);

This would firmly pin the “no side effects on upstream failure” contract.

📜 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 49acbd8 and 850586f.

📒 Files selected for processing (1)
  • src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java (3 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/lecture/NebulaTranscriptionResourceIntegrationTest.java
🧠 Learnings (3)
📚 Learning: 2025-08-11T13:22:05.140Z
Learnt from: Wallenstein61
Repo: ls1intum/Artemis PR: 10989
File: src/test/java/de/tum/cit/aet/artemis/programming/service/sharing/ExerciseSharingResourceImportTest.java:128-131
Timestamp: 2025-08-11T13:22:05.140Z
Learning: In the ExerciseSharingResourceImportTest class in Artemis, mockServer.verify() is not needed in the tearDown method as the test design doesn't require strict verification of all mocked HTTP expectations. The mockServer field is managed differently in this test class.

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.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). (10)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Build and Push Docker Image / Build linux/amd64 Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: bean-instantiation-check
  • GitHub Check: client-style
  • GitHub Check: client-tests
  • GitHub Check: server-tests
  • GitHub Check: server-style
  • GitHub Check: client-tests-selected
  • GitHub Check: Analyse
🔇 Additional comments (4)
src/test/java/de/tum/cit/aet/artemis/lecture/NebulaTranscriptionResourceIntegrationTest.java (4)

8-8: Static import for delete() is appropriate

Importing delete from MockMvcRequestBuilders for the new DELETE tests is correct and keeps the test code readable.


211-216: 403 expectation for non‑existent lecture unit matches security semantics

This test now correctly expects 403 FORBIDDEN when the lecture unit id is unknown, which aligns with @EnforceAtLeastEditorInLectureUnit denying access before the controller can check for a transcription.


218-223: Good edge‑case test for valid unit without transcription (404)

This test nicely covers the “lecture unit exists but no transcription record” case and asserts 404 NOT_FOUND, matching the documented service behavior.


251-262: Authorization test for student role is clear and focused

This test cleanly verifies that a USER cannot cancel transcriptions and that the endpoint responds with 403 FORBIDDEN, which is sufficient without extra state assertions.

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report215 ran210 passed3 skipped2 failed1h 16m 7s 180ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exam/test-exam/TestExamParticipation.spec.ts
ts.Test exam participation › Early Hand-in › Using exercise sidebar to navigate within exam❌ failure3m 35s 685ms
ts.Test exam participation › Early Hand-in › Using exercise overview to navigate within exam❌ failure3m 46s 891ms

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

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

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.

Left a comment

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/main/java/de/tum/cit/aet/artemis/nebula/service/LectureTranscriptionService.java (1)

273-296: Align error handling consistency and clean up stale failure tracking on successful cancellation

Two optional improvements:

  • The explicit else branch checking response.getStatusCode().is2xxSuccessful() is inconsistent with startNebulaTranscription, which relies on exceptions. Since nebulaRestTemplate is a custom-qualified bean, verify its error handler configuration; if it uses the default ResponseErrorHandler, non-2xx responses will already throw before reaching the else branch. Consider either removing the explicit status check and relying solely on exception handling (like startNebulaTranscription), or document the custom error handling behavior.

  • On successful cancellation, add failureCountMap.remove(jobId); after deleting the transcription record to prevent stale entries. This keeps in-memory state aligned with the deleted DB record and avoids accumulating entries during polling.

📜 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 850586f and dd094ee.

📒 Files selected for processing (2)
  • src/main/java/de/tum/cit/aet/artemis/nebula/service/LectureTranscriptionService.java (1 hunks)
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureTranscriptionServiceIntegrationTest.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/java/de/tum/cit/aet/artemis/lecture/LectureTranscriptionServiceIntegrationTest.java
🧰 Additional context used
📓 Path-based instructions (1)
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/nebula/service/LectureTranscriptionService.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Build and Push Docker Image / Build linux/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-selected
  • GitHub Check: server-tests
  • GitHub Check: bean-instantiation-check
  • GitHub Check: server-style
  • GitHub Check: client-tests
🔇 Additional comments (1)
src/main/java/de/tum/cit/aet/artemis/nebula/service/LectureTranscriptionService.java (1)

249-297: Cancellation flow and state validation look correct

The lookup, status checks (blocking COMPLETED/FAILED), Nebula cancel call, and conditional deletion on successful 2xx response all align well with the intended semantics and fix the earlier “delete-before-verifying” issue from the previous review. Logging and error mapping to ResponseStatusException are consistent with startNebulaTranscription.

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

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

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

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

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report218 ran213 passed3 skipped2 failed1h 11m 57s 259ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/programming/ProgrammingExerciseParticipation.spec.ts
ts.Programming exercise participation › Programming exercise team participation › Check team participation › Instructor checks the participation❌ failure7s 780ms
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure2m 38s 500ms

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report218 ran213 passed3 skipped2 failed1h 10m 52s 777ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/programming/ProgrammingExerciseParticipation.spec.ts
ts.Programming exercise participation › Programming exercise team participation › Check team participation › Instructor checks the participation❌ failure8s 638ms
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure2m 39s 20ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client Pull requests that update TypeScript code. (Added Automatically!) lecture 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.

3 participants