Skip to content

fix: apply per-field Content-Type in multipart/form-data serialization#7863

Open
dfcz1314 wants to merge 5 commits intousebruno:mainfrom
dfcz1314:fix/multipart-per-field-content-type
Open

fix: apply per-field Content-Type in multipart/form-data serialization#7863
dfcz1314 wants to merge 5 commits intousebruno:mainfrom
dfcz1314:fix/multipart-per-field-content-type

Conversation

@dfcz1314
Copy link
Copy Markdown

@dfcz1314 dfcz1314 commented Apr 27, 2026

Problem

When using body:multipart-form with a text field that has contentType set (e.g. application/json; charset=utf-8), the per-field Content-Type header is missing from the actual multipart body sent
to the server.

Servers that inspect individual part headers to determine the encoding of that field (common in APIs
that accept JSON in a multipart field alongside binary files) will fail to parse the field and return
errors.

Actual part in the sent body:
Content-Disposition: form-data; name="message"

{"key":"value"}

Expected part in the sent body:
Content-Disposition: form-data; name="message"
Content-Type: application/json; charset=utf-8

{"key":"value"}

Root Cause

In both bruno-cli and bruno-electron prepare-request.js, the filtered multipartForm params
array was passed directly to axiosRequest.data. axios/form-data does not read the contentType
property from plain param objects when serializing, so per-part Content-Type headers are never
emitted.

Fix

Build a FormData instance explicitly and use form.append(name, value, { contentType }) for each
field. form-data (already a dependency at 4.0.4) supports per-part content type via the third
options argument. File fields preserve the existing large-file streaming and filename inference
behavior.

Verification

Verified with a local echo server capturing the raw multipart body:

Before:
Content-Disposition: form-data; name="message"

{"MessageType":4,...}

After:
Content-Disposition: form-data; name="message"
Content-Type: application/json; charset=utf-8

{"MessageType":4,...}

Summary by CodeRabbit

  • New Features
    • Improved multipart form-data uploads: streams large files based on a configurable threshold and supports single/array file fields with per-part filename/Content-Type.
    • Requests now retain original multipart params and collection context for diagnostics.
  • Bug Fixes
    • Correct multipart headers (including boundary) are merged into request headers.
    • Safer file handling with guarded read/stream operations and robust empty-field handling.
  • Tests
    • Added tests validating multipart formatting for files, arrays, and content-type behavior.

When a multipart form field has a contentType set (e.g. application/json;
charset=utf-8), the per-field Content-Type header was missing from the
serialized request body because the params array was passed directly to
axios without building a FormData instance.

Build FormData explicitly so each field's contentType is passed via
form.append(name, value, { contentType }) and emitted in the part header.
File fields preserve large-file streaming and filename inference.

Fixes: multipart requests where servers parse per-part Content-Type headers
       (e.g. APIs expecting the "message" field to be application/json).
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 304adaef-e8e2-4942-9c9a-060645dcb875

📥 Commits

Reviewing files that changed from the base of the PR and between 98e0ba7 and 35edbe8.

📒 Files selected for processing (2)
  • packages/bruno-cli/tests/utils/form-data.spec.js
  • packages/bruno-electron/tests/utils/form-data.spec.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bruno-cli/tests/utils/form-data.spec.js

Walkthrough

Prepare-request handlers (CLI & Electron) now build real multipart FormData via createFormData, merge the FormData headers (including boundary) into axiosRequest.headers, and send the FormData as axiosRequest.data. FormData creation now streams large files based on a configurable threshold and handles arrays and errors robustly.

Changes

