11import { createServer , Server } from "http" ;
22import { expect } from "chai" ;
3- import * as nock from "nock" ;
4- import AbortController from "abort-controller" ;
3+ import * as sinon from "sinon" ;
54import * as FormData from "form-data" ;
5+ import * as auth from "./auth" ;
6+ import nock from "./test/helpers/nock" ;
67const proxySetup = require ( "proxy" ) ;
78
89import { Client , CLI_OAUTH_PROJECT_NUMBER } from "./apiv2" ;
910import { FirebaseError } from "./error" ;
1011import { streamToString , stringToStream } from "./utils" ;
1112
1213describe ( "apiv2" , ( ) => {
14+ let authStub : sinon . SinonStub | undefined ;
15+ before ( ( ) => {
16+ if ( typeof ( auth . getAccessToken as any ) . restore !== "function" ) {
17+ authStub = sinon . stub ( auth , "getAccessToken" ) . resolves ( { access_token : "owner" } as any ) ;
18+ }
19+ } ) ;
20+ after ( ( ) => {
21+ if ( authStub ) {
22+ authStub . restore ( ) ;
23+ }
24+ } ) ;
25+
1326 beforeEach ( ( ) => {
1427 // The api module has package variables that we don't want sticking around.
1528 delete require . cache [ require . resolve ( "./apiv2" ) ] ;
@@ -150,17 +163,39 @@ describe("apiv2", () => {
150163 } ) ;
151164
152165 it ( "should resend a multipart body when retrying after a premature close" , async ( ) => {
153- const sentBodies : string [ ] = [ ] ;
154- const capture = ( b : unknown ) : boolean => {
155- sentBodies . push ( typeof b === "string" ? b : JSON . stringify ( b ) ) ;
166+ let body1 : string | undefined ;
167+ let body2 : string | undefined ;
168+
169+ const bodyToStr = ( b : unknown ) : string => {
170+ if ( b instanceof Uint8Array || Buffer . isBuffer ( b ) ) {
171+ return Buffer . from ( b ) . toString ( "utf8" ) ;
172+ } else if ( typeof b === "string" ) {
173+ return b ;
174+ } else {
175+ return JSON . stringify ( b ) ;
176+ }
177+ } ;
178+
179+ const capture1 = ( b : unknown ) : boolean => {
180+ if ( body1 === undefined ) {
181+ body1 = bodyToStr ( b ) ;
182+ }
156183 return true ;
157184 } ;
158- nock ( "https://example.com" ) . post ( "/upload" , capture ) . once ( ) . replyWithError ( {
185+
186+ const capture2 = ( b : unknown ) : boolean => {
187+ if ( body2 === undefined ) {
188+ body2 = bodyToStr ( b ) ;
189+ }
190+ return true ;
191+ } ;
192+
193+ nock ( "https://example.com" ) . post ( "/upload" , capture1 ) . once ( ) . replyWithError ( {
159194 message :
160195 "Invalid response body while trying to fetch https://example.com/upload: Premature close" ,
161196 code : "ERR_STREAM_PREMATURE_CLOSE" ,
162197 } ) ;
163- nock ( "https://example.com" ) . post ( "/upload" , capture ) . once ( ) . reply ( 200 , { ok : true } ) ;
198+ nock ( "https://example.com" ) . post ( "/upload" , capture2 ) . once ( ) . reply ( 200 , { ok : true } ) ;
164199
165200 const form = new FormData ( ) ;
166201 form . append ( "code" , "secret-code-123" ) ;
@@ -177,9 +212,10 @@ describe("apiv2", () => {
177212 } ) ;
178213 expect ( r . status ) . to . equal ( 200 ) ;
179214 // Both the original attempt and the retry must carry the full body.
180- expect ( sentBodies ) . to . have . length ( 2 ) ;
181- expect ( sentBodies [ 0 ] ) . to . contain ( "secret-code-123" ) ;
182- expect ( sentBodies [ 1 ] ) . to . contain ( "secret-code-123" ) ;
215+ expect ( body1 ) . to . not . be . undefined ;
216+ expect ( body2 ) . to . not . be . undefined ;
217+ expect ( body1 ) . to . contain ( "secret-code-123" ) ;
218+ expect ( body2 ) . to . contain ( "secret-code-123" ) ;
183219 expect ( nock . isDone ( ) ) . to . be . true ;
184220 } ) ;
185221
@@ -584,7 +620,11 @@ describe("apiv2", () => {
584620 new Promise ( ( resolve ) => proxyServer . close ( resolve ) ) ,
585621 new Promise ( ( resolve ) => targetServer . close ( resolve ) ) ,
586622 ] ) ;
587- process . env . HTTP_PROXY = oldProxy ;
623+ if ( oldProxy === undefined ) {
624+ delete process . env . HTTP_PROXY ;
625+ } else {
626+ process . env . HTTP_PROXY = oldProxy ;
627+ }
588628 } ) ;
589629
590630 it ( "should be able to make a basic GET request" , async ( ) => {
0 commit comments