Skip to content

Conversation

@jaycnz
Copy link
Contributor

@jaycnz jaycnz commented Jan 21, 2026

Summary by CodeRabbit

  • New Features

    • Video duration validation on file upload (minimum 1 second)
  • Bug Fixes

    • Unified upload error handling with clearer "Upload Failed!" messages
    • Prevents duplicate upload tasks and improves handling for rejected/invalid files
  • Tests

    • Added comprehensive tests for video duration detection and edge cases
  • Documentation

    • Updated upload helper text and validation messages (format, size, one-file, duration)

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

@jaycnz jaycnz requested a review from edmonday January 21, 2026 01:18
@jaycnz jaycnz self-assigned this Jan 21, 2026
@jaycnz jaycnz added type: fix Iterations on existing features or infrastructure. effort: 3 Bug Interns labels Jan 21, 2026
@linear
Copy link

linear bot commented Jan 21, 2026

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 21, 2026

Walkthrough

Replaces per-error boolean flags with a unified errorType, adds getVideoDuration for client-side duration validation (resolves/rejects via video metadata, tests cover ~0.49/0.5s edge cases), maps error codes to messages, and updates drop/upload UI and tests to use errorType.

Changes

Cohort / File(s) Summary
Video upload component
apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/AddByFile.tsx
Replace multiple boolean error flags with errorType; use getVideoDuration on accepted drop; set general-upload-error or file-duration-too-short on failures; guard duplicate upload task creation; unify rendering and copy around errorType.
Duration validation utility
apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/utils/getVideoDuration/getVideoDuration.ts, .../index.ts
Add getVideoDuration(file: File): Promise<number> that creates a video element, loads metadata, returns duration, revokes object URL; re-export added in index.ts.
Duration utility tests
apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/utils/getVideoDuration/getVideoDuration.spec.tsx
Tests for successful metadata load, error propagation, object URL lifecycle, and edge cases around durations (~0.49 / 0.5s).
Dropzone text test update
apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/AddByFile.spec.tsx
Update assertion to match new longer instructional dropzone copy.
Localization
libs/locales/en/apps-journeys-admin.json
Add/update keys for file-size/type/duplicate/minimum-duration messages; consolidate upload hint text and remove trailing-space duplicates.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant User as User
participant UI as AddByFile Component
participant Dur as getVideoDuration
participant Upload as UploadTaskManager
User->>UI: Drag & drop file
UI->>Dur: createObjectURL + load metadata
Dur-->>UI: resolve(duration) or reject(error)
alt duration >= threshold
UI->>Upload: create upload task (if none)
Upload-->>UI: task accepted / progress
else duration too short or load error
UI-->>User: set errorType -> show message
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • edmonday
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 'fix: custom video upload help and error messages' directly aligns with the main changes in the PR, which refactor video upload error handling, add duration validation, and update error/help messages throughout the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 jaychen/nes-1108-custom-video-upload-help-and-error-message

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.

@nx-cloud
Copy link

nx-cloud bot commented Jan 21, 2026

View your CI Pipeline Execution ↗ for commit 77d36de

Command Status Duration Result
nx run videos-admin-e2e:e2e ✅ Succeeded 7s View ↗
nx run watch-modern-e2e:e2e ✅ Succeeded 4s View ↗
nx run journeys-e2e:e2e ✅ Succeeded 25s View ↗
nx run journeys-admin-e2e:e2e ✅ Succeeded 33s View ↗
nx run resources-e2e:e2e ✅ Succeeded 25s View ↗
nx run watch-e2e:e2e ✅ Succeeded 26s View ↗
nx run player-e2e:e2e ✅ Succeeded 3s View ↗
nx run-many --target=vercel-alias --projects=watch ✅ Succeeded 2s View ↗
Additional runs (20) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2026-01-21 02:39:00 UTC

@github-actions github-actions bot requested a deployment to Preview - journeys-admin January 21, 2026 01:20 Pending
@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 21, 2026 01:25 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin January 21, 2026 01:25 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys January 21, 2026 01:25 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 21, 2026 01:25 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources January 21, 2026 01:25 Inactive
@github-actions
Copy link
Contributor

github-actions bot commented Jan 21, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch-modern ✅ Ready watch-modern preview Wed Jan 21 15:26:48 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 21, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
player ✅ Ready player preview Wed Jan 21 15:26:46 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 21, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys ✅ Ready journeys preview Wed Jan 21 15:27:07 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 21, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
videos-admin ✅ Ready videos-admin preview Wed Jan 21 15:27:05 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 21, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch ✅ Ready watch preview Wed Jan 21 15:27:21 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 21, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys-admin ✅ Ready journeys-admin preview Wed Jan 21 15:27:20 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 21, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
resources ✅ Ready resources preview Wed Jan 21 15:27:17 NZDT 2026

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

🤖 Fix all issues with AI agents
In
`@apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/AddByFile.tsx`:
- Around line 61-70: The duration check in AddByFile.tsx is too permissive:
replace the current conditional that uses "duration && duration < 0.5" with a
strict numeric validation that treats null/NaN/zero as invalid and enforces a
minimum of 1 second; use the value returned from getVideoDuration (refer to the
duration variable and files[0]) and call setErrorType('file-duration-too-short')
when duration is missing, NaN, or less than 1.0 seconds so sub‑1s clips are
rejected reliably.
- Around line 95-99: The onDropRejected handler is assigning
fileRejections[0].errors[0].code (ErrorCode | string) directly to setErrorType
which expects a restricted customErrorCode; add a type guard in onDropRejected
to check whether the dropped error code is one of the allowed customErrorCode
values (e.g., via a whitelist/enum or an isCustomErrorCode function) and call
setErrorType with that value, otherwise call
setErrorType('general-upload-error') as the fallback; update references in the
same function (onDropRejected, FileRejection) to use the guard before setting
state.
🧹 Nitpick comments (1)
apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/utils/getVideoDuration/getVideoDuration.spec.tsx (1)