Cohort / File(s) Summary
Prepare request (CLI & Electron)
packages/bruno-cli/src/runner/prepare-request.js, packages/bruno-electron/src/ipc/network/prepare-request.js
Switch multipart handling to construct FormData via createFormData(..., streamThreshold), set axiosRequest.data = form, merge form.getHeaders() into axiosRequest.headers (including boundary), and preserve original multipart params on _originalMultipartData / collectionPath.
FormData utilities (CLI & Electron)
packages/bruno-cli/src/utils/form-data.js, packages/bruno-electron/src/utils/form-data.js
createFormData signature adds streamThreshold (default ~20MB); normalize file inputs to arrays, skip falsy paths, choose streaming vs buffering via isLargeFile, append multiple values as separate parts, remove special-case text branch, and wrap file IO in try/catch with console error logging.
Tests (FormData)
packages/bruno-cli/tests/utils/form-data.spec.js, packages/bruno-electron/tests/utils/form-data.spec.js
Add/expand tests verifying multipart formatting: per-part Content-Type when provided, array-valued fields emit multiple parts, file parts include filename, and file-field string paths do not throw (error logged).

Sequence Diagram(s)

sequenceDiagram
    rect rgba(0,128,255,0.5)
    Participant Client
    end
    rect rgba(0,200,83,0.5)
    Participant RequestPreparer
    end
    rect rgba(255,193,7,0.5)
    Participant FileSystem
    end
    rect rgba(156,39,176,0.5)
    Participant FormDataLib
    end
    rect rgba(244,67,54,0.5)
    Participant Axios
    end

    Client->>RequestPreparer: prepare multipart request
    RequestPreparer->>RequestPreparer: filter enabled params
    RequestPreparer->>FileSystem: resolve paths & stat sizes
    alt file is large
        RequestPreparer->>FileSystem: createReadStream(file)
    else small file
        RequestPreparer->>FileSystem: readFileSync(file)
    end
    RequestPreparer->>FormDataLib: append parts (files + fields)
    FormDataLib-->>RequestPreparer: form object + getHeaders()
    RequestPreparer->>Axios: merge headers + axiosRequest.data = form
    Client->>Axios: send request
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

size/M

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • Pragadesh-45
  • bijin-bruno

Poem

Files and fields in tidy rows,
Boundaries set where data flows.
Streams and buffers take the stage,
Multipart parts now turn the page. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing per-field Content-Type headers in multipart form-data serialization.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown
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 (1)
packages/bruno-cli/src/runner/prepare-request.js (1)

405-432: Tiny nit — duplicated multipart logic across CLI and Electron is becoming non-trivial.

