11import test from "ava" ;
22import * as td from "testdouble" ;
33
4- import { OFFICIAL_REGISTRY } from "../../lib/definitions/constants.js" ;
4+ import {
5+ OFFICIAL_REGISTRY ,
6+ GITHUB_ACTIONS_PROVIDER_NAME ,
7+ GITLAB_PIPELINES_PROVIDER_NAME ,
8+ } from "../../lib/definitions/constants.js" ;
59
610// https://api-docs.npmjs.com/#tag/registry.npmjs.org/operation/exchangeOidcToken
711
8- let exchangeToken , getIDToken ;
12+ let exchangeToken , getIDToken , envCi ;
913const packageName = "@scope/some-package" ;
1014const pkg = { name : packageName } ;
1115const idToken = "id-token-value" ;
@@ -14,15 +18,19 @@ const token = "token-value";
1418test . beforeEach ( async ( t ) => {
1519 await td . replace ( globalThis , "fetch" ) ;
1620 ( { getIDToken } = await td . replaceEsm ( "@actions/core" ) ) ;
21+ ( { default : envCi } = await td . replaceEsm ( "env-ci" ) ) ;
1722
1823 ( { default : exchangeToken } = await import ( "../../lib/trusted-publishing/token-exchange.js" ) ) ;
1924} ) ;
2025
2126test . afterEach . always ( ( t ) => {
2227 td . reset ( ) ;
28+
29+ delete process . env . NPM_ID_TOKEN ;
2330} ) ;
2431
25- test . serial ( "that an access token is returned when token exchange succeeds" , async ( t ) => {
32+ test . serial ( "that an access token is returned when token exchange succeeds on GitHub Actions" , async ( t ) => {
33+ td . when ( envCi ( ) ) . thenReturn ( { name : GITHUB_ACTIONS_PROVIDER_NAME } ) ;
2634 td . when ( getIDToken ( "npm:registry.npmjs.org" ) ) . thenResolve ( idToken ) ;
2735 td . when (
2836 fetch ( `${ OFFICIAL_REGISTRY } -/npm/v1/oidc/token/exchange/package/${ encodeURIComponent ( packageName ) } ` , {
@@ -36,13 +44,17 @@ test.serial("that an access token is returned when token exchange succeeds", asy
3644 t . is ( await exchangeToken ( pkg ) , token ) ;
3745} ) ;
3846
39- test . serial ( "that `undefined` is returned when ID token retrieval fails" , async ( t ) => {
40- td . when ( getIDToken ( "npm:registry.npmjs.org" ) ) . thenThrow ( new Error ( "Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable" ) ) ;
47+ test . serial ( "that `undefined` is returned when ID token retrieval fails on GitHub Actions" , async ( t ) => {
48+ td . when ( envCi ( ) ) . thenReturn ( { name : GITHUB_ACTIONS_PROVIDER_NAME } ) ;
49+ td . when ( getIDToken ( "npm:registry.npmjs.org" ) ) . thenThrow (
50+ new Error ( "Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable" )
51+ ) ;
4152
4253 t . is ( await exchangeToken ( pkg ) , undefined ) ;
4354} ) ;
4455
45- test . serial ( "that `undefined` is returned when token exchange fails" , async ( t ) => {
56+ test . serial ( "that `undefined` is returned when token exchange fails on GitHub Actions" , async ( t ) => {
57+ td . when ( envCi ( ) ) . thenReturn ( { name : GITHUB_ACTIONS_PROVIDER_NAME } ) ;
4658 td . when ( getIDToken ( "npm:registry.npmjs.org" ) ) . thenResolve ( idToken ) ;
4759 td . when (
4860 fetch ( `${ OFFICIAL_REGISTRY } -/npm/v1/oidc/token/exchange/package/${ encodeURIComponent ( packageName ) } ` , {
@@ -55,3 +67,45 @@ test.serial("that `undefined` is returned when token exchange fails", async (t)
5567
5668 t . is ( await exchangeToken ( pkg ) , undefined ) ;
5769} ) ;
70+
71+ test . serial ( "that an access token is returned when token exchange succeeds on GitLab Pipelines" , async ( t ) => {
72+ process . env . NPM_ID_TOKEN = idToken ;
73+ td . when ( envCi ( ) ) . thenReturn ( { name : GITLAB_PIPELINES_PROVIDER_NAME } ) ;
74+ td . when (
75+ fetch ( `${ OFFICIAL_REGISTRY } -/npm/v1/oidc/token/exchange/package/${ encodeURIComponent ( packageName ) } ` , {
76+ method : "POST" ,
77+ headers : { Authorization : `Bearer ${ idToken } ` } ,
78+ } )
79+ ) . thenResolve (
80+ new Response ( JSON . stringify ( { token } ) , { status : 201 , headers : { "Content-Type" : "application/json" } } )
81+ ) ;
82+
83+ t . is ( await exchangeToken ( pkg ) , token ) ;
84+ } ) ;
85+
86+ test . serial ( "that `undefined` is returned when ID token is not available on GitLab Pipelines" , async ( t ) => {
87+ td . when ( envCi ( ) ) . thenReturn ( { name : GITLAB_PIPELINES_PROVIDER_NAME } ) ;
88+
89+ t . is ( await exchangeToken ( pkg ) , undefined ) ;
90+ } ) ;
91+
92+ test . serial ( "that `undefined` is returned when token exchange fails on GitLab Pipelines" , async ( t ) => {
93+ process . env . NPM_ID_TOKEN = idToken ;
94+ td . when ( envCi ( ) ) . thenReturn ( { name : GITLAB_PIPELINES_PROVIDER_NAME } ) ;
95+ td . when (
96+ fetch ( `${ OFFICIAL_REGISTRY } -/npm/v1/oidc/token/exchange/package/${ encodeURIComponent ( packageName ) } ` , {
97+ method : "POST" ,
98+ headers : { Authorization : `Bearer ${ idToken } ` } ,
99+ } )
100+ ) . thenResolve (
101+ new Response ( JSON . stringify ( { message : "foo" } ) , { status : 401 , headers : { "Content-Type" : "application/json" } } )
102+ ) ;
103+
104+ t . is ( await exchangeToken ( pkg ) , undefined ) ;
105+ } ) ;
106+
107+ test . serial ( "that `undefined` is returned when no supported CI provider is detected" , async ( t ) => {
108+ td . when ( envCi ( ) ) . thenReturn ( { name : "Other Service" } ) ;
109+
110+ t . is ( await exchangeToken ( pkg ) , undefined ) ;
111+ } ) ;
0 commit comments