@@ -3,28 +3,127 @@ jest.mock("azure-devops-node-api");
33jest . mock ( "../../config" ) ;
44jest . mock ( "../azdoClient" ) ;
55
6- // Imports
6+ import { IRequestOptions , IRestResponse , RestClient } from "typed-rest-client" ;
77import uuid from "uuid/v4" ;
88import { Config , readYaml } from "../../config" ;
9- import {
10- disableVerboseLogging ,
11- enableVerboseLogging ,
12- logger
13- } from "../../logger" ;
14- import { IVariableGroupData } from "../../types" ;
9+ import { deepClone } from "../../lib/util" ;
10+ import { disableVerboseLogging , enableVerboseLogging } from "../../logger" ;
11+ import { IServiceEndpointData , IVariableGroupData } from "../../types" ;
12+ import * as azdoClient from "../azdoClient" ;
13+ import { IServiceEndpoint } from "./azdoInterfaces" ;
1514import {
1615 addServiceEndpoint ,
17- createServiceEndPointParams
16+ createServiceEndpointIfNotExists ,
17+ createServiceEndPointParams ,
18+ getServiceEndpointByName
1819} from "./serviceEndpoint" ;
20+ import * as serviceEndpoint from "./serviceEndpoint" ;
1921
20- // Tests
2122const serviceEndpointName : string = uuid ( ) ;
2223const subscriptionId : string = uuid ( ) ;
2324const subscriptionName : string = uuid ( ) ;
2425const servicePrincipalId : string = uuid ( ) ;
2526const servicePrincipalSecret : string = uuid ( ) ;
2627const tenantId : string = uuid ( ) ;
2728
29+ const mockedConfig = {
30+ azure_devops : {
31+ orrg : uuid ( )
32+ }
33+ } ;
34+
35+ const mockedYaml = {
36+ description : "mydesc" ,
37+ key_vault_provider : {
38+ name : "vault" ,
39+ service_endpoint : {
40+ name : serviceEndpointName ,
41+ service_principal_id : servicePrincipalId ,
42+ service_principal_secret : servicePrincipalSecret ,
43+ subscription_id : subscriptionId ,
44+ subscription_name : subscriptionName ,
45+ tenant_id : tenantId
46+ }
47+ } ,
48+ name : "myvg"
49+ } ;
50+
51+ const mockedMatchServiceEndpointResponse = {
52+ result : {
53+ count : 1 ,
54+ value : [
55+ {
56+ authorization : {
57+ parameters : {
58+ authenticationType : "authenticationType" ,
59+ serviceprincipalid : "serviceprincipalid" ,
60+ serviceprincipalkey : "serviceprincipalkey" ,
61+ tenantid : "tenantid"
62+ } ,
63+ scheme : "ssh"
64+ } ,
65+ createdBy : {
66+ _links : {
67+ avatar : {
68+ href : "https://person.com"
69+ }
70+ } ,
71+ descriptor : "test" ,
72+ displayName : "tester" ,
73+ id : "test" ,
74+ imageUrl : "https://www.test.com" ,
75+ uniqueName : "test" ,
76+ url : "https://www.tester.com"
77+ } ,
78+ data : {
79+ creationMode : "creationMode" ,
80+ environment : "environment" ,
81+ scopeLevel : "scopeLevel" ,
82+ subscriptionId : "subscriptionId" ,
83+ subscriptionName : "subscriptionName"
84+ } ,
85+ id : "test" ,
86+ isReady : true ,
87+ isShared : false ,
88+ name : "test" ,
89+ owner : "tester" ,
90+ type : "test" ,
91+ url : "https://www.test.com"
92+ }
93+ ]
94+ } ,
95+ statusCode : 200
96+ } ;
97+
98+ const mockedNonMatchServiceEndpointResponse = {
99+ result : {
100+ count : 0 ,
101+ value : [ ]
102+ } ,
103+ statusCode : 200
104+ } ;
105+
106+ const mockedInvalidServiceEndpointResponse = {
107+ result : {
108+ count : 2 ,
109+ value : [ ]
110+ } ,
111+ statusCode : 200
112+ } ;
113+
114+ const createServiceEndpointInput : IServiceEndpointData = {
115+ name : serviceEndpointName ,
116+ service_principal_id : servicePrincipalId ,
117+ service_principal_secret : servicePrincipalSecret ,
118+ subscription_id : subscriptionId ,
119+ subscription_name : subscriptionName ,
120+ tenant_id : tenantId
121+ } ;
122+
123+ const getCreateServiceEndpointInput = ( ) : IServiceEndpointData => {
124+ return deepClone ( createServiceEndpointInput ) ;
125+ } ;
126+
28127beforeAll ( ( ) => {
29128 enableVerboseLogging ( ) ;
30129} ) ;
@@ -208,38 +307,128 @@ describe("Validate service endpoint parameters creation", () => {
208307 } ) ;
209308} ) ;
210309
211- describe ( "addServiceEndpoint" , ( ) => {
212- test ( "should pass when service endpoint config is set" , async ( ) => {
213- ( Config as jest . Mock ) . mockReturnValue ( {
214- azure_devops : {
215- orrg : uuid ( )
216- }
217- } ) ;
310+ const testAddServiceEndpoint = async (
311+ positive = true ,
312+ getRestClientThrowException = false
313+ ) => {
314+ ( Config as jest . Mock ) . mockReturnValueOnce ( mockedConfig ) ;
315+ ( readYaml as jest . Mock ) . mockReturnValueOnce ( mockedYaml ) ;
218316
219- ( readYaml as jest . Mock ) . mockReturnValue ( {
220- description : "mydesc" ,
221- key_vault_provider : {
222- name : "vault" ,
223- service_endpoint : {
224- name : serviceEndpointName ,
225- service_principal_id : servicePrincipalId ,
226- service_principal_secret : servicePrincipalSecret ,
227- subscription_id : subscriptionId ,
228- subscription_name : subscriptionName ,
229- tenant_id : tenantId
317+ jest . spyOn ( azdoClient , "getRestClient" ) . mockReturnValueOnce (
318+ Promise . resolve ( {
319+ create : async (
320+ resource : string ,
321+ resources : any ,
322+ options ?: IRequestOptions
323+ ) : Promise < IRestResponse < { [ key : string ] : string } > > => {
324+ if ( getRestClientThrowException ) {
325+ return new Promise ( ( _ , reject ) => {
326+ reject ( new Error ( "fake" ) ) ;
327+ } ) ;
230328 }
231- } ,
232- name : "myvg"
329+ return new Promise ( resolve => {
330+ resolve ( {
331+ result : {
332+ status : "OK"
333+ } ,
334+ statusCode : positive ? 200 : 400
335+ } ) ;
336+ } ) ;
337+ }
338+ } as RestClient )
339+ ) ;
340+
341+ const input = readYaml < IVariableGroupData > ( "" ) ;
342+ return await addServiceEndpoint ( input . key_vault_provider ! . service_endpoint ) ;
343+ } ;
344+
345+ describe ( "test addServiceEndpoint function" , ( ) => {
346+ it ( "+ve: should pass when service endpoint config is set" , async ( ) => {
347+ const result = await testAddServiceEndpoint ( ) ;
348+ expect ( result ) . toStrictEqual ( {
349+ status : "OK"
233350 } ) ;
234- const input = readYaml < IVariableGroupData > ( "" ) ;
351+ } ) ;
352+ it ( "-ve: create API returns non 200 status code" , async ( ) => {
353+ await expect ( testAddServiceEndpoint ( false ) ) . rejects . toThrow ( ) ;
354+ } ) ;
355+ it ( "-ve: create API throw exection" , async ( ) => {
356+ await expect ( testAddServiceEndpoint ( true , true ) ) . rejects . toThrow ( ) ;
357+ } ) ;
358+ } ) ;
235359
236- let invalidGroupError : Error | undefined ;
237- try {
238- logger . info ( "calling add variable group" ) ;
239- await addServiceEndpoint ( input . key_vault_provider ! . service_endpoint ) ;
240- } catch ( err ) {
241- invalidGroupError = err ;
242- }
243- expect ( invalidGroupError ) . toBeDefined ( ) ;
360+ const testGetServiceEndpointByName = async ( positive = true , more = false ) => {
361+ ( Config as jest . Mock ) . mockReturnValueOnce ( mockedConfig ) ;
362+ ( readYaml as jest . Mock ) . mockReturnValueOnce ( mockedYaml ) ;
363+
364+ jest . spyOn ( azdoClient , "getRestClient" ) . mockReturnValueOnce (
365+ Promise . resolve ( {
366+ get : async (
367+ resource : string ,
368+ options ?: IRequestOptions
369+ ) : Promise <
370+ IRestResponse < {
371+ count : number ;
372+ value : IServiceEndpoint [ ] ;
373+ } >
374+ > => {
375+ return new Promise ( resolve => {
376+ if ( more ) {
377+ resolve ( mockedInvalidServiceEndpointResponse ) ;
378+ } else if ( positive ) {
379+ resolve ( mockedMatchServiceEndpointResponse ) ;
380+ } else {
381+ resolve ( mockedNonMatchServiceEndpointResponse ) ;
382+ }
383+ } ) ;
384+ }
385+ } as RestClient )
386+ ) ;
387+
388+ const input = readYaml < IVariableGroupData > ( "" ) ;
389+ return await getServiceEndpointByName ( "dummy" ) ;
390+ } ;
391+
392+ describe ( "test getServiceEndpointByName function" , ( ) => {
393+ it ( "positive test" , async ( ) => {
394+ const result = await testGetServiceEndpointByName ( ) ;
395+ expect ( result ?. id ) . toBe ( "test" ) ;
396+ } ) ;
397+ it ( "negative test: no match" , async ( ) => {
398+ const result = await testGetServiceEndpointByName ( false ) ;
399+ expect ( result ) . toBeNull ( ) ;
400+ } ) ;
401+ it ( "negative test: too many matches" , async ( ) => {
402+ await expect ( testGetServiceEndpointByName ( true , true ) ) . rejects . toThrow ( ) ;
403+ } ) ;
404+ } ) ;
405+
406+ describe ( "test createServiceEndpointIfNotExists function" , ( ) => {
407+ it ( "+ve" , async ( ) => {
408+ jest
409+ . spyOn ( serviceEndpoint , "getServiceEndpointByName" )
410+ . mockReturnValueOnce ( Promise . resolve ( null ) ) ;
411+ jest
412+ . spyOn ( serviceEndpoint , "addServiceEndpoint" )
413+ . mockReturnValueOnce (
414+ Promise . resolve ( mockedMatchServiceEndpointResponse . result . value [ 0 ] )
415+ ) ;
416+ const endpoint = await createServiceEndpointIfNotExists (
417+ createServiceEndpointInput
418+ ) ;
419+ expect ( endpoint ) . toStrictEqual (
420+ mockedMatchServiceEndpointResponse . result . value [ 0 ]
421+ ) ;
422+ } ) ;
423+ it ( "-ve: missing endpoint" , async ( ) => {
424+ jest
425+ . spyOn ( serviceEndpoint , "getServiceEndpointByName" )
426+ . mockReturnValueOnce ( Promise . resolve ( null ) ) ;
427+ jest
428+ . spyOn ( serviceEndpoint , "addServiceEndpoint" )
429+ . mockReturnValueOnce ( Promise . reject ( new Error ( "fake" ) ) ) ;
430+ await expect (
431+ createServiceEndpointIfNotExists ( createServiceEndpointInput )
432+ ) . rejects . toThrow ( ) ;
244433 } ) ;
245434} ) ;
0 commit comments