@@ -584,6 +584,9 @@ TEST(FDv2StreamingSynchronizerTest, MalformedJsonEventReturnsInterrupted) {
584584 1s);
585585 FDv2StreamingSynchronizerTestPeer::MarkStarted (synchronizer);
586586
587+ auto mock_client = std::make_shared<MockSseClient>();
588+ FDv2StreamingSynchronizerTestPeer::SetSseClient (synchronizer, mock_client);
589+
587590 sse::Event bad_event (" server-intent" , " this is not json" );
588591
589592 // Act: deliver an event whose data field cannot be parsed as JSON.
@@ -592,13 +595,43 @@ TEST(FDv2StreamingSynchronizerTest, MalformedJsonEventReturnsInterrupted) {
592595 auto result = future.WaitForResult (2s);
593596
594597 // Assert: the synchronizer reports Interrupted{kInvalidData} so the
595- // orchestrator knows the stream produced unparseable bytes.
598+ // orchestrator knows the stream produced unparseable bytes, and drives
599+ // the SSE client to restart so the next connection starts clean.
596600 ASSERT_TRUE (result.has_value ());
597601 auto * interrupted =
598602 std::get_if<FDv2SourceResult::Interrupted>(&result->value );
599603 ASSERT_NE (interrupted, nullptr );
600604 EXPECT_EQ (interrupted->error .Kind (),
601605 FDv2SourceResult::ErrorInfo::ErrorKind::kInvalidData );
606+ EXPECT_EQ (mock_client->restart_count_ , 1 );
607+ }
608+
609+ TEST (FDv2StreamingSynchronizerTest,
610+ SchemaViolationServerIntentTriggersRestart) {
611+ auto logger = MakeNullLogger ();
612+ IoContextRunner runner;
613+
614+ FDv2StreamingSynchronizer synchronizer (
615+ runner.context ().get_executor (), logger,
616+ MakeEndpoints (" http://localhost" ), MakeHttpProperties (), std::nullopt ,
617+ 1s);
618+ FDv2StreamingSynchronizerTestPeer::MarkStarted (synchronizer);
619+
620+ auto mock_client = std::make_shared<MockSseClient>();
621+ FDv2StreamingSynchronizerTestPeer::SetSseClient (synchronizer, mock_client);
622+
623+ // Well-formed JSON, but the shape doesn't match a server-intent payload.
624+ sse::Event bad_event (" server-intent" ,
625+ R"( {"data":{"flags":true,"segments":{}}})" );
626+
627+ FDv2StreamingSynchronizerTestPeer::OnEvent (synchronizer, bad_event);
628+ auto future = synchronizer.Next (data_model::Selector{});
629+ auto result = future.WaitForResult (2s);
630+
631+ ASSERT_TRUE (result.has_value ());
632+ ASSERT_NE (std::get_if<FDv2SourceResult::Interrupted>(&result->value ),
633+ nullptr );
634+ EXPECT_EQ (mock_client->restart_count_ , 1 );
602635}
603636
604637TEST (FDv2StreamingSynchronizerTest, TranslationFailureReturnsInterrupted) {
0 commit comments