Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lib/db/build-index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ module.exports = async function buildIndex (config, db) {
const { type, project, detail } = evt
let key = `${project.repoOwner}:${project.repoName}:${type}`
switch (type) {
case 'PACKAGE_JSON':
if (detail.private) {
const prefix = `${project.repoOwner}:${project.repoName}:`
await db.batch([
{ type: 'put', key, value: evt },
{ type: 'del', key: `${prefix}PACKUMENT` },
{ type: 'del', key: `${prefix}PACKAGE_MANIFEST` }
])
continue
}
break
case 'ISSUE':
key += `:${detail.number}`
break
Expand Down
109 changes: 109 additions & 0 deletions test/build-index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'use strict'
const { suite, test, beforeEach, afterEach } = require('mocha')
const assert = require('assert')
const os = require('os')
const path = require('path')
const fs = require('fs-extra')
const level = require('level')
const github = require('../lib/github')
const files = require('../lib/files')
const npm = require('../lib/npm')
const buildIndex = require('../lib/db/build-index')
const { Project } = require('../lib/project')
const indices = require('../template/indicies')

suite('Private package indexing', () => {
let db
let directory
let pkg
let npmCalls
let restore
const prefix = 'example:sample:'

beforeEach(async () => {
directory = await fs.mkdtemp(path.join(os.tmpdir(), 'statusboard-index-'))
db = level(directory, { valueEncoding: 'json' })
pkg = { name: 'sample', version: '1.0.0' }
npmCalls = 0
restore = []
function stub (object, key, value) {
const original = object[key]
restore.push(() => { object[key] = original })
object[key] = value
}
stub(github, 'getRepo', async () => ({ branch: 'main' }))
for (const method of ['getRepoIssues', 'getRepoActivity', 'getRepoCommits']) {
stub(github, method, async function * () {})
}
stub(files, 'getPackageJson', async () => pkg)
stub(npm, 'getPackument', async () => {
npmCalls++
return { name: pkg.name, versions: { [pkg.version]: {} } }
})
stub(npm, 'getManifest', async () => {
npmCalls++
return { name: pkg.name, version: pkg.version }
})
})

afterEach(async () => {
for (const reset of restore) reset()
await db.close()
await fs.remove(directory)
})

function index () {
return buildIndex({
github: { token: 'unused-test-token' },
projects: [new Project('example/sample')],
orgs: []
}, db)
}

async function assertNoNpmMetadata () {
for (const type of ['PACKUMENT', 'PACKAGE_MANIFEST']) {
await assert.rejects(db.get(`${prefix}${type}`), err => err.notFound)
}
let projects
for await (const { key, value } of db.createReadStream()) {
projects = await indices.projects(projects, {}, key, value)
}
const project = projects.find(project => project.repo === 'example/sample')
assert.strictEqual(project.packageJson.private, true)
assert.strictEqual(project.packument, undefined)
assert.ok(project.repoDetails)
}

test('removes stale npm metadata when a public package becomes private', async () => {
await index()
assert.strictEqual(npmCalls, 2)
assert.ok(await db.get(`${prefix}PACKUMENT`))
assert.ok(await db.get(`${prefix}PACKAGE_MANIFEST`))
await db.put('example:other:PACKUMENT', { name: 'other' })

pkg.private = true
await index()
await assertNoNpmMetadata()
assert.strictEqual(npmCalls, 2)
assert.deepStrictEqual(await db.get('example:other:PACKUMENT'), { name: 'other' })

// Reindexing a private package should be safe after the records are gone.
await index()
await assertNoNpmMetadata()
assert.strictEqual(npmCalls, 2)

pkg.private = false
pkg.version = '2.0.0'
await index()
assert.strictEqual(npmCalls, 4)
assert.strictEqual((await db.get(`${prefix}PACKAGE_MANIFEST`)).detail.version, '2.0.0')
assert.ok((await db.get(`${prefix}PACKUMENT`)).detail.versions['2.0.0'])
})

test('indexes a new private package without fetching npm metadata', async () => {
pkg.private = true
await index()
await assertNoNpmMetadata()
assert.strictEqual(npmCalls, 0)
})
})
Loading