This block is now ~25 lines virtually identical to packages/bruno-electron/src/ipc/network/prepare-request.js:475-504. Not a blocker for this PR (per the "rule of three" we're at exactly two callsites), but if we ever touch this a third time, extracting a small helper like buildMultipartForm(enabledParams, { collectionPath, threshold }) into a shared util would be very welcome.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-cli/src/runner/prepare-request.js` around lines 405 - 432,
Extract the multipart form building logic into a shared helper (e.g.,
buildMultipartForm) and replace the duplicated blocks in prepare-request.js with
a call to that helper; the helper should accept enabledParams and an options
object (e.g., { collectionPath, threshold: STREAMING_FILE_SIZE_THRESHOLD }) and
perform the same steps currently done here (filtering enabled params, using
isLargeFile, fs.createReadStream vs fs.readFileSync, setting
filename/contentType opts, appending fields/files to a FormData instance, and
returning { form, headers } so callers can set axiosRequest.data and
Object.assign(axiosRequest.headers, headers)). Ensure the helper uses the
existing symbols isLargeFile and STREAMING_FILE_SIZE_THRESHOLD and preserves
behavior for file vs non-file params and opts merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/bruno-cli/src/runner/prepare-request.js`:
- Around line 409-429: The multipart file-param branch in prepareRequest
currently calls isLargeFile and fs.readFileSync without error handling and
doesn't resolve relative paths against collectionPath, causing crashes and wrong
resolution; update the file-handling block (the each loop that checks param.type
=== 'file') to first resolve filePath relative to collectionPath like the mode
=== 'file' branch does, wrap the isLargeFile/readFileSync/fs.createReadStream
operations in a try/catch, and on error log the failure and skip appending that
file (mirroring the graceful logging/skipping behavior used in the mode ===
'file' branch).

In `@packages/bruno-electron/src/ipc/network/prepare-request.js`:
- Around line 500-503: The code conditionally skips merging multipart headers
when contentTypeDefined is true, causing missing boundary parameters; always
merge form.getHeaders() into axiosRequest.headers before setting
axiosRequest.data so the Content-Type header includes the correct boundary even
if a user-provided Content-Type exists—update the logic around
contentTypeDefined/axiosRequest.headers to Object.assign(axiosRequest.headers,
form.getHeaders()) unconditionally, then set axiosRequest.data = form.
- Around line 482-494: The loop that calls isLargeFile and fs.readFileSync
inside prepareRequest's multipart branch can throw and isn't mirroring the safe
behavior in the mode === 'file' branch: resolve relative filePath against
collectionPath, wrap each file handling (the isLargeFile check,
createReadStream/readFileSync and form.append) in a try/catch, and on error log
the problem and continue (do not throw); use the same logging approach as the
mode === 'file' branch so bad or missing paths (isLargeFile throwing Error("File
... is not a file")) are skipped instead of aborting the whole prepareRequest.
Ensure you reference the same STREAMING_FILE_SIZE_THRESHOLD, isLargeFile,
form.append and collectionPath logic while implementing this change.

---

Nitpick comments:
In `@packages/bruno-cli/src/runner/prepare-request.js`:
- Around line 405-432: Extract the multipart form building logic into a shared
helper (e.g., buildMultipartForm) and replace the duplicated blocks in
prepare-request.js with a call to that helper; the helper should accept
enabledParams and an options object (e.g., { collectionPath, threshold:
STREAMING_FILE_SIZE_THRESHOLD }) and perform the same steps currently done here
(filtering enabled params, using isLargeFile, fs.createReadStream vs
fs.readFileSync, setting filename/contentType opts, appending fields/files to a
FormData instance, and returning { form, headers } so callers can set
axiosRequest.data and Object.assign(axiosRequest.headers, headers)). Ensure the
helper uses the existing symbols isLargeFile and STREAMING_FILE_SIZE_THRESHOLD
and preserves behavior for file vs non-file params and opts merging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4c0c4803-20d6-43a6-b5da-920073813492

📥 Commits

Reviewing files that changed from the base of the PR and between 9361393 and 432d13b.

📒 Files selected for processing (2)
  • packages/bruno-cli/src/runner/prepare-request.js
  • packages/bruno-electron/src/ipc/network/prepare-request.js

Comment thread packages/bruno-cli/src/runner/prepare-request.js Outdated
Comment thread packages/bruno-electron/src/ipc/network/prepare-request.js Outdated
Comment thread packages/bruno-electron/src/ipc/network/prepare-request.js Outdated
…params

- Resolve filePath against collectionPath when not absolute, mirroring
  the mode === 'file' branch behavior in both CLI and Electron
- Wrap isLargeFile/readFileSync/createReadStream in try/catch and log
  errors instead of crashing, so bad or missing paths are skipped
- Always merge form.getHeaders() unconditionally in Electron so the
  Content-Type boundary is present even when contentTypeDefined is true
Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
packages/bruno-electron/src/ipc/network/prepare-request.js (1)

475-509: Consider consolidating multipart construction into a shared helper. 🧰

This block is now a near-duplicate of packages/bruno-cli/src/runner/prepare-request.js (lines 405–439) and overlaps significantly with the existing createFormData in packages/bruno-electron/src/utils/form-data.js (which is missing the streaming threshold + try/catch parity that this PR adds). Extracting a single buildMultipartFormData(params, collectionPath) helper would prevent these three sites from drifting next time someone tweaks streaming, path resolution, or per-part headers.

Not blocking — happy to defer if you'd rather keep the diff tight. As per coding guidelines, "Avoid abstractions unless the exact same code is being used in more than 3 places" — this is right at that threshold.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-electron/src/ipc/network/prepare-request.js` around lines 475
- 509, The multipart form construction in this block duplicates logic in
createFormData and the CLI prepare-request; extract a shared helper function
buildMultipartFormData(params, collectionPath, streamThreshold) that
encapsulates the file path resolution, streaming threshold check (isLargeFile
with STREAMING_FILE_SIZE_THRESHOLD), try/catch around file reads, per-part
contentType/filename opts, and returns { form, headers } (or sets headers via
form.getHeaders()); replace the current inline logic in prepare-request.js and
the CLI prepare-request and update createFormData to call this new helper so all
three sites use the same implementation and parity for streaming and error
handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/bruno-electron/src/ipc/network/prepare-request.js`:
- Around line 475-509: The multipart form construction in this block duplicates
logic in createFormData and the CLI prepare-request; extract a shared helper
function buildMultipartFormData(params, collectionPath, streamThreshold) that
encapsulates the file path resolution, streaming threshold check (isLargeFile
with STREAMING_FILE_SIZE_THRESHOLD), try/catch around file reads, per-part
contentType/filename opts, and returns { form, headers } (or sets headers via
form.getHeaders()); replace the current inline logic in prepare-request.js and
the CLI prepare-request and update createFormData to call this new helper so all
three sites use the same implementation and parity for streaming and error
handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: de10777f-911e-4092-80f2-cea87a899048

📥 Commits

Reviewing files that changed from the base of the PR and between 432d13b and bf9c945.

📒 Files selected for processing (2)
  • packages/bruno-cli/src/runner/prepare-request.js
  • packages/bruno-electron/src/ipc/network/prepare-request.js

…Data helper

Extract shared buildMultipartFormData logic from both prepare-request.js
files into the existing createFormData utility in each package's form-data.js.

Changes per package (cli + electron):
- form-data.js: add optional streamThreshold param, isLargeFile streaming
  decision, try/catch on file reads, and handle single-string file values
  in addition to arrays
- prepare-request.js: replace 30-line inline FormData block with a single
  createFormData(enabledParams, collectionPath, STREAMING_FILE_SIZE_THRESHOLD)
  call, eliminating duplication across CLI, Electron, and the existing
  createFormData sites (axios-instance.js, index.js)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
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.

Caution

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

⚠️ Outside diff range comments (1)
packages/bruno-electron/src/utils/form-data.js (1)

64-104: ⚠️ Potential issue | 🟡 Minor

Update formatMultipartData() to render repeated parts and per-part Content-Type headers.

The formatter is used in request preview (sent to the UI via IPC at network/index.js:859 and 1535). However, createFormData() now appends repeated parts for array values and can include per-part Content-Type headers, while formatMultipartData() still collapses arrays and omits per-part headers. Users will see a preview that doesn't match the actual payload sent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-electron/src/utils/form-data.js` around lines 64 - 104,
formatMultipartData currently collapses array fields and omits per-part
Content-Type, producing a preview that doesn't match createFormData's actual
payload; update formatMultipartData to mirror createFormData's behavior by
rendering repeated parts for array values (i.e., emit one multipart part per
array element rather than joining) and include each part's Content-Type when a
datum.contentType is present, also showing per-file filename/filename options
for file parts so the preview matches the FormData produced by createFormData.
🧹 Nitpick comments (1)
packages/bruno-cli/src/utils/form-data.js (1)

9-49: Add a regression test for per-part Content-Type.

This helper now drives both the initial multipart request path and multipart recreation after retries. Please lock this down with a test that asserts a text field with contentType: 'application/json; charset=utf-8' produces a per-part Content-Type header, so this fix does not regress quietly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-cli/src/utils/form-data.js` around lines 9 - 49, Add a
regression test that calls createFormData with a text field object containing
contentType: 'application/json; charset=utf-8' (use a sample name/value and
collectionPath) and then inspects the generated multipart payload to assert the
per-part header "Content-Type: application/json; charset=utf-8" appears for that
part; locate createFormData in the utils/form-data.js module and exercise it
(use FormData methods like getBuffer()/getBoundary() or getHeaders() to
build/parse the multipart body) and fail the test if the per-part Content-Type
is missing or different so the multipart recreation for retries remains correct.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/bruno-electron/src/utils/form-data.js`:
- Around line 64-104: formatMultipartData currently collapses array fields and
omits per-part Content-Type, producing a preview that doesn't match
createFormData's actual payload; update formatMultipartData to mirror
createFormData's behavior by rendering repeated parts for array values (i.e.,
emit one multipart part per array element rather than joining) and include each
part's Content-Type when a datum.contentType is present, also showing per-file
filename/filename options for file parts so the preview matches the FormData
produced by createFormData.

---

Nitpick comments:
In `@packages/bruno-cli/src/utils/form-data.js`:
- Around line 9-49: Add a regression test that calls createFormData with a text
field object containing contentType: 'application/json; charset=utf-8' (use a
sample name/value and collectionPath) and then inspects the generated multipart
payload to assert the per-part header "Content-Type: application/json;
charset=utf-8" appears for that part; locate createFormData in the
utils/form-data.js module and exercise it (use FormData methods like
getBuffer()/getBoundary() or getHeaders() to build/parse the multipart body) and
fail the test if the per-part Content-Type is missing or different so the
multipart recreation for retries remains correct.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1f287492-852c-41a1-97e3-83c9816cf061

📥 Commits

Reviewing files that changed from the base of the PR and between bf9c945 and 0067c79.

📒 Files selected for processing (4)
  • packages/bruno-cli/src/runner/prepare-request.js
  • packages/bruno-cli/src/utils/form-data.js
  • packages/bruno-electron/src/ipc/network/prepare-request.js
  • packages/bruno-electron/src/utils/form-data.js

@pull-request-size pull-request-size Bot added size/L and removed size/M labels Apr 28, 2026
- formatMultipartData: render each array value as a separate part
  (was incorrectly joining with ', '), include per-part Content-Type
  when datum.contentType is set, and fix duplicate boundary markers
  for file fields — preview now matches the actual multipart payload
  sent by createFormData
- electron prepare-request: preserve _originalMultipartData and
  collectionPath on axiosRequest so the UI preview (parseDataFromRequest)
  and FormData recreation on redirects (axios-instance) continue to work
  now that prepare-request builds FormData directly
- Add form-data.spec.js regression tests to both packages covering
  per-part Content-Type, array expansion, and single-string file paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
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 (1)
packages/bruno-cli/tests/utils/form-data.spec.js (1)

13-13: Use OS-aware temp directory instead of hardcoded /tmp

Hardcoding '/tmp' is not cross-platform-safe. Use os.tmpdir() once and reuse it across tests.

Proposed patch
 const { createFormData } = require('../../src/utils/form-data');
+const os = require('os');
+
+const collectionPath = os.tmpdir();
@@
-    const form = createFormData(data, '/tmp');
+    const form = createFormData(data, collectionPath);
@@
-    const form = createFormData(data, '/tmp');
+    const form = createFormData(data, collectionPath);
@@
-    const form = createFormData(data, '/tmp');
+    const form = createFormData(data, collectionPath);
@@
-      expect(() => createFormData(data, '/tmp')).not.toThrow();
+      expect(() => createFormData(data, collectionPath)).not.toThrow();

As per coding guidelines: "Bruno is a cross-platform Electron desktop app... Use os.tmpdir() instead of hardcoding /tmp."

Also applies to: 20-20, 29-29, 40-40

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-cli/tests/utils/form-data.spec.js` at line 13, Tests in
form-data.spec.js hardcode '/tmp' when calling createFormData (and in other
assertions on lines noted), which is not cross-platform; import Node's os
module, call os.tmpdir() once (e.g., const tmpDir = os.tmpdir()) at the top of
the spec, replace every hardcoded '/tmp' argument and assertion with tmpDir, and
reuse tmpDir across the createFormData(...) calls and related expectations so
the tests work on Windows and other environments.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/bruno-cli/tests/utils/form-data.spec.js`:
- Around line 18-25: The test "omits Content-Type header for text field without
contentType" doesn't assert the absence of a Content-Type header, so add a
negative assertion when using createFormData(data, '/tmp') and form.getBuffer():
verify the serialized buffer contains the field name and value (e.g.,
'name="field"' and 'hello') and also assert it does NOT contain a
'Content-Type:' line for that field; use createFormData and form.getBuffer() as
the reference symbols to locate the test and ensure the negative assertion
checks the raw multipart section for the text field.
- Around line 35-42: The test "handles single-string file value (not wrapped in
array)" currently only asserts createFormData doesn't throw but doesn't verify
fallback logging; update the test to assert that console.error was called when
the file read fails by using the existing jest.spyOn(console, 'error') mock and
replacing expect(...).not.toThrow() with both the no-throw assertion and an
expectation like expect(consoleSpy).toHaveBeenCalled(); keep the mockRestore()
call to restore console.error; target the createFormData invocation and the
consoleSpy variable to implement this strengthened degraded-path assertion.

In `@packages/bruno-electron/tests/utils/form-data.spec.js`:
- Around line 48-53: Update the test for formatMultipartData to assert
conditional emission of per-part Content-Type by creating a mixed payload with
two parts (e.g., one text field that includes contentType and one text field
that does not), call formatMultipartData(boundary), then assert the output
contains the specific Content-Type string for the field that set contentType and
does NOT contain any Content-Type header for the other field; use unique
identifiers (field names like 'messageWithType' and 'messageWithoutType') so
assertions target the correct part.

---

Nitpick comments:
In `@packages/bruno-cli/tests/utils/form-data.spec.js`:
- Line 13: Tests in form-data.spec.js hardcode '/tmp' when calling
createFormData (and in other assertions on lines noted), which is not
cross-platform; import Node's os module, call os.tmpdir() once (e.g., const
tmpDir = os.tmpdir()) at the top of the spec, replace every hardcoded '/tmp'
argument and assertion with tmpDir, and reuse tmpDir across the
createFormData(...) calls and related expectations so the tests work on Windows
and other environments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9484c2bc-e57f-4c9a-8b0a-a9fdd0b0369d

📥 Commits

Reviewing files that changed from the base of the PR and between 0067c79 and 98e0ba7.

📒 Files selected for processing (4)
  • packages/bruno-cli/tests/utils/form-data.spec.js
  • packages/bruno-electron/src/ipc/network/prepare-request.js
  • packages/bruno-electron/src/utils/form-data.js
  • packages/bruno-electron/tests/utils/form-data.spec.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/bruno-electron/src/ipc/network/prepare-request.js
  • packages/bruno-electron/src/utils/form-data.js

Comment thread packages/bruno-cli/tests/utils/form-data.spec.js
Comment thread packages/bruno-cli/tests/utils/form-data.spec.js
Comment thread packages/bruno-electron/tests/utils/form-data.spec.js
- cli form-data.spec.js: replace hardcoded '/tmp' with os.tmpdir() for
  cross-platform safety, add negative Content-Type assertion in the
  'omits Content-Type' test, and assert consoleSpy.toHaveBeenCalled()
  in the degraded-path file test
- electron form-data.spec.js: add mixed-payload test to verify Content-Type
  is emitted only for the field that defines contentType and not globally

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant