diff --git a/libs/internal/src/fdv2_protocol_handler.cpp b/libs/internal/src/fdv2_protocol_handler.cpp index c07b7fbfe..e45f7d0be 100644 --- a/libs/internal/src/fdv2_protocol_handler.cpp +++ b/libs/internal/src/fdv2_protocol_handler.cpp @@ -73,11 +73,15 @@ FDv2ProtocolHandler::Result FDv2ProtocolHandler::HandleServerIntent( state_ = State::kFull; } else if (code == IntentCode::kTransferChanges) { state_ = State::kPartial; - } else { - // kNone or kUnknown: emit an empty changeset immediately. - state_ = State::kInactive; + } else if (code == IntentCode::kNone) { + state_ = State::kPartial; return data_model::FDv2ChangeSet{ data_model::ChangeSetType::kNone, {}, data_model::Selector{}}; + } else { + // kUnknown: an intent code we don't recognise. + Reset(); + return Error::ProtocolError( + "server-intent had an unrecognized intent code"); } return std::monostate{}; } diff --git a/libs/internal/tests/fdv2_protocol_handler_test.cpp b/libs/internal/tests/fdv2_protocol_handler_test.cpp index 9e0cc8e18..d97caf961 100644 --- a/libs/internal/tests/fdv2_protocol_handler_test.cpp +++ b/libs/internal/tests/fdv2_protocol_handler_test.cpp @@ -62,6 +62,37 @@ TEST(FDv2ProtocolHandlerTest, NoneIntentEmitsEmptyChangeSetImmediately) { EXPECT_FALSE(cs->selector.value.has_value()); } +TEST(FDv2ProtocolHandlerTest, NoneIntentAllowsSubsequentPartialCycle) { + FDv2ProtocolHandler handler; + + handler.HandleEvent("server-intent", MakeServerIntent("none")); + handler.HandleEvent("put-object", + MakePutObject("flag", "my-flag", kFlagJson)); + auto result = handler.HandleEvent("payload-transferred", + MakePayloadTransferred("s1", 1)); + + auto* cs = std::get_if(&result); + ASSERT_NE(cs, nullptr); + EXPECT_EQ(cs->type, data_model::ChangeSetType::kPartial); + ASSERT_EQ(cs->changes.size(), 1u); + EXPECT_EQ(cs->changes[0].key, "my-flag"); +} + +// ============================================================================ +// Unknown intent +// ============================================================================ + +TEST(FDv2ProtocolHandlerTest, UnknownIntentReturnsProtocolError) { + FDv2ProtocolHandler handler; + + auto result = + handler.HandleEvent("server-intent", MakeServerIntent("future-code")); + + auto* err = std::get_if(&result); + ASSERT_NE(err, nullptr); + EXPECT_EQ(err->kind, FDv2ProtocolHandler::Error::Kind::kProtocolError); +} + // ============================================================================ // kTransferFull intent // ============================================================================