@@ -79,6 +79,50 @@ public function testEmitReturnsReceiptDataOnSuccess(): void
7979 self ::assertSame ('<NFS-e>ok</NFS-e> ' , $ receipt ->rawXml );
8080 }
8181
82+ public function testEmitBuildsXmlWithTpAmbBeforeMunicipalityFields (): void
83+ {
84+ $ payload = json_encode ([
85+ 'nNFSe ' => '100 ' ,
86+ 'chaveAcesso ' => 'tpamb-order-ok ' ,
87+ 'dataHoraProcessamento ' => '2026-01-02T10:00:00 ' ,
88+ ], JSON_THROW_ON_ERROR );
89+
90+ self ::$ server ->setResponseOfPath (
91+ '/SefinNacional/nfse ' ,
92+ new Response ($ payload , ['Content-Type ' => 'application/json ' ], 201 )
93+ );
94+
95+ $ holder = new class () {
96+ public string $ capturedXml = '' ;
97+ };
98+
99+ $ capturingSigner = new class ($ holder ) implements XmlSignerInterface {
100+ public function __construct (private object $ holder )
101+ {
102+ }
103+
104+ public function sign (string $ xml , string $ cnpj ): string
105+ {
106+ $ this ->holder ->capturedXml = $ xml ;
107+
108+ return $ xml ;
109+ }
110+ };
111+
112+ $ client = $ this ->makeClient ($ capturingSigner );
113+ $ client ->emit ($ this ->makeDps ());
114+
115+ self ::assertNotSame ('' , $ holder ->capturedXml );
116+
117+ $ normalizedXml = str_replace (["\n" , ' ' ], '' , $ holder ->capturedXml );
118+ $ tpAmbIndex = strpos ($ normalizedXml , '<tpAmb>2</tpAmb> ' );
119+ $ cLocEmiIndex = strpos ($ normalizedXml , '<cLocEmi>3303302</cLocEmi> ' );
120+
121+ self ::assertNotFalse ($ tpAmbIndex );
122+ self ::assertNotFalse ($ cLocEmiIndex );
123+ self ::assertLessThan ($ cLocEmiIndex , $ tpAmbIndex );
124+ }
125+
82126 public function testQueryReturnsReceiptDataOnSuccess (): void
83127 {
84128 $ payload = json_encode ([
0 commit comments