From 2ec5863df502bf5bd8065aa3877dd8b3fb46a82f Mon Sep 17 00:00:00 2001 From: Pavan Kumar Date: Tue, 26 May 2026 17:41:56 +0530 Subject: [PATCH] test: align test assertions with spec-canonical body shape PR #182 made add_analysis/add_attachment coerce dict/list bodies to JSON-encoded strings (forcing encoding=json). Three test files still asserted the old in-memory dict shape and broke CI on main: - test_encoding: rewrote the two pytest.raises blocks that expected dict/list bodies to raise; new code intentionally coerces. Replaced with assertions on the new shape, plus new raises for genuinely invalid input (bad JSON string, bad base64 string). - test_get_transcription: switched to Vcon.decoded_body(transcript) before drilling into body["text"], since body is now a JSON string. - TestCheckAndTagMetrics (3 tests): overriding analysis[0]["body"] with a plain string while leaving encoding=json caused with_decoded_body to crash on json.loads("Hello world"); the link's outer try/except swallowed the error and no metric was recorded. Also override encoding to "none" alongside the body override. --- common/tests/test_encoding.py | 37 ++++++++++++++++--- .../links/groq_whisper/test_groq_whisper.py | 4 +- conserver/tests/test_link_metrics.py | 3 ++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/common/tests/test_encoding.py b/common/tests/test_encoding.py index 710cfcd..6161978 100644 --- a/common/tests/test_encoding.py +++ b/common/tests/test_encoding.py @@ -10,18 +10,45 @@ def test_encoding(): print("test_vcon:", _vcon) test_vcon = vcon.Vcon(_vcon) + # Spec (draft-ietf-vcon-vcon-core-02 §2.3.2): body is always a String. A + # dict/list passed in for convenience is JSON-encoded at the boundary and + # the encoding is forced to "json". + test_vcon.add_attachment( + type="test_encoding_dict_coerced", + body={"key": "value"}, + encoding="json", + ) + assert test_vcon.find_attachment_by_purpose("test_encoding_dict_coerced") == { + "type": "test_encoding_dict_coerced", + "body": json.dumps({"key": "value"}), + "encoding": "json", + } + + test_vcon.add_attachment( + type="test_encoding_list_coerced", + body=["key", "value"], + encoding="base64url", + ) + assert test_vcon.find_attachment_by_purpose("test_encoding_list_coerced") == { + "type": "test_encoding_list_coerced", + "body": json.dumps(["key", "value"]), + "encoding": "json", + } + + # Invalid JSON string with encoding=json still raises. with pytest.raises(Exception): test_vcon.add_attachment( - type="test_encoding", - body={"key": "value"}, + type="test_encoding_bad_json", + body="not-valid-json", encoding="json", ) + # Invalid base64url string with encoding=base64url still raises. with pytest.raises(Exception): test_vcon.add_attachment( - type= "test_encoding", - body=["key", "value"], - encoding= "base64url", + type="test_encoding_bad_b64", + body="not valid base64!!!", + encoding="base64url", ) test_vcon.add_attachment( diff --git a/conserver/links/groq_whisper/test_groq_whisper.py b/conserver/links/groq_whisper/test_groq_whisper.py index 3b91cb0..9f17c94 100644 --- a/conserver/links/groq_whisper/test_groq_whisper.py +++ b/conserver/links/groq_whisper/test_groq_whisper.py @@ -435,7 +435,9 @@ def test_get_transcription(sample_vcon_with_existing_transcript): assert transcript is not None assert transcript["type"] == "transcript" assert transcript["dialog"] == 0 - assert transcript["body"]["text"] == "Existing transcript" + # add_analysis JSON-encodes a dict body at the boundary per spec + # (draft-ietf-vcon-vcon-core-02 §2.3.2), so decode before drilling in. + assert Vcon.decoded_body(transcript)["text"] == "Existing transcript" # Check non-existent transcription transcript = get_transcription(sample_vcon_with_existing_transcript, 1) # No dialog at index 1 diff --git a/conserver/tests/test_link_metrics.py b/conserver/tests/test_link_metrics.py index 334ebe3..8f5b5b4 100644 --- a/conserver/tests/test_link_metrics.py +++ b/conserver/tests/test_link_metrics.py @@ -431,6 +431,7 @@ def _run(self, vcon, applies=True, side_effect=None): def test_tag_applied_increments_counter(self, metric_reader): vcon = make_transcript_vcon() vcon.analysis[0]["body"] = "Hello world" + vcon.analysis[0]["encoding"] = "none" self._run(vcon, applies=True) metrics = extract_metrics(metric_reader) assert_metric_has_attrs(metrics, "conserver.link.openai.tags_applied", @@ -441,6 +442,7 @@ def test_tag_applied_increments_counter(self, metric_reader): def test_success_records_evaluation_time(self, metric_reader): vcon = make_transcript_vcon() vcon.analysis[0]["body"] = "Hello world" + vcon.analysis[0]["encoding"] = "none" self._run(vcon, applies=True) metrics = extract_metrics(metric_reader) assert_metric_has_attrs(metrics, "conserver.link.openai.evaluation_time", @@ -450,6 +452,7 @@ def test_success_records_evaluation_time(self, metric_reader): def test_failure_increments_counter(self, metric_reader): vcon = make_transcript_vcon() vcon.analysis[0]["body"] = "Hello world" + vcon.analysis[0]["encoding"] = "none" self._run(vcon, side_effect=Exception("OpenAI error")) metrics = extract_metrics(metric_reader) assert_metric_has_attrs(metrics, "conserver.link.openai.evaluation_failures",