@@ -463,7 +463,8 @@ TEST_F(MoqtMessageSpecificTest, ThreePartObject) {
463463 webtransport::test::InMemoryStream stream (/* stream_id=*/ 0 );
464464 MoqtParserTestVisitor data_visitor;
465465 MoqtDataParser parser (&stream, &data_visitor);
466- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (1 , 1 , true , false );
466+ MoqtDataStreamType type =
467+ MoqtDataStreamType::Subgroup (1 , 1 , true , false , true );
467468 auto message = std::make_unique<StreamHeaderSubgroupMessage>(type);
468469 EXPECT_TRUE (message->SetPayloadLength (14 ));
469470 message->set_wire_image_size (message->total_message_size () - 11 );
@@ -499,7 +500,8 @@ TEST_F(MoqtMessageSpecificTest, ThreePartObjectFirstIncomplete) {
499500 webtransport::test::InMemoryStream stream (/* stream_id=*/ 0 );
500501 MoqtParserTestVisitor data_visitor;
501502 MoqtDataParser parser (&stream, &data_visitor);
502- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (2 , 1 , false , false );
503+ MoqtDataStreamType type =
504+ MoqtDataStreamType::Subgroup (2 , 1 , false , false , true );
503505 auto message = std::make_unique<StreamHeaderSubgroupMessage>(type);
504506 EXPECT_TRUE (message->SetPayloadLength (payload_length));
505507
@@ -533,7 +535,8 @@ TEST_F(MoqtMessageSpecificTest, ObjectSplitInExtension) {
533535 webtransport::test::InMemoryStream stream (/* stream_id=*/ 0 );
534536 MoqtParserTestVisitor data_visitor;
535537 MoqtDataParser parser (&stream, &data_visitor);
536- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (2 , 1 , false , false );
538+ MoqtDataStreamType type =
539+ MoqtDataStreamType::Subgroup (2 , 1 , false , false , true );
537540 auto message = std::make_unique<StreamHeaderSubgroupMessage>(type);
538541
539542 // first part
@@ -557,7 +560,8 @@ TEST_F(MoqtMessageSpecificTest, StreamHeaderSubgroupFollowOn) {
557560 MoqtParserTestVisitor data_visitor;
558561 MoqtDataParser parser (&stream, &data_visitor);
559562 // first part
560- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (0 , 1 , false , false );
563+ MoqtDataStreamType type =
564+ MoqtDataStreamType::Subgroup (0 , 1 , false , false , true );
561565 auto message1 = std::make_unique<StreamHeaderSubgroupMessage>(type);
562566 stream.Receive (message1->PacketSample (), false );
563567 parser.ReadAllData ();
@@ -583,7 +587,8 @@ TEST_F(MoqtMessageSpecificTest, StreamHeaderSubgroupFollowOnExpandedVarInts) {
583587 MoqtParserTestVisitor data_visitor;
584588 MoqtDataParser parser (&stream, &data_visitor);
585589 // first part
586- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (0 , 1 , false , false );
590+ MoqtDataStreamType type =
591+ MoqtDataStreamType::Subgroup (0 , 1 , false , false , true );
587592 auto message1 = std::make_unique<StreamHeaderSubgroupMessage>(type);
588593 message1->ExpandVarints ();
589594 stream.Receive (message1->PacketSample (), false );
@@ -954,7 +959,8 @@ TEST_F(MoqtMessageSpecificTest, FinMidDataPayload) {
954959 webtransport::test::InMemoryStream stream (/* stream_id=*/ 0 );
955960 MoqtParserTestVisitor data_visitor;
956961 MoqtDataParser parser (&stream, &data_visitor);
957- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (0 , 1 , true , false );
962+ MoqtDataStreamType type =
963+ MoqtDataStreamType::Subgroup (0 , 1 , true , false , true );
958964 auto message = std::make_unique<StreamHeaderSubgroupMessage>(type);
959965 stream.Receive (
960966 message->PacketSample ().substr (0 , message->total_message_size () - 1 ),
@@ -972,7 +978,8 @@ TEST_F(MoqtMessageSpecificTest, FinMidExtension) {
972978 webtransport::test::InMemoryStream stream (/* stream_id=*/ 0 );
973979 MoqtParserTestVisitor data_visitor;
974980 MoqtDataParser parser (&stream, &data_visitor);
975- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (0 , 1 , false , false );
981+ MoqtDataStreamType type =
982+ MoqtDataStreamType::Subgroup (0 , 1 , false , false , true );
976983 auto message = std::make_unique<StreamHeaderSubgroupMessage>(type);
977984 // Read up to the extension body and then FIN.
978985 stream.Receive (message->PacketSample ().substr (0 , 7 ), true );
@@ -989,7 +996,8 @@ TEST_F(MoqtMessageSpecificTest, PartialPayloadThenFin) {
989996 webtransport::test::InMemoryStream stream (/* stream_id=*/ 0 );
990997 MoqtParserTestVisitor data_visitor;
991998 MoqtDataParser parser (&stream, &data_visitor);
992- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (1 , 1 , false , false );
999+ MoqtDataStreamType type =
1000+ MoqtDataStreamType::Subgroup (1 , 1 , false , false , true );
9931001 auto message = std::make_unique<StreamHeaderSubgroupMessage>(type);
9941002 stream.Receive (
9951003 message->PacketSample ().substr (0 , message->total_message_size () - 1 ),
@@ -1600,7 +1608,8 @@ class MoqtDataParserStateMachineTest : public quic::test::QuicTest {
16001608};
16011609
16021610TEST_F (MoqtDataParserStateMachineTest, ReadAll) {
1603- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (0 , 1 , false , false );
1611+ MoqtDataStreamType type =
1612+ MoqtDataStreamType::Subgroup (0 , 1 , false , false , true );
16041613 stream_.Receive (StreamHeaderSubgroupMessage (type).PacketSample ());
16051614 stream_.Receive (StreamMiddlerSubgroupMessage (type).PacketSample ());
16061615 parser_.ReadAllData ();
@@ -1614,7 +1623,8 @@ TEST_F(MoqtDataParserStateMachineTest, ReadAll) {
16141623}
16151624
16161625TEST_F (MoqtDataParserStateMachineTest, ReadObjects) {
1617- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (0 , 1 , true , false );
1626+ MoqtDataStreamType type =
1627+ MoqtDataStreamType::Subgroup (0 , 1 , true , false , true );
16181628 stream_.Receive (StreamHeaderSubgroupMessage (type).PacketSample ());
16191629 stream_.Receive (StreamMiddlerSubgroupMessage (type).PacketSample (),
16201630 /* fin=*/ true );
@@ -1629,7 +1639,8 @@ TEST_F(MoqtDataParserStateMachineTest, ReadObjects) {
16291639}
16301640
16311641TEST_F (MoqtDataParserStateMachineTest, ReadTypeThenObjects) {
1632- MoqtDataStreamType type = MoqtDataStreamType::Subgroup (1 , 1 , false , false );
1642+ MoqtDataStreamType type =
1643+ MoqtDataStreamType::Subgroup (1 , 1 , false , false , true );
16331644 stream_.Receive (StreamHeaderSubgroupMessage (type).PacketSample ());
16341645 stream_.Receive (StreamMiddlerSubgroupMessage (type).PacketSample (),
16351646 /* fin=*/ true );
@@ -1742,7 +1753,8 @@ TEST_F(MoqtDataParserStateMachineTest, IgnoresEndRangeIndicators) {
17421753
17431754TEST_F (MoqtDataParserStateMachineTest, IntegerOverflowObjectId) {
17441755 MoqtDataStreamType type = MoqtDataStreamType::Subgroup (
1745- 0 , 1 , /* no_extension_headers=*/ true , /* default_priority=*/ false );
1756+ 0 , 1 , /* no_extension_headers=*/ true , /* default_priority=*/ false ,
1757+ /* has_first_object=*/ true );
17461758 stream_.Receive (StreamHeaderSubgroupMessage (type).PacketSample ());
17471759 char buffer[32 ];
17481760 quic::QuicDataWriter writer (sizeof (buffer), buffer);
@@ -1757,4 +1769,53 @@ TEST_F(MoqtDataParserStateMachineTest, IntegerOverflowObjectId) {
17571769 " Integer overflow when parsing object ID" );
17581770}
17591771
1772+ TEST_F (MoqtDataParserStateMachineTest, SubgroupHasFirstObjectTrue) {
1773+ MoqtDataStreamType type = MoqtDataStreamType::Subgroup (
1774+ 0 , 1 , /* no_extension_headers=*/ true , /* default_priority=*/ false ,
1775+ /* has_first_object=*/ true );
1776+ stream_.Receive (StreamHeaderSubgroupMessage (type).PacketSample ());
1777+ stream_.Receive (StreamMiddlerSubgroupMessage (type).PacketSample (),
1778+ /* fin=*/ true );
1779+ parser_.ReadAtMostOneObject ();
1780+ ASSERT_EQ (visitor_.messages_received (), 1 );
1781+ ASSERT_TRUE (visitor_.last_message ().has_value ());
1782+ EXPECT_EQ (visitor_.last_message ()->first_object_in_subgroup , true );
1783+ parser_.ReadAtMostOneObject ();
1784+ ASSERT_EQ (visitor_.messages_received (), 2 );
1785+ ASSERT_TRUE (visitor_.last_message ().has_value ());
1786+ EXPECT_EQ (visitor_.last_message ()->first_object_in_subgroup , false );
1787+ EXPECT_EQ (visitor_.parsing_error (), std::nullopt );
1788+ EXPECT_TRUE (visitor_.fin_received ());
1789+ }
1790+
1791+ TEST_F (MoqtDataParserStateMachineTest, SubgroupHasFirstObjectFalse) {
1792+ MoqtDataStreamType type = MoqtDataStreamType::Subgroup (
1793+ 0 , 1 , /* no_extension_headers=*/ true , /* default_priority=*/ false ,
1794+ /* has_first_object=*/ false );
1795+ stream_.Receive (StreamHeaderSubgroupMessage (type).PacketSample ());
1796+ stream_.Receive (StreamMiddlerSubgroupMessage (type).PacketSample (),
1797+ /* fin=*/ true );
1798+ parser_.ReadAtMostOneObject ();
1799+ ASSERT_EQ (visitor_.messages_received (), 1 );
1800+ ASSERT_TRUE (visitor_.last_message ().has_value ());
1801+ EXPECT_EQ (visitor_.last_message ()->first_object_in_subgroup , false );
1802+ parser_.ReadAtMostOneObject ();
1803+ ASSERT_EQ (visitor_.messages_received (), 2 );
1804+ ASSERT_TRUE (visitor_.last_message ().has_value ());
1805+ EXPECT_EQ (visitor_.last_message ()->first_object_in_subgroup , false );
1806+ EXPECT_EQ (visitor_.parsing_error (), std::nullopt );
1807+ EXPECT_TRUE (visitor_.fin_received ());
1808+ }
1809+
1810+ TEST_F (MoqtDataParserStateMachineTest, FetchFirstObjectMissing) {
1811+ StreamHeaderFetchMessage header;
1812+ stream_.Receive (header.PacketSample ());
1813+ parser_.ReadStreamType ();
1814+ ASSERT_EQ (visitor_.messages_received (), 0 );
1815+ parser_.ReadAtMostOneObject ();
1816+ ASSERT_EQ (visitor_.messages_received (), 1 );
1817+ ASSERT_TRUE (visitor_.last_message ().has_value ());
1818+ EXPECT_FALSE (visitor_.last_message ()->first_object_in_subgroup .has_value ());
1819+ }
1820+
17601821} // namespace moqt::test
0 commit comments