1var path = require('path') 2 3var mr = require('npm-registry-mock') 4var test = require('tap').test 5var common = require('../common-tap') 6var Tacks = require('tacks') 7var Dir = Tacks.Dir 8var File = Tacks.File 9 10var workdir = common.pkg 11var cachedir = common.cache 12var modulesdir = path.join(workdir, 'modules') 13var oldModule = path.join(modulesdir, 'good-night-0.1.0.tgz') 14var newModule = path.join(modulesdir, 'good-night-1.0.0.tgz') 15 16var config = [ 17 '--cache', cachedir, 18 '--prefix', workdir, 19 '--registry', common.registry 20] 21 22var fixture = new Tacks(Dir({ 23 'modules': Dir({ 24 'good-night-0.1.0.tgz': File(Buffer.from( 25 '1f8b0800000000000003ed934f4bc43010c57beea7187a59056dd36eff80' + 26 'de85050541c1f3d8c634da4e4a925a8af8dd6db7bb8ba0e0c15559e9eff2' + 27 '206f929909bc06f327143c6826f51f8d2267cf30c6d2388641c32c61ef75' + 28 '4d9426e084519a25491645cbcc61e192c5d1e0ef7b90cf688d453d8cf2dd' + 29 '77a65d60a707c28b0b031e61cdbd33f08452c52949515aef64729eb93652' + 30 'd168323ff4d9f6bce026d7b2b11bafef11b1eb3a221a2aa6126c6da9f4e8' + 31 '5e691f6e908a1a697b5ff346196995eec7023399c1c7fe95cc3999f57077' + 32 'b717d7979efbeafef5a7fd2336b90f6a943484ff477a7c917f96c5bbfc87' + 33 '493ae63f627138e7ff37c815195571bf52e268b1820e0d0825498055d069' + 34 '6939d8521ab86f2dace0815715a0a9386f16c7e7730c676666660e9837c0' + 35 'f6795d000c0000', 36 'hex' 37 )), 38 'good-night-1.0.0.tgz': File(Buffer.from( 39 '1f8b0800000000000003ed954d6bc24010863dfb2bb6b9a8503793b849a0' + 40 'eda5979efa052d484184252e495a331b76d78a94fef76e8cf683163cd42a' + 41 '957d2e03796777268187543c7de299f0aba6d2472db1b5650020668cd81a' + 42 '24117cae4bc23822ad208c93284a1208c216040318c436dff6223f31d386' + 43 '2bbbca6fef69de85bcd77fc24b9b583ce4a5f04e88974939e96391e5c63b' + 44 '6e9267a17421b10e030a14d6cf2742a7aaa8cc2a5b2c38e7f3f91c116d47' + 45 'd3c2672697aa4eaf1425771c2725c7f579252aa90b23d5a26ed04de87f9f' + 46 '3f2d52817ab9dcf0fee2f6d26bbfb6f7fdd10e8895f77ec90bb4f2ffc98c' + 47 '0dfe439c7cf81fc4b5ff213070feef8254a2965341a732eb76b4cef39c12' + 48 'e456eb52d82a29198dc637639f9c751fce8796eba35ea777ea0c3c14d6fe' + 49 '532314f62ba9ccf6676cf21fbefcff59ed3f4b22e7ff2e60110bc37d2fe1' + 50 '70381c8e9df306642df14500100000', 51 'hex' 52 )) 53 }) 54})) 55 56var server 57 58// In this test we mock a situation where the user has a package in his cache, 59// a newer version of the package is published, and the user tried to install 60// said new version while requestion that the cache be used. 61// npm should see that it doesn't have the package in its cache and hit the 62// registry. 63var onlyOldMetadata = { 64 'name': 'good-night', 65 'dist-tags': { 66 'latest': '0.1.0' 67 }, 68 'versions': { 69 '0.1.0': { 70 'name': 'good-night', 71 'version': '0.1.0', 72 'dist': { 73 'shasum': '2a746d49dd074ba0ec2d6ff13babd40c658d89eb', 74 'tarball': 'http://localhost:' + common.port + '/good-night/-/good-night-0.1.0.tgz' 75 } 76 } 77 } 78} 79 80var oldAndNewMetadata = Object.assign({}, onlyOldMetadata) 81oldAndNewMetadata['dist-tags'] = { latest: '1.0.0' } 82oldAndNewMetadata.versions = Object.assign({ 83 '1.0.0': { 84 'name': 'good-night', 85 'version': '1.0.0', 86 'dist': { 87 'shasum': 'f377bf002a0a8fc4085d347a160a790b76896bc3', 88 'tarball': 'http://localhost:' + common.port + '/good-night/-/good-night-1.0.0.tgz' 89 } 90 } 91}, oldAndNewMetadata.versions) 92 93function setup () { 94 cleanup() 95 fixture.create(workdir) 96} 97 98function cleanup () { 99 fixture.remove(workdir) 100} 101 102test('setup', function (t) { 103 setup() 104 t.end() 105}) 106 107test('setup initial server', function (t) { 108 mr({ 109 port: common.port, 110 throwOnUnmatched: true 111 }, function (err, s) { 112 t.ifError(err, 'registry mocked successfully') 113 server = s 114 115 server.get('/good-night') 116 .many({ min: 1, max: 1 }) 117 .reply(200, onlyOldMetadata) 118 server.get('/good-night/-/good-night-0.1.0.tgz') 119 .many({ min: 1, max: 1 }) 120 .replyWithFile(200, oldModule) 121 122 t.end() 123 }) 124}) 125 126test('install initial version', function (t) { 127 common.npm(config.concat([ 128 'install', 'good-night' 129 ]), {stdio: 'inherit'}, function (err, code) { 130 if (err) throw err 131 t.is(code, 0, 'initial install succeeded') 132 server.done() 133 t.end() 134 }) 135}) 136 137test('cleanup initial server', function (t) { 138 server.close() 139 t.end() 140}) 141 142test('setup new server', function (t) { 143 mr({ 144 port: common.port, 145 throwOnUnmatched: true 146 }, function (err, s) { 147 t.ifError(err, 'registry mocked successfully') 148 server = s 149 150 server.get('/good-night') 151 .many({ min: 1, max: 1 }) 152 .reply(200, oldAndNewMetadata) 153 154 server.get('/good-night/-/good-night-1.0.0.tgz') 155 .many({ min: 1, max: 1 }) 156 .replyWithFile(200, newModule) 157 158 t.end() 159 }) 160}) 161 162test('install new version', function (t) { 163 common.npm(config.concat([ 164 '--prefer-offline', 165 'install', 'good-night@1.0.0' 166 ]), {}, function (err, code, stdout, stderr) { 167 if (err) throw err 168 t.equal(stderr, '', 'no error output') 169 t.is(code, 0, 'install succeeded') 170 171 t.end() 172 }) 173}) 174 175test('install does not hit server again', function (t) { 176 // The mock server route definitions ensure we don't hit the server again 177 common.npm(config.concat([ 178 '--prefer-offline', 179 '--parseable', 180 'install', 'good-night' 181 ]), {stdio: [0, 'pipe', 2]}, function (err, code, stdout) { 182 if (err) throw err 183 t.is(code, 0, 'install succeeded') 184 185 t.match(stdout, /^update\tgood-night\t1.0.0\t/, 'installed latest version') 186 server.done() 187 t.end() 188 }) 189}) 190 191test('cleanup', function (t) { 192 server.close() 193 cleanup() 194 t.end() 195}) 196