• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2
3const common = require('../common-tap.js')
4const npm = require('../../')
5const test = require('tap').test
6const mkdirp = require('mkdirp')
7const rimraf = require('rimraf')
8const path = require('path')
9const fs = require('fs')
10const cacheFile = require('npm-cache-filename')
11const mr = require('npm-registry-mock')
12const ms = require('mississippi')
13const Tacks = require('tacks')
14const File = Tacks.File
15
16const allPackageMetadata = require('../../lib/search/all-package-metadata.js')
17
18const PKG_DIR = path.resolve(common.cache, 'update-index')
19const CACHE_DIR = path.resolve(PKG_DIR, 'cache', '_cacache')
20let cacheBase
21let cachePath
22
23let server
24
25function setup () {
26  mkdirp.sync(cacheBase)
27}
28
29function cleanup (cb) {
30  rimraf(PKG_DIR, cb)
31}
32
33test('setup', function (t) {
34  mr({port: common.port, throwOnUnmatched: true}, function (err, s) {
35    t.ifError(err, 'registry mocked successfully')
36    npm.load({ cache: path.dirname(CACHE_DIR), registry: common.registry }, function (err) {
37      t.ifError(err, 'npm loaded successfully')
38      npm.config.set('cache', path.dirname(CACHE_DIR))
39      cacheBase = cacheFile(npm.config.get('cache'))(common.registry + '/-/all')
40      cachePath = path.join(cacheBase, '.cache.json')
41      server = s
42      t.pass('all set up')
43      t.done()
44    })
45  })
46})
47
48test('allPackageMetadata full request', function (t) {
49  setup()
50  var updated = Date.now()
51  server.get('/-/all').once().reply(200, {
52    '_updated': 1234,
53    'bar': { name: 'bar', version: '1.0.0' },
54    'foo': { name: 'foo', version: '1.0.0' }
55  }, {
56    date: updated
57  })
58  var stream = allPackageMetadata({
59    cache: CACHE_DIR,
60    registry: common.registry,
61    staleness: 600
62  })
63  t.ok(stream, 'returned a stream')
64  var results = []
65  stream.on('data', function (pkg) {
66    results.push(pkg)
67  })
68  ms.finished(stream, function (err) {
69    if (err) throw err
70    t.deepEquals(results, [{
71      name: 'bar',
72      version: '1.0.0'
73    }, {
74      name: 'foo',
75      version: '1.0.0'
76    }])
77    var fileData = JSON.parse(fs.readFileSync(cachePath))
78    t.ok(fileData, 'cache contents written to the right file')
79    t.deepEquals(fileData, {
80      '_updated': 1234,
81      bar: {
82        name: 'bar',
83        version: '1.0.0'
84      },
85      foo: {
86        name: 'foo',
87        version: '1.0.0'
88      }
89    }, 'cache contents based on what was written')
90    server.done()
91    cleanup(t.end)
92  })
93})
94
95test('allPackageMetadata cache only', function (t) {
96  setup()
97  var now = Date.now()
98  var cacheContents = {
99    '_updated': now,
100    bar: { name: 'bar', version: '1.0.0' },
101    cool: { name: 'cool', version: '1.0.0' },
102    foo: { name: 'foo', version: '2.0.0' },
103    other: { name: 'other', version: '1.0.0' }
104  }
105  var fixture = new Tacks(File(cacheContents))
106  fixture.create(cachePath)
107  var stream = allPackageMetadata({
108    cache: CACHE_DIR,
109    registry: common.registry,
110    staleness: 10000000
111  })
112  t.ok(stream, 'returned a stream')
113  var results = []
114  stream.on('data', function (pkg) {
115    results.push(pkg)
116  })
117  ms.finished(stream, function (err) {
118    t.ifError(err, 'stream finished without error')
119    t.deepEquals(
120      results.map(function (pkg) { return pkg.name }),
121      ['bar', 'cool', 'foo', 'other'],
122      'packages deduped and sorted, without _updated'
123    )
124    var fileData = JSON.parse(fs.readFileSync(cachePath))
125    t.ok(fileData, 'cache contents written to the right file')
126    t.deepEquals(fileData, cacheContents, 'cacheContents written directly')
127    server.done()
128    cleanup(t.end)
129  })
130})
131
132test('createEntryStream merged stream', function (t) {
133  setup()
134  var now = Date.now()
135  var cacheTime = now - 601000
136  var reqTime = (new Date(now)).toISOString()
137  server.get('/-/all/since?stale=update_after&startkey=' + cacheTime).once().reply(200, {
138    'bar': { name: 'bar', version: '2.0.0' },
139    'car': { name: 'car', version: '1.0.0' },
140    'foo': { name: 'foo', version: '1.0.0' }
141  }, {
142    date: reqTime
143  })
144  var fixture = new Tacks(File({
145    '_updated': cacheTime,
146    bar: { name: 'bar', version: '1.0.0' },
147    cool: { name: 'cool', version: '1.0.0' },
148    foo: { name: 'foo', version: '2.0.0' },
149    other: { name: 'other', version: '1.0.0' }
150  }))
151  fixture.create(cachePath)
152  var stream = allPackageMetadata({
153    cache: CACHE_DIR,
154    registry: common.registry,
155    staleness: 600
156  })
157  t.ok(stream, 'returned a stream')
158  var results = []
159  stream.on('data', function (pkg) {
160    results.push(pkg)
161  })
162  ms.finished(stream, function (err) {
163    t.ifError(err, 'stream finished without error')
164    t.deepEquals(
165      results.map(function (pkg) { return pkg.name }),
166      ['bar', 'car', 'cool', 'foo', 'other'],
167      'packages deduped and sorted'
168    )
169    t.deepEquals(results[0], {
170      name: 'bar',
171      version: '2.0.0'
172    }, 'update stream version wins on dedupe')
173    t.deepEquals(results[3], {
174      name: 'foo',
175      version: '1.0.0'
176    }, 'update stream version wins on dedupe even when the newer one has a lower semver.')
177    var cacheContents = {
178      '_updated': Date.parse(reqTime),
179      bar: { name: 'bar', version: '2.0.0' },
180      car: { name: 'car', version: '1.0.0' },
181      cool: { name: 'cool', version: '1.0.0' },
182      foo: { name: 'foo', version: '1.0.0' },
183      other: { name: 'other', version: '1.0.0' }
184    }
185    var fileData = JSON.parse(fs.readFileSync(cachePath))
186    t.ok(fileData, 'cache contents written to the right file')
187    t.deepEquals(fileData, cacheContents, 'cache updated correctly')
188    server.done()
189    cleanup(t.end)
190  })
191})
192
193test('allPackageMetadata no sources', function (t) {
194  setup()
195  server.get('/-/all').once().reply(404, {})
196  var stream = allPackageMetadata({
197    cache: CACHE_DIR,
198    registry: common.registry,
199    staleness: 600
200  })
201  ms.finished(stream, function (err) {
202    t.ok(err, 'no sources, got an error')
203    t.match(err.message, /No search sources available/, 'useful error message')
204    server.done()
205    cleanup(t.end)
206  })
207})
208
209test('cleanup', function (t) {
210  server.close()
211  cleanup(t.end)
212})
213