4-13: Avoid any for the mocked video element.
Use a small typed mock to keep the spec type-safe.

♻️ Suggested typing tweak
 describe('getVideoDuration', () => {
-  let mockVideo: any
+  type MockVideo = Partial<HTMLVideoElement> & {
+    onloadedmetadata: (() => void) | null
+    onerror: (() => void) | null
+  }
+  let mockVideo: MockVideo

As per coding guidelines, define a type instead of any where possible.

@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 21, 2026 01:44 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin January 21, 2026 01:44 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 21, 2026 01:44 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources January 21, 2026 01:44 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys January 21, 2026 01:44 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 21, 2026 02:19 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources January 21, 2026 02:19 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys January 21, 2026 02:19 Inactive
@github-actions github-actions bot requested a deployment to Preview - journeys-admin January 21, 2026 02:19 Pending
@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 21, 2026 02:19 Inactive
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

Caution

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

⚠️ Outside diff range comments (1)
apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/AddByFile.spec.tsx (1)

89-98: Add mock for getVideoDuration to prevent test hangs.

When dropTestVideo() is called in tests (lines 89-98, 188-227), it triggers onDropAccepted which awaits getVideoDuration. In JSDOM, the video element's onloadedmetadata event never fires for File objects, causing the Promise to hang indefinitely and tests to timeout.

Add this mock at the top of the test file with the existing mocks:

🛠️ Add getVideoDuration mock
jest.mock('./utils/getVideoDuration/getVideoDuration', () => ({
  getVideoDuration: jest.fn().mockResolvedValue(5)
}))
♻️ Duplicate comments (2)
apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/AddByFile.tsx (2)

61-70: Duration check is inconsistent with the error message.

The code checks duration < 0.5 but the error message states "Minimum duration is 1 second" (line 128). Additionally, the check duration && duration < 0.5 allows 0 or NaN through since 0 is falsy. This was flagged in a previous review.

🛠️ Proposed fix
     let duration: number | null = null
     try {
       duration = await getVideoDuration(files[0])
     } catch (error) {
       return setErrorType('general-upload-error')
     }
 
-    if (duration && duration < 0.5) {
+    if (duration == null || !Number.isFinite(duration) || duration < 1) {
       return setErrorType('file-duration-too-short')
     }

95-99: Type error: fileRejections[0].errors[0].code is ErrorCode | string, not assignable to customErrorCode.

The as customErrorCode cast is unsafe because react-dropzone's error code can be an arbitrary string. This will cause a TypeScript error (TS2345) as indicated by pipeline failures. Add validation before casting.

🛠️ Proposed fix
   const onDropRejected = async (
     fileRejections: FileRejection[]
   ): Promise<void> => {
-    setErrorType(fileRejections[0].errors[0].code as customErrorCode)
+    const code = fileRejections[0]?.errors[0]?.code
+    const validCodes: string[] = [
+      ErrorCode.FileTooLarge,
+      ErrorCode.FileInvalidType,
+      ErrorCode.TooManyFiles,
+      ErrorCode.FileTooSmall
+    ]
+    if (code != null && validCodes.includes(code)) {
+      setErrorType(code as customErrorCode)
+    } else {
+      setErrorType('general-upload-error')
+    }
   }
🧹 Nitpick comments (2)
apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/AddByFile.tsx (1)

43-48: Type definition should be exported or moved to a shared types file.

The customErrorCode type is defined inside the component function, which limits reusability and makes testing harder. Consider moving it outside the component or to a shared types file.

♻️ Suggested refactor
+type CustomErrorCode =
+  | ErrorCode
+  | 'file-duration-too-short'
+  | 'general-upload-error'
+
 export function AddByFile({ onChange }: AddByFileProps): ReactElement {
   // ...
-  type customErrorCode =
-    | ErrorCode
-    | 'file-duration-too-short'
-    | 'general-upload-error'
-
-  const [errorType, setErrorType] = useState<customErrorCode | null>(null)
+  const [errorType, setErrorType] = useState<CustomErrorCode | null>(null)
apps/journeys-admin/src/components/Editor/Slider/Settings/Drawer/VideoLibrary/VideoFromMux/AddByFile/AddByFile.spec.tsx (1)

155-362: Consider adding tests for duration validation errors.

The implementation adds file-duration-too-short error handling, but there's no test verifying this behavior. Consider adding a test that mocks getVideoDuration to return a value below the threshold.

🧪 Suggested test
it('should show error for video duration too short', async () => {
  const { getVideoDuration } = require('./utils/getVideoDuration/getVideoDuration')
  getVideoDuration.mockResolvedValueOnce(0.4) // Below 0.5s threshold (or 1s if fixed)

  render(
    <TestWrapper>
      <AddByFile onChange={jest.fn()} />
    </TestWrapper>
  )

  await dropTestVideo()

  await waitFor(() => {
    expect(screen.getByText('Upload Failed!')).toBeInTheDocument()
    expect(
      screen.getByText('Video is too short. Minimum duration is 1 second.')
    ).toBeInTheDocument()
  })
})

@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 21, 2026 02:25 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources January 21, 2026 02:25 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys January 21, 2026 02:25 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 21, 2026 02:25 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin January 21, 2026 02:25 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug effort: 3 Interns type: fix Iterations on existing features or infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants