@@ -74,6 +74,7 @@ void main() {
7474 'type' : 'service_account' ,
7575 'project_id' : 'test-project' ,
7676 'universe_domain' : 'example.com' ,
77+ 'quota_project_id' : 'test-quota' ,
7778 };
7879
7980 test ('from valid individual params' , () {
@@ -82,13 +83,15 @@ void main() {
8283 clientId,
8384 testPrivateKeyString,
8485 projectId: 'test-project' ,
86+ quotaProject: 'test-quota' ,
8587 );
8688 expect (credentials.email, 'email' );
8789 expect (credentials.clientId, clientId);
8890 expect (credentials.privateKey, testPrivateKeyString);
8991 expect (credentials.impersonatedUser, isNull);
9092 expect (credentials.projectId, 'test-project' );
9193 expect (credentials.universeDomain, defaultUniverseDomain);
94+ expect (credentials.quotaProject, 'test-quota' );
9295 });
9396
9497 test ('from valid individual params with user' , () {
@@ -98,13 +101,15 @@ void main() {
98101 testPrivateKeyString,
99102 impersonatedUser: 'x@y.com' ,
100103 projectId: 'test-project' ,
104+ quotaProject: 'test-quota' ,
101105 );
102106 expect (credentials.email, 'email' );
103107 expect (credentials.clientId, clientId);
104108 expect (credentials.privateKey, testPrivateKeyString);
105109 expect (credentials.impersonatedUser, 'x@y.com' );
106110 expect (credentials.projectId, 'test-project' );
107111 expect (credentials.universeDomain, defaultUniverseDomain);
112+ expect (credentials.quotaProject, 'test-quota' );
108113 });
109114
110115 test ('from JSON string' , () {
@@ -118,6 +123,7 @@ void main() {
118123 expect (credentialsFromJson.impersonatedUser, isNull);
119124 expect (credentialsFromJson.projectId, 'test-project' );
120125 expect (credentialsFromJson.universeDomain, 'example.com' );
126+ expect (credentialsFromJson.quotaProject, 'test-quota' );
121127 });
122128
123129 test ('from JSON string with user' , () {
@@ -132,6 +138,7 @@ void main() {
132138 expect (credentialsFromJson.impersonatedUser, 'x@y.com' );
133139 expect (credentialsFromJson.projectId, 'test-project' );
134140 expect (credentialsFromJson.universeDomain, 'example.com' );
141+ expect (credentialsFromJson.quotaProject, 'test-quota' );
135142 });
136143
137144 test ('from JSON map' , () {
@@ -145,6 +152,7 @@ void main() {
145152 expect (credentialsFromJson.impersonatedUser, isNull);
146153 expect (credentialsFromJson.projectId, 'test-project' );
147154 expect (credentialsFromJson.universeDomain, 'example.com' );
155+ expect (credentialsFromJson.quotaProject, 'test-quota' );
148156 });
149157
150158 test ('from JSON map with user' , () {
@@ -159,6 +167,7 @@ void main() {
159167 expect (credentialsFromJson.impersonatedUser, 'x@y.com' );
160168 expect (credentialsFromJson.projectId, 'test-project' );
161169 expect (credentialsFromJson.universeDomain, 'example.com' );
170+ expect (credentialsFromJson.quotaProject, 'test-quota' );
162171 });
163172
164173 test ('sign data' , () {
@@ -336,6 +345,35 @@ void main() {
336345 expect (response.statusCode, 204 );
337346 });
338347
348+ test ('successful request with quotaProject' , () async {
349+ final client = authenticatedClient (
350+ mockClient (
351+ expectAsync1 ((request) async {
352+ expect (request.method, 'POST' );
353+ expect (request.url, url);
354+ expect (request.headers, hasLength (2 ));
355+ expect (
356+ request.headers,
357+ containsPair ('Authorization' , 'Bearer bar' ),
358+ );
359+ expect (
360+ request.headers,
361+ containsPair ('x-goog-user-project' , 'test-quota-project' ),
362+ );
363+
364+ return Response ('' , 204 );
365+ }),
366+ expectClose: false ,
367+ ),
368+ credentials,
369+ quotaProject: 'test-quota-project' ,
370+ );
371+ expect (client.credentials, credentials);
372+
373+ final response = await client.send (RequestImpl ('POST' , url));
374+ expect (response.statusCode, 204 );
375+ });
376+
339377 test ('throws on access denied' , () {
340378 final client = authenticatedClient (
341379 mockClient (
@@ -555,6 +593,54 @@ void main() {
555593 client.close ();
556594 });
557595
596+ test ('clientViaServiceAccount sends quotaProject header' , () async {
597+ final credentials = ServiceAccountCredentials .fromJson ({
598+ 'private_key_id' : '301029' ,
599+ 'private_key' : testPrivateKeyString,
600+ 'client_email' : 'test@test.iam.gserviceaccount.com' ,
601+ 'client_id' : 'myid' ,
602+ 'type' : 'service_account' ,
603+ 'quota_project_id' : 'test-quota-project' ,
604+ });
605+
606+ var callCount = 0 ;
607+ final client = await clientViaServiceAccount (
608+ credentials,
609+ ['https://www.googleapis.com/auth/cloud-platform' ],
610+ baseClient: mockClient (
611+ expectAsync1 ((request) async {
612+ if (callCount == 0 ) {
613+ expect (request.method, 'POST' );
614+ expect (request.url, googleOauth2TokenEndpoint);
615+ callCount++ ;
616+ return Response (
617+ jsonEncode ({
618+ 'access_token' : 'test_token' ,
619+ 'token_type' : 'Bearer' ,
620+ 'expires_in' : 3600 ,
621+ }),
622+ 200 ,
623+ headers: jsonContentType,
624+ );
625+ } else {
626+ expect (
627+ request.headers,
628+ containsPair ('x-goog-user-project' , 'test-quota-project' ),
629+ );
630+ callCount++ ;
631+ return Response ('' , 200 );
632+ }
633+ }, count: 2 ),
634+ expectClose: false ,
635+ ),
636+ );
637+
638+ final response = await client.get (Uri .parse ('http://example.com' ));
639+ expect (response.statusCode, 200 );
640+
641+ client.close ();
642+ });
643+
558644 test ('clientViaMetadataServer returns null credentials' , () async {
559645 final client = await clientViaMetadataServer (
560646 baseClient: mockClient (
0 commit comments