11const t = require ( 'tap' )
2- const { load : loadMockNpm } = require ( '../../fixtures/mock-npm' )
2+ const {
3+ load : originalLoadMockNpm ,
4+ mockNpmRegistryFetch,
5+ putPackagePayload } = require ( '../../fixtures/mock-npm' )
36const { cleanZlib } = require ( '../../fixtures/clean-snapshot' )
47const MockRegistry = require ( '@npmcli/mock-registry' )
58const pacote = require ( 'pacote' )
@@ -22,6 +25,20 @@ const pkgJson = {
2225
2326t . cleanSnapshot = data => cleanZlib ( data )
2427
28+ function loadMockNpm ( test , args ) {
29+ return originalLoadMockNpm ( test , {
30+ ...args ,
31+ mocks : {
32+ ...mockNpmRegistryFetch ( {
33+ [ `/-/package/${ pkg } /dist-tags` ] : ( ) => {
34+ throw new Error ( 'not found' )
35+ } ,
36+ } ) . mocks ,
37+ ...args . mocks ,
38+ } ,
39+ } )
40+ }
41+
2542t . test ( 'respects publishConfig.registry, runs appropriate scripts' , async t => {
2643 const { npm, joinedOutput, prefix } = await loadMockNpm ( t , {
2744 config : {
@@ -1068,3 +1085,105 @@ t.test('does not abort when prerelease and authored tag latest', async t => {
10681085 } ) . reply ( 200 , { } )
10691086 await npm . exec ( 'publish' , [ ] )
10701087} )
1088+
1089+ t . test ( 'PREVENTS publish when latest dist-tag is HIGHER than publishing version' , async t => {
1090+ const latest = '100.0.0'
1091+ const version = '50.0.0'
1092+
1093+ const { npm } = await loadMockNpm ( t , {
1094+ config : {
1095+ loglevel : 'silent' ,
1096+ [ `${ alternateRegistry . slice ( 6 ) } /:_authToken` ] : 'test-other-token' ,
1097+ } ,
1098+ prefixDir : {
1099+ 'package.json' : JSON . stringify ( {
1100+ ...pkgJson ,
1101+ version,
1102+ scripts : {
1103+ prepublishOnly : 'touch scripts-prepublishonly' ,
1104+ prepublish : 'touch scripts-prepublish' , // should NOT run this one
1105+ publish : 'touch scripts-publish' ,
1106+ postpublish : 'touch scripts-postpublish' ,
1107+ } ,
1108+ publishConfig : { registry : alternateRegistry } ,
1109+ } , null , 2 ) ,
1110+ } ,
1111+ mocks : {
1112+ ...mockNpmRegistryFetch ( {
1113+ [ `/-/package/${ pkg } /dist-tags` ] : { latest } ,
1114+ } ) . mocks ,
1115+ } ,
1116+ } )
1117+ await t . rejects ( async ( ) => {
1118+ await npm . exec ( 'publish' , [ ] )
1119+ } , new Error ( 'Cannot publish a lower version without an explicit dist tag.' ) )
1120+ } )
1121+
1122+ t . test ( 'ALLOWS publish when latest dist-tag is LOWER than publishing version' , async t => {
1123+ const version = '100.0.0'
1124+ const latest = '50.0.0'
1125+
1126+ const { npm } = await loadMockNpm ( t , {
1127+ config : {
1128+ loglevel : 'silent' ,
1129+ [ `${ alternateRegistry . slice ( 6 ) } /:_authToken` ] : 'test-other-token' ,
1130+ } ,
1131+ prefixDir : {
1132+ 'package.json' : JSON . stringify ( {
1133+ ...pkgJson ,
1134+ version,
1135+ publishConfig : { registry : alternateRegistry } ,
1136+ } , null , 2 ) ,
1137+ } ,
1138+ mocks : {
1139+ ...mockNpmRegistryFetch ( {
1140+ [ `/-/package/${ pkg } /dist-tags` ] : { latest } ,
1141+ } ) . mocks ,
1142+ } ,
1143+ } )
1144+ const registry = new MockRegistry ( {
1145+ tap : t ,
1146+ registry : alternateRegistry ,
1147+ authorization : 'test-other-token' ,
1148+ } )
1149+ registry . nock . put ( `/${ pkg } ` , body => {
1150+ return t . match ( body , putPackagePayload ( {
1151+ pkg, alternateRegistry, version,
1152+ } ) )
1153+ } ) . reply ( 200 , { } )
1154+ await npm . exec ( 'publish' , [ ] )
1155+ } )
1156+
1157+ t . test ( 'ALLOWS publish when latest dist-tag is missing from response' , async t => {
1158+ const version = '100.0.0'
1159+
1160+ const { npm } = await loadMockNpm ( t , {
1161+ config : {
1162+ loglevel : 'silent' ,
1163+ [ `${ alternateRegistry . slice ( 6 ) } /:_authToken` ] : 'test-other-token' ,
1164+ } ,
1165+ prefixDir : {
1166+ 'package.json' : JSON . stringify ( {
1167+ ...pkgJson ,
1168+ version,
1169+ publishConfig : { registry : alternateRegistry } ,
1170+ } , null , 2 ) ,
1171+ } ,
1172+ mocks : {
1173+ ...mockNpmRegistryFetch ( {
1174+ [ `/-/package/${ pkg } /dist-tags` ] : { } ,
1175+ } ) . mocks ,
1176+ } ,
1177+ } )
1178+ const registry = new MockRegistry ( {
1179+ tap : t ,
1180+ registry : alternateRegistry ,
1181+ authorization : 'test-other-token' ,
1182+ } )
1183+ registry . nock . put ( `/${ pkg } ` , body => {
1184+ return t . match ( body , putPackagePayload ( {
1185+ pkg, alternateRegistry, version,
1186+ } ) )
1187+ } ) . reply ( 200 , { } )
1188+ await npm . exec ( 'publish' , [ ] )
1189+ } )
0 commit comments