11"use strict" ;
22
3+ jest . mock ( "@lerna/otplease" ) ;
4+
35// local modules _must_ be explicitly mocked
46jest . mock ( "../lib/get-packages-without-license" ) ;
57jest . mock ( "../lib/verify-npm-package-access" ) ;
68jest . mock ( "../lib/get-npm-username" ) ;
9+ jest . mock ( "../lib/get-two-factor-auth-required" ) ;
710jest . mock ( "../lib/get-unpublished-packages" ) ;
811// FIXME: better mock for version command
912jest . mock ( "../../version/lib/git-push" ) ;
@@ -12,13 +15,15 @@ jest.mock("../../version/lib/is-behind-upstream");
1215jest . mock ( "../../version/lib/remote-branch-exists" ) ;
1316
1417// mocked or stubbed modules
18+ const otplease = require ( "@lerna/otplease" ) ;
1519const npmDistTag = require ( "@lerna/npm-dist-tag" ) ;
1620const npmPublish = require ( "@lerna/npm-publish" ) ;
1721const packDirectory = require ( "@lerna/pack-directory" ) ;
1822const PromptUtilities = require ( "@lerna/prompt" ) ;
1923const collectUpdates = require ( "@lerna/collect-updates" ) ;
2024const getNpmUsername = require ( "../lib/get-npm-username" ) ;
2125const verifyNpmPackageAccess = require ( "../lib/verify-npm-package-access" ) ;
26+ const getTwoFactorAuthRequired = require ( "../lib/get-two-factor-auth-required" ) ;
2227
2328// helpers
2429const commitChangeToPackage = require ( "@lerna-test/commit-change-to-package" ) ;
@@ -127,6 +132,12 @@ Map {
127132 "lerna-test" ,
128133 expect . figgyPudding ( { registry : "https://registry.npmjs.org/" } )
129134 ) ;
135+
136+ expect ( getTwoFactorAuthRequired ) . toHaveBeenCalled ( ) ;
137+ expect ( getTwoFactorAuthRequired ) . toHaveBeenLastCalledWith (
138+ // extra insurance that @lerna /npm-conf is defaulting things correctly
139+ expect . figgyPudding ( { otp : undefined } )
140+ ) ;
130141 } ) ;
131142
132143 it ( "publishes changed independent packages" , async ( ) => {
@@ -168,10 +179,15 @@ Map {
168179 } ) ;
169180
170181 describe ( "--otp" , ( ) => {
182+ otplease . getOneTimePassword . mockImplementation ( ( ) => Promise . resolve ( "654321" ) ) ;
183+
171184 it ( "passes one-time password to npm commands" , async ( ) => {
172185 const testDir = await initFixture ( "normal" ) ;
173186 const otp = "123456" ;
174187
188+ // cli option skips prompt
189+ getTwoFactorAuthRequired . mockResolvedValueOnce ( true ) ;
190+
175191 await lernaPublish ( testDir ) ( "--otp" , otp ) ;
176192
177193 expect ( npmPublish ) . toHaveBeenCalledWith (
@@ -180,6 +196,23 @@ Map {
180196 expect . objectContaining ( { otp } ) ,
181197 expect . objectContaining ( { otp } )
182198 ) ;
199+ expect ( otplease . getOneTimePassword ) . not . toHaveBeenCalled ( ) ;
200+ } ) ;
201+
202+ it ( "prompts for OTP when option missing and account-level 2FA enabled" , async ( ) => {
203+ const testDir = await initFixture ( "normal" ) ;
204+
205+ getTwoFactorAuthRequired . mockResolvedValueOnce ( true ) ;
206+
207+ await lernaPublish ( testDir ) ( ) ;
208+
209+ expect ( npmPublish ) . toHaveBeenCalledWith (
210+ expect . objectContaining ( { name : "package-1" } ) ,
211+ "/TEMP_DIR/package-1-MOCKED.tgz" ,
212+ expect . objectContaining ( { otp : undefined } ) ,
213+ expect . objectContaining ( { otp : "654321" } )
214+ ) ;
215+ expect ( otplease . getOneTimePassword ) . toHaveBeenLastCalledWith ( "Enter OTP:" ) ;
183216 } ) ;
184217 } ) ;
185218
0 commit comments