@@ -2,10 +2,12 @@ import * as sinon from "sinon";
22import { expect } from "chai" ;
33
44import * as gcb from "../../../gcp/cloudbuild" ;
5+ import * as rm from "../../../gcp/resourceManager" ;
56import * as prompt from "../../../prompt" ;
67import * as poller from "../../../operation-poller" ;
78import * as repo from "../../../init/features/apphosting/repo" ;
89import * as utils from "../../../utils" ;
10+ import * as srcUtils from "../../../../src/getProjectNumber" ;
911import { FirebaseError } from "../../../error" ;
1012
1113const projectId = "projectId" ;
@@ -53,8 +55,11 @@ describe("composer", () => {
5355 let getConnectionStub : sinon . SinonStub ;
5456 let getRepositoryStub : sinon . SinonStub ;
5557 let createConnectionStub : sinon . SinonStub ;
58+ let serviceAccountHasRolesStub : sinon . SinonStub ;
5659 let createRepositoryStub : sinon . SinonStub ;
5760 let fetchLinkableRepositoriesStub : sinon . SinonStub ;
61+ let getProjectNumberStub : sinon . SinonStub ;
62+ let openInBrowserPopupStub : sinon . SinonStub ;
5863
5964 beforeEach ( ( ) => {
6065 promptOnceStub = sandbox . stub ( prompt , "promptOnce" ) . throws ( "Unexpected promptOnce call" ) ;
@@ -70,13 +75,20 @@ describe("composer", () => {
7075 createConnectionStub = sandbox
7176 . stub ( gcb , "createConnection" )
7277 . throws ( "Unexpected createConnection call" ) ;
78+ serviceAccountHasRolesStub = sandbox . stub ( rm , "serviceAccountHasRoles" ) . resolves ( true ) ;
7379 createRepositoryStub = sandbox
7480 . stub ( gcb , "createRepository" )
7581 . throws ( "Unexpected createRepository call" ) ;
7682 fetchLinkableRepositoriesStub = sandbox
7783 . stub ( gcb , "fetchLinkableRepositories" )
7884 . throws ( "Unexpected fetchLinkableRepositories call" ) ;
7985 sandbox . stub ( utils , "openInBrowser" ) . resolves ( ) ;
86+ openInBrowserPopupStub = sandbox
87+ . stub ( utils , "openInBrowserPopup" )
88+ . throws ( "Unexpected openInBrowserPopup call" ) ;
89+ getProjectNumberStub = sandbox
90+ . stub ( srcUtils , "getProjectNumber" )
91+ . throws ( "Unexpected getProjectNumber call" ) ;
8092 } ) ;
8193
8294 afterEach ( ( ) => {
@@ -139,6 +151,24 @@ describe("composer", () => {
139151 expect ( createConnectionStub ) . to . be . calledWith ( projectId , location , connectionId ) ;
140152 } ) ;
141153
154+ it ( "checks if secret manager admin role is granted for cloud build P4SA when creating an oauth connection" , async ( ) => {
155+ getConnectionStub . onFirstCall ( ) . rejects ( new FirebaseError ( "error" , { status : 404 } ) ) ;
156+ getConnectionStub . onSecondCall ( ) . resolves ( completeConn ) ;
157+ createConnectionStub . resolves ( op ) ;
158+ pollOperationStub . resolves ( pendingConn ) ;
159+ promptOnceStub . resolves ( "any key" ) ;
160+ getProjectNumberStub . onFirstCall ( ) . resolves ( projectId ) ;
161+ openInBrowserPopupStub . resolves ( { url : "" , cleanup : sandbox . stub ( ) } ) ;
162+
163+ await repo . getOrCreateOauthConnection ( projectId , location ) ;
164+ expect ( serviceAccountHasRolesStub ) . to . be . calledWith (
165+ projectId ,
166+ `service-${ projectId } @gcp-sa-cloudbuild.iam.gserviceaccount.com` ,
167+ [ "roles/secretmanager.admin" ] ,
168+ true ,
169+ ) ;
170+ } ) ;
171+
142172 it ( "creates repository if it doesn't exist" , async ( ) => {
143173 getConnectionStub . resolves ( completeConn ) ;
144174 fetchLinkableRepositoriesStub . resolves ( repos ) ;
0 commit comments