test: add regression coverage for list-of-primitive multipart fields - #827
Open
kraenhansen wants to merge 1 commit into
Open
test: add regression coverage for list-of-primitive multipart fields#827kraenhansen wants to merge 1 commit into
kraenhansen wants to merge 1 commit into
Conversation
Locks in the wire format restored by #825: each item of a List[str] multipart field must be sent as its own form field, not as a single json.dumps'd array (which caused invalid_keyword_length on speech_to_text.convert(keyterms=[...]) -- #819). Covers all eight affected fields across speech_to_text, dubbing, music, music.finetunes, studio.projects and audio_native, plus the async path, and asserts object-valued fields stay JSON-encoded. The fields live in Fern-generated raw_client.py files, so these tests are the guardrail against a regeneration silently reverting the fix. Co-authored-by: Kræn Hansen <mail@kraenhansen.dk>
PaulAsjes
approved these changes
Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
tests/test_multipart_list_fields.py, a regression test for the fix in #825 (which resolved #819).The bug: generator
fern-python-sdk4.46.9 began serializing every non-scalar multipart field viajson.dumps(jsonable_encoder(...)).List[str]is not a scalar, sospeech_to_text.convert(keyterms=["a", "b"])was sent as one form field containing["a", "b"]instead of twokeytermsfields, and the API validated the whole JSON array against its per-item limits (invalid_keyword_length).Because the fix lives in Fern-generated
raw_client.pyfiles and is re-applied on every regeneration by Fern Replay, there was nothing stopping a future regeneration from silently reverting it. These tests assert the wire format directly, so a revert fails CI.How it works
Each test builds a real
ElevenLabs/AsyncElevenLabsclient backed by anhttpx.MockTransportwhose handler records the outgoing request and raises a sentinel to abort before a response is needed. The captured multipart body is parsed withemail.message_from_bytesinto an ordered list of(name, value)pairs, and the tests assert on those pairs.Coverage
All eight fields restored by #825, plus the async path and a negative control:
speech_to_text.convert(sync + async)keytermsdubbing.project.createkeytermsmusic.video_to_musictagsmusic.finetunes.createtagsstudio.projects.creategenres,pronunciation_dictionary_locators,voice_settingsaudio_native.createpronunciation_dictionary_locatorstest_speech_to_text_object_fields_stay_json_encodedis the negative control: object-valued fields such asentity_detectionmust keepjson.dumpsencoding, so the tests would also catch an over-broad "fix" that unwrapped those too.Test plan
pytest tests/test_multipart_list_fields.py— 9 passedsrc/elevenlabs/to the commit before fix: send list-of-primitive multipart fields as repeated form fields (#819) #825 makes all 8 wire-format tests fail (the object-field control still passes, as expected)ruff@0.11.5check + format andmypy@1.13.0clean on the new fileNotes
The tests only touch
tests/, which is listed in.fernignore, so nothing here is at risk of being overwritten by regeneration.