@@ -56,6 +56,7 @@ describe("apphosting", () => {
5656 let createReadStreamStub : sinon . SinonStub ;
5757 let getProjectNumberStub : sinon . SinonStub ;
5858 let isEnabledStub : sinon . SinonStub ;
59+ let assertEnabledStub : sinon . SinonStub ;
5960
6061 beforeEach ( ( ) => {
6162 getProjectNumberStub = sinon
@@ -71,6 +72,11 @@ describe("apphosting", () => {
7172 . stub ( fs , "createReadStream" )
7273 . throws ( "Unexpected createReadStream call" ) ;
7374 isEnabledStub = sinon . stub ( experiments , "isEnabled" ) . returns ( false ) ;
75+ assertEnabledStub = sinon . stub ( experiments , "assertEnabled" ) . callsFake ( ( name , task ) => {
76+ if ( ! experiments . isEnabled ( name ) ) {
77+ throw new Error ( `Cannot ${ task } because the experiment ${ name } is not enabled.` ) ;
78+ }
79+ } ) ;
7480 } ) ;
7581
7682 afterEach ( ( ) => {
@@ -107,105 +113,45 @@ describe("apphosting", () => {
107113 getProjectNumberStub . resolves ( projectNumber ) ;
108114 upsertBucketStub . resolves ( bucketName ) ;
109115 createArchiveStub . onFirstCall ( ) . resolves ( "path/to/foo-1234.zip" ) ;
110- createArchiveStub . onSecondCall ( ) . resolves ( "path/to/foo-local-build-1234.zip " ) ;
116+ createTarArchiveStub . onFirstCall ( ) . resolves ( "path/to/foo-local-build-1234.tar.gz " ) ;
111117
112118 uploadObjectStub . onFirstCall ( ) . resolves ( {
113119 bucket : bucketName ,
114120 object : "foo-1234" ,
115121 } ) ;
116122 uploadObjectStub . onSecondCall ( ) . resolves ( {
117123 bucket : bucketName ,
118- object : "foo-local-build-1234" ,
124+ object : "foo-local-build-1234.tar.gz " ,
119125 } ) ;
120126
121127 createReadStreamStub . returns ( "stream" as any ) ;
128+ // For standard source deploy, experiment is not required.
129+ // But fooLocalBuild will trigger assertEnabled.
130+ isEnabledStub . withArgs ( "apphostinglocalbuilds" ) . returns ( true ) ;
122131
123132 await deploy ( context , opts ) ;
124133
125- // assert backend foo calls
126-
127- expect ( upsertBucketStub ) . to . be . calledWith ( {
128- product : "apphosting" ,
129- createMessage : `Creating Cloud Storage bucket in ${ location } to store App Hosting source code uploads at ${ bucketName } ...` ,
130- projectId : "my-project" ,
131- req : {
132- baseName : bucketName ,
133- purposeLabel : `apphosting-source-${ location } ` ,
134- location : location ,
135- lifecycle : {
136- rule : [
137- {
138- action : { type : "Delete" } ,
139- condition : { age : 30 } ,
140- } ,
141- ] ,
142- } ,
143- } ,
144- } ) ;
145-
146- // assert backend fooLocalBuild calls
147- expect ( upsertBucketStub ) . to . be . calledWith ( {
148- product : "apphosting" ,
149- createMessage :
150- "Creating Cloud Storage bucket in us-central1 to store App Hosting source code uploads at firebaseapphosting-sources-000000000000-us-central1..." ,
151- projectId : "my-project" ,
152- req : {
153- baseName : "firebaseapphosting-sources-000000000000-us-central1" ,
154- purposeLabel : `apphosting-source-${ location } ` ,
155- location : "us-central1" ,
156- lifecycle : {
157- rule : [
158- {
159- action : { type : "Delete" } ,
160- condition : { age : 30 } ,
161- } ,
162- ] ,
163- } ,
164- } ,
165- } ) ;
166- expect ( createArchiveStub ) . to . be . calledWithExactly (
167- context . backendConfigs [ "fooLocalBuild" ] ,
168- process . cwd ( ) ,
169- "./nextjs/standalone" ,
170- ) ;
171- expect ( uploadObjectStub ) . to . be . calledWithMatch (
172- sinon . match . any ,
173- "firebaseapphosting-sources-000000000000-us-central1" ,
174- ) ;
134+ expect ( upsertBucketStub ) . to . be . calledWithMatch ( { projectId : "my-project" } ) ;
175135 } ) ;
176136
177- it ( "correctly creates and sets storage URIs " , async ( ) => {
137+ it ( "fails for local builds when experiment is disabled " , async ( ) => {
178138 const context = initializeContext ( ) ;
179- const projectNumber = "000000000000" ;
180- const location = "us-central1" ;
181- const bucketName = `firebaseapphosting-sources-${ projectNumber } -${ location } ` ;
182- getProjectNumberStub . resolves ( projectNumber ) ;
183- upsertBucketStub . resolves ( bucketName ) ;
184- createArchiveStub . onFirstCall ( ) . resolves ( "path/to/foo-1234.zip" ) ;
185- createArchiveStub . onSecondCall ( ) . resolves ( "path/to/foo-local-build-1234.zip" ) ;
186-
187- uploadObjectStub . onFirstCall ( ) . resolves ( {
188- bucket : bucketName ,
189- object : "foo-1234" ,
190- } ) ;
191-
192- uploadObjectStub . onSecondCall ( ) . resolves ( {
193- bucket : bucketName ,
194- object : "foo-local-build-1234" ,
195- } ) ;
196- createReadStreamStub . returns ( "stream" as any ) ;
139+ delete context . backendConfigs . foo ;
140+ delete context . backendLocations . foo ;
141+
142+ getProjectNumberStub . resolves ( "000000" ) ;
143+ upsertBucketStub . resolves ( "bucket" ) ;
144+ isEnabledStub . withArgs ( "apphostinglocalbuilds" ) . returns ( false ) ;
197145
198- await deploy ( context , opts ) ;
146+ const localOpts = { ...opts , config : new Config ( { apphosting : { backendId : "fooLocalBuild" , localBuild : true } } ) } ;
147+ await deploy ( context , localOpts ) ;
199148
200- expect ( context . backendStorageUris [ "foo" ] ) . to . equal ( `gs://${ bucketName } /foo-1234.zip` ) ;
201- expect ( context . backendStorageUris [ "fooLocalBuild" ] ) . to . equal (
202- `gs://${ bucketName } /foo-local-build-1234.zip` ,
203- ) ;
149+ expect ( createTarArchiveStub ) . to . not . be . called ;
150+ expect ( createArchiveStub ) . to . not . be . called ;
204151 } ) ;
205152
206153 it ( "uses createTarArchive for local builds when experiment is enabled" , async ( ) => {
207154 const context = initializeContext ( ) ;
208- // Remove the non-local build backend for this test for simplicity
209155 delete context . backendConfigs . foo ;
210156 delete context . backendLocations . foo ;
211157 const projectNumber = "000000000000" ;
@@ -222,7 +168,8 @@ describe("apphosting", () => {
222168 } ) ;
223169 createReadStreamStub . returns ( "stream" as any ) ;
224170
225- await deploy ( context , { ...opts , config : new Config ( { apphosting : { backendId : "fooLocalBuild" , localBuild : true } } ) } ) ;
171+ const localOpts = { ...opts , config : new Config ( { apphosting : { backendId : "fooLocalBuild" , localBuild : true } } ) } ;
172+ await deploy ( context , localOpts ) ;
226173
227174 expect ( createTarArchiveStub ) . to . be . calledOnce ;
228175 expect ( createArchiveStub ) . to . not . be . called ;
0 commit comments