From 427fd8e2fa9aca34d43c27726164f46ad6104832 Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Sun, 14 Jan 2018 12:29:50 +0000 Subject: [PATCH 1/7] Add more thorough tests for registries.npm.request authorisation --- __tests__/registries/npm-registry.js | 662 ++++++++++++++++++++++++--- 1 file changed, 590 insertions(+), 72 deletions(-) diff --git a/__tests__/registries/npm-registry.js b/__tests__/registries/npm-registry.js index 6fa85aac66..d6c3eea9ac 100644 --- a/__tests__/registries/npm-registry.js +++ b/__tests__/registries/npm-registry.js @@ -72,137 +72,655 @@ function createMocks(): Object { } describe('request', () => { - test('should call requestManager.request with url', () => { + // a helper function for creating an instance of npm registry, + // making requests and inspecting request parameters + function createRegistry(config: Object): Object { const testCwd = '.'; const {mockRequestManager, mockRegistries, mockReporter} = createMocks(); const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter); + npmRegistry.config = config; + return { + request(url: string, options: Object, packageName: string): Object { + npmRegistry.request(url, options, packageName); + const lastIndex = mockRequestManager.request.mock.calls.length - 1; + const requestParams = mockRequestManager.request.mock.calls[lastIndex][0]; + return requestParams; + }, + }; + } + test('should call requestManager.request with url', () => { const url = 'https://github.com/yarnpkg/yarn.tgz'; + const config = {}; + const requestParams = createRegistry(config).request(url); + expect(requestParams.url).toBe(url); + }); - npmRegistry.request(url); - - const requestParams = mockRequestManager.request.mock.calls[0][0]; + const testCases = [ + { + title: 'default registry is npm, scoped packages on private registry', + config: { + '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', + '@private:registry': 'https://registry.myorg.com/', + }, + requests: [ + { + url: 'yarn', + pkg: 'yarn', + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: '@yarn%2fcore', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: '-/package/yarn/dist-tags', + pkg: 'yarn', + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: '-/package/@yarn%2fcore/dist-tags', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: '-/user/token/abcdef', + pkg: null, + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: 'https://registry.npmjs.org/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.yarnpkg.com', auth: false}, + }, + { + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: null, + expect: {root: 'https://registry.yarnpkg.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: '@yarn/core', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: '@private/pkg', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com', auth: 'scopedPrivateAuthToken'}, + }, + { + url: 'https://some.cdn.com/some-hash/@private-pkg-1.0.0.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@private/pkg', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + ], + }, + { + title: 'default registry is npm, scoped packages in npm and private registry', + config: { + '//registry.npmjs.org/:_authToken': 'scopedNpmAuthToken', + '@yarn:registry': 'https://registry.npmjs.org/', + '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', + '@private:registry': 'https://registry.myorg.com/', + }, + requests: [ + { + url: 'yarn', + pkg: 'yarn', + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: '@yarn%2fcore', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + }, + { + url: '-/package/yarn/dist-tags', + pkg: 'yarn', + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: '-/package/@yarn%2fcore/dist-tags', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + }, + { + url: '-/user/token/abcdef', + pkg: null, + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: 'https://registry.npmjs.org/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + }, + { + // THIS IS THE BUG!!! + skip: true, + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.yarnpkg.com', auth: 'scopedNpmAuthToken'}, + }, + { + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: null, + expect: {root: 'https://registry.yarnpkg.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: '@yarn/core', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: '@private/pkg', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com', auth: 'scopedPrivateAuthToken'}, + }, + { + url: 'https://some.cdn.com/some-hash/@private-pkg-1.0.0.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@private/pkg', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + ], + }, + { + title: 'default registry is npm, global npm auth, and one scope on private registry', + config: { + _authToken: 'scopedNpmAuthToken', + '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', + '@private:registry': 'https://registry.myorg.com/', + }, + requests: [ + { + url: 'yarn', + pkg: 'yarn', + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: '@yarn%2fcore', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + }, + { + url: '-/package/yarn/dist-tags', + pkg: 'yarn', + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: '-/package/@yarn%2fcore/dist-tags', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + }, + { + url: '-/user/token/abcdef', + pkg: null, + expect: {root: 'https://registry.npmjs.org', auth: false}, + }, + { + url: 'https://registry.npmjs.org/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + }, + { + // THIS IS THE BUG!!! + skip: true, + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.yarnpkg.com', auth: 'scopedNpmAuthToken'}, + }, + { + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: null, + expect: {root: 'https://registry.yarnpkg.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: '@yarn/core', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: '@private/pkg', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com', auth: 'scopedPrivateAuthToken'}, + }, + { + url: 'https://some.cdn.com/some-hash/@private-pkg-1.0.0.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@private/pkg', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + ], + }, + { + title: 'default registry is a private registry and one scope on npm registry', + config: { + 'always-auth': true, + registry: 'https://registry.myorg.com/', + '//registry.myorg.com/:_authToken': 'privateAuthToken', + '//registry.npmjs.org/:_authToken': 'scopedNpmAuthToken', + '@yarn:registry': 'https://registry.npmjs.org/', + }, + requests: [ + { + url: 'yarn', + pkg: 'yarn', + expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, + }, + { + url: '@yarn%2fcore', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + }, + { + url: '-/package/yarn/dist-tags', + pkg: 'yarn', + expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, + }, + { + url: '-/package/@yarn%2fcore/dist-tags', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + }, + { + url: '-/user/token/abcdef', + pkg: null, + expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, + }, + { + url: 'https://registry.npmjs.org/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + }, + { + // THIS IS THE BUG!!! + skip: true, + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.yarnpkg.com', auth: 'scopedNpmAuthToken'}, + }, + { + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: null, + expect: {root: 'https://registry.yarnpkg.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: '@yarn/core', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: '@private/pkg', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, + }, + { + url: 'https://some.cdn.com/some-hash/@private-pkg-1.0.0.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@private/pkg', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + ], + }, + { + title: 'default registry is npm with always-auth and one scope on private registry', + config: { + 'always-auth': true, + '//registry.npmjs.org/:_authToken': 'npmAuthToken', + '@private:registry': 'https://registry.myorg.com/', + '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', + }, + requests: [ + { + url: 'yarn', + pkg: 'yarn', + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + }, + { + url: '@yarn%2fcore', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + }, + { + url: '-/package/yarn/dist-tags', + pkg: 'yarn', + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + }, + { + url: '-/package/@yarn%2fcore/dist-tags', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + }, + { + url: '-/user/token/abcdef', + pkg: null, + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + }, + { + url: 'https://registry.npmjs.org/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + }, + { + // THIS IS THE BUG!!! + skip: true, + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: '@yarn/core', + expect: {root: 'https://registry.yarnpkg.com', auth: 'npmAuthToken'}, + }, + { + url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', + pkg: null, + expect: {root: 'https://registry.yarnpkg.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: '@yarn/core', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@yarn/core.tgz', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: '@private/pkg', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com', auth: 'scopedPrivateAuthToken'}, + }, + { + url: 'https://some.cdn.com/some-hash/@private-pkg-1.0.0.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@private/pkg', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + ], + }, + { + title: 'mismatching registry and request paths', + config: { + '@private:registry': 'https://registry.myorg.com/api/npm/registry/', + '//registry.myorg.com/api/npm/registry/:_authToken': 'scopedPrivateAuthToken', + }, + requests: [ + { + url: 'https://registry.myorg.com/api/npm/registry/private---pkg.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com/api/npm/registry/', auth: 'scopedPrivateAuthToken'}, + }, + { + url: 'https://registry.myorg.com/api/packages/private---pkg.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com/api/packages/', auth: false}, + }, + ], + }, + { + title: 'using custom-host-suffix for registries where pathnames play a role', + config: { + '@private:registry': 'https://registry.myorg.com/api/npm/registry/', + '//registry.myorg.com/api/npm/registry/:_authToken': 'scopedPrivateAuthToken', + 'custom-host-suffix': 'registry.myorg.com', + }, + requests: [ + { + url: '@private/pkg', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com/api/npm/registry/', auth: 'scopedPrivateAuthToken'}, + }, + { + url: 'https://some.cdn.com/some-hash/@private-pkg-1.0.0.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@private/pkg', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://registry.myorg.com/api/packages/private---pkg.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com/api/packages/', auth: 'scopedPrivateAuthToken'}, + }, + ], + }, + { + title: 'using multiple entries for registries where pathnames play a role', + config: { + '@private:registry': 'https://registry.myorg.com/api/npm/registry/', + '//registry.myorg.com/api/npm/registry/:_authToken': 'scopedPrivateAuthToken', + '//registry.myorg.com/api/packages/:_authToken': 'scopedPrivateAuthToken', + }, + requests: [ + { + url: '@private/pkg', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com/api/npm/registry/', auth: 'scopedPrivateAuthToken'}, + }, + { + url: 'https://some.cdn.com/some-hash/@private-pkg-1.0.0.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + url: 'https://some.cdn.com/@private/pkg', + pkg: null, + expect: {root: 'https://some.cdn.com', auth: false}, + }, + { + skip: true, + url: 'https://registry.myorg.com/api/packages/private---pkg.tar.gz', + pkg: '@private/pkg', + expect: {root: 'https://registry.myorg.com/api/packages/', auth: 'scopedPrivateAuthToken'}, + }, + ], + }, + ]; + + testCases.forEach(testCase => { + describe(testCase.title, () => { + const registry = createRegistry(testCase.config); + testCase.requests.forEach(req => { + const desc = + `with request url ${req.url}${req.pkg ? ` in context of package ${req.pkg}` : ''} ` + + `auth is ${req.expect.auth ? req.expect.auth : 'not sent'}`; + (req.skip ? it.skip : req.only ? it.only : it)(desc, () => { + const requestParams = registry.request(req.url, {}, req.pkg); + expect(requestParams.url.substr(0, req.expect.root.length)).toBe(req.expect.root); + expect(requestParams.headers.authorization).toBe(req.expect.auth ? `Bearer ${req.expect.auth}` : undefined); + }); + }); + }); + }); - expect(requestParams.url).toBe(url); + // TODO - remove all these, but for now, keep them to see if they all pass when the bug is fixed + test('should not add authorization header if none configured', () => { + const url = 'https://registry.npmjs.org/yarn'; + const requestParams = createRegistry({}).request(url, {}, 'yarn'); + expect(requestParams.headers.authorization).toBeUndefined(); }); test('should not add authorization header if pathname not to registry', () => { - const testCwd = '.'; - const {mockRequestManager, mockRegistries, mockReporter} = createMocks(); - const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter); - const url = 'https://github.com/yarnpkg/yarn.tgz'; - - npmRegistry.request(url); - - const requestParams = mockRequestManager.request.mock.calls[0][0]; - + const config = {}; + const requestParams = createRegistry(config).request(url); expect(requestParams.headers.authorization).toBeUndefined(); }); test('should not add authorization header if pathname not to registry and always-auth is true', () => { - const testCwd = '.'; - const {mockRequestManager, mockRegistries, mockReporter} = createMocks(); - const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter); - const url = 'https://github.com/yarnpkg/yarn.tgz'; - - npmRegistry.config = { + const config = { 'always-auth': true, _authToken: 'testAuthToken', }; - npmRegistry.request(url); - - const requestParams = mockRequestManager.request.mock.calls[0][0]; - + const requestParams = createRegistry(config).request(url); expect(requestParams.headers.authorization).toBeUndefined(); }); test('should not add authorization header if pathname is to registry and always-auth is false', () => { - const testCwd = '.'; - const {mockRequestManager, mockRegistries, mockReporter} = createMocks(); - const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter); - const url = 'https://registry.npmjs.org/yarnpkg/yarn.tgz'; - - npmRegistry.config = { + const config = { // Default is: 'always-auth': false, _authToken: 'testAuthToken', }; - npmRegistry.request(url); - - const requestParams = mockRequestManager.request.mock.calls[0][0]; - + const requestParams = createRegistry(config).request(url); expect(requestParams.headers.authorization).toBeUndefined(); }); test('should not add authorization header if pathname is to registry and not scopped package', () => { - const testCwd = '.'; - const {mockRequestManager, mockRegistries, mockReporter} = createMocks(); - const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter); - const url = 'https://registry.npmjs.org/yarnpkg/yarn.tgz'; - - npmRegistry.config = { + const config = { _authToken: 'testAuthToken', }; - npmRegistry.request(url); - - const requestParams = mockRequestManager.request.mock.calls[0][0]; - + const requestParams = createRegistry(config).request(url); expect(requestParams.headers.authorization).toBeUndefined(); }); test('should add authorization header if pathname is to registry and always-auth is true', () => { - const testCwd = '.'; - const {mockRequestManager, mockRegistries, mockReporter} = createMocks(); - const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter); - const url = 'https://registry.npmjs.org/yarnpkg/yarn.tgz'; - - npmRegistry.config = { + const config = { 'always-auth': true, _authToken: 'testAuthToken', }; - npmRegistry.request(url); - - const requestParams = mockRequestManager.request.mock.calls[0][0]; - + const requestParams = createRegistry(config).request(url); expect(requestParams.headers.authorization).toBe('Bearer testAuthToken'); }); test('should add authorization header if pathname is to registry and is scopped package', () => { - const testCwd = '.'; - const {mockRequestManager, mockRegistries, mockReporter} = createMocks(); - const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter); - const url = 'https://registry.npmjs.org/@testScope%2fyarn.tgz'; - - npmRegistry.config = { + const config = { _authToken: 'testAuthToken', }; - npmRegistry.request(url); - - const requestParams = mockRequestManager.request.mock.calls[0][0]; - + const requestParams = createRegistry(config).request(url); expect(requestParams.headers.authorization).toBe('Bearer testAuthToken'); }); test('should add authorization header with token for custom registries with a scoped package', () => { - const testCwd = '.'; - const {mockRequestManager, mockRegistries, mockReporter} = createMocks(); - const npmRegistry = new NpmRegistry(testCwd, mockRegistries, mockRequestManager, mockReporter); - const url = 'https://some.other.registry/@testScope%2fyarn.tgz'; - - npmRegistry.config = { + const config = { '//some.other.registry/:_authToken': 'testScopedAuthToken', '@testScope:registry': '//some.other.registry/', }; - npmRegistry.request(url); + const requestParams = createRegistry(config).request(url); + expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); + }); - const requestParams = mockRequestManager.request.mock.calls[0][0]; + test('should add authorization header with token for default registry when using npm login --scope=@foo', () => { + const url = 'https://npmjs.registry.org/@foo%2fyarn.tgz'; + const config = { + '//npmjs.registry.org/:_authToken': 'testScopedAuthToken', + '@foo:registry': 'https://npmjs.registry.org/', + }; + const requestParams = createRegistry(config).request(url); + expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); + }); + test('should add authorization header with token for yarn registry as default with a scoped package', () => { + const url = 'https://registry.yarnpkg.com/@testScope%2fyarn.tgz'; + const config = { + '//registry.yarnpkg.com/:_authToken': 'testScopedAuthToken', + registry: 'https://registry.yarnpkg.com', + }; + const requestParams = createRegistry(config).request(url); + expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); + }); + + test('should add authorization header with token for per scope yarn registry with a scoped package', () => { + const url = 'https://registry.yarnpkg.com/@testScope%2fyarn.tgz'; + const config = { + '//registry.yarnpkg.com/:_authToken': 'testScopedAuthToken', + '@testScope:registry': 'https://registry.yarnpkg.com', + }; + const requestParams = createRegistry(config).request(url); + expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); + }); + + test('should not add authorization header if default registry is yarn and npm token exists', () => { + const url = 'https://registry.yarnpkg.com/@testScope%2fyarn.tgz'; + const config = { + '//registry.npmjs.com/:_authToken': 'testScopedAuthToken', + registry: 'https://registry.yarnpkg.com/', + }; + const requestParams = createRegistry(config).request(url); + expect(requestParams.headers.authorization).toBeUndefined(); + }); + + test('should not add authorization header if request pathname does not match registry pathname', () => { + const url = 'https://custom.registry.com/tarball/path/@testScope%2fyarn.tgz'; + const config = { + '//custom.registry.com/meta/path/:_authToken': 'testScopedAuthToken', + '@testScope:registry': 'https://custom.registry.com/meta/path/', + }; + const requestParams = createRegistry(config).request(url); + expect(requestParams.headers.authorization).toBeUndefined(); + }); + + test('should add authorization header if request pathname matches registry pathname', () => { + const url = 'https://custom.registry.com/custom/path/@testScope%2fyarn.tgz'; + const config = { + '//custom.registry.com/custom/path/:_authToken': 'testScopedAuthToken', + '@testScope:registry': 'https://custom.registry.com/custom/path/', + }; + const requestParams = createRegistry(config).request(url); + expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); + }); + + test('should add authorization header if pathname does not match but custom-host-suffix is used', () => { + const url = 'https://some.other.registry/tarball/path/@testScope%2fyarn.tgz'; + const config = { + '//some.other.registry/some/path/:_authToken': 'testScopedAuthToken', + '@testScope:registry': 'https://some.other.registry/some/path/', + 'custom-host-suffix': 'some.other.registry', + }; + const requestParams = createRegistry(config).request(url); expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); }); }); From 99ca0b6cf042360ffcedda723396e38e603f52c0 Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Sun, 14 Jan 2018 12:51:56 +0000 Subject: [PATCH 2/7] Fix the bug where npm private packages where not authed correctly --- __tests__/registries/npm-registry.js | 13 ++++--------- src/registries/npm-registry.js | 5 ++++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/__tests__/registries/npm-registry.js b/__tests__/registries/npm-registry.js index d6c3eea9ac..79026f87f2 100644 --- a/__tests__/registries/npm-registry.js +++ b/__tests__/registries/npm-registry.js @@ -211,8 +211,6 @@ describe('request', () => { expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, }, { - // THIS IS THE BUG!!! - skip: true, url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', pkg: '@yarn/core', expect: {root: 'https://registry.yarnpkg.com', auth: 'scopedNpmAuthToken'}, @@ -288,8 +286,6 @@ describe('request', () => { expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, }, { - // THIS IS THE BUG!!! - skip: true, url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', pkg: '@yarn/core', expect: {root: 'https://registry.yarnpkg.com', auth: 'scopedNpmAuthToken'}, @@ -367,8 +363,6 @@ describe('request', () => { expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, }, { - // THIS IS THE BUG!!! - skip: true, url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', pkg: '@yarn/core', expect: {root: 'https://registry.yarnpkg.com', auth: 'scopedNpmAuthToken'}, @@ -445,8 +439,6 @@ describe('request', () => { expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, }, { - // THIS IS THE BUG!!! - skip: true, url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', pkg: '@yarn/core', expect: {root: 'https://registry.yarnpkg.com', auth: 'npmAuthToken'}, @@ -454,7 +446,7 @@ describe('request', () => { { url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', pkg: null, - expect: {root: 'https://registry.yarnpkg.com', auth: false}, + expect: {root: 'https://registry.yarnpkg.com', auth: 'npmAuthToken'}, }, { url: 'https://some.cdn.com/@yarn/core.tgz', @@ -740,6 +732,9 @@ describe('isRequestToRegistry functional test', () => { ['http://foo.bar/foo/bar/baz', 'https://foo.bar:443/foo/'], ['https://foo.bar/foo/bar/baz', 'https://foo.bar:443/foo/'], ['HTTP://xn--xample-hva.com:80/foo/bar/baz', 'http://êxample.com/foo/bar/baz'], + // yarn and npm registries are interchangeable + ['https://registry.npmjs.org/foo/bar', 'https://registry.npmjs.org/'], + ['https://registry.yarnpkg.com/foo/bar', 'https://registry.npmjs.org/'], ]; const invalidRegistryUrls = [ diff --git a/src/registries/npm-registry.js b/src/registries/npm-registry.js index 501ef18a48..2637169e67 100644 --- a/src/registries/npm-registry.js +++ b/src/registries/npm-registry.js @@ -110,8 +110,11 @@ export default class NpmRegistry extends Registry { const registryPath = registryParsed.path || ''; const customHostSuffix = this.getRegistryOrGlobalOption(registryUrl, 'custom-host-suffix'); + const requestToRegistryHost = () => requestHost === registryHost; + const requestToNpm = () => YARN_REGISTRY.includes(requestHost) && DEFAULT_REGISTRY.includes(registryHost); + return ( - requestHost === registryHost && + (requestToRegistryHost() || requestToNpm()) && (requestPath.startsWith(registryPath) || // For some registries, the package path does not prefix with the registry path (typeof customHostSuffix === 'string' && requestHost.endsWith(customHostSuffix))) From a0500aaa80d7fe54373729b67c8962d58e083a4e Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Sun, 14 Jan 2018 12:52:48 +0000 Subject: [PATCH 3/7] Remove the old tests that have now been compacted into test gen --- __tests__/registries/npm-registry.js | 143 --------------------------- 1 file changed, 143 deletions(-) diff --git a/__tests__/registries/npm-registry.js b/__tests__/registries/npm-registry.js index 79026f87f2..ef2b024996 100644 --- a/__tests__/registries/npm-registry.js +++ b/__tests__/registries/npm-registry.js @@ -572,149 +572,6 @@ describe('request', () => { }); }); }); - - // TODO - remove all these, but for now, keep them to see if they all pass when the bug is fixed - test('should not add authorization header if none configured', () => { - const url = 'https://registry.npmjs.org/yarn'; - const requestParams = createRegistry({}).request(url, {}, 'yarn'); - expect(requestParams.headers.authorization).toBeUndefined(); - }); - - test('should not add authorization header if pathname not to registry', () => { - const url = 'https://github.com/yarnpkg/yarn.tgz'; - const config = {}; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBeUndefined(); - }); - - test('should not add authorization header if pathname not to registry and always-auth is true', () => { - const url = 'https://github.com/yarnpkg/yarn.tgz'; - const config = { - 'always-auth': true, - _authToken: 'testAuthToken', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBeUndefined(); - }); - - test('should not add authorization header if pathname is to registry and always-auth is false', () => { - const url = 'https://registry.npmjs.org/yarnpkg/yarn.tgz'; - const config = { - // Default is: 'always-auth': false, - _authToken: 'testAuthToken', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBeUndefined(); - }); - - test('should not add authorization header if pathname is to registry and not scopped package', () => { - const url = 'https://registry.npmjs.org/yarnpkg/yarn.tgz'; - const config = { - _authToken: 'testAuthToken', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBeUndefined(); - }); - - test('should add authorization header if pathname is to registry and always-auth is true', () => { - const url = 'https://registry.npmjs.org/yarnpkg/yarn.tgz'; - const config = { - 'always-auth': true, - _authToken: 'testAuthToken', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBe('Bearer testAuthToken'); - }); - - test('should add authorization header if pathname is to registry and is scopped package', () => { - const url = 'https://registry.npmjs.org/@testScope%2fyarn.tgz'; - const config = { - _authToken: 'testAuthToken', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBe('Bearer testAuthToken'); - }); - - test('should add authorization header with token for custom registries with a scoped package', () => { - const url = 'https://some.other.registry/@testScope%2fyarn.tgz'; - const config = { - '//some.other.registry/:_authToken': 'testScopedAuthToken', - '@testScope:registry': '//some.other.registry/', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); - }); - - test('should add authorization header with token for default registry when using npm login --scope=@foo', () => { - const url = 'https://npmjs.registry.org/@foo%2fyarn.tgz'; - const config = { - '//npmjs.registry.org/:_authToken': 'testScopedAuthToken', - '@foo:registry': 'https://npmjs.registry.org/', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); - }); - - test('should add authorization header with token for yarn registry as default with a scoped package', () => { - const url = 'https://registry.yarnpkg.com/@testScope%2fyarn.tgz'; - const config = { - '//registry.yarnpkg.com/:_authToken': 'testScopedAuthToken', - registry: 'https://registry.yarnpkg.com', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); - }); - - test('should add authorization header with token for per scope yarn registry with a scoped package', () => { - const url = 'https://registry.yarnpkg.com/@testScope%2fyarn.tgz'; - const config = { - '//registry.yarnpkg.com/:_authToken': 'testScopedAuthToken', - '@testScope:registry': 'https://registry.yarnpkg.com', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); - }); - - test('should not add authorization header if default registry is yarn and npm token exists', () => { - const url = 'https://registry.yarnpkg.com/@testScope%2fyarn.tgz'; - const config = { - '//registry.npmjs.com/:_authToken': 'testScopedAuthToken', - registry: 'https://registry.yarnpkg.com/', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBeUndefined(); - }); - - test('should not add authorization header if request pathname does not match registry pathname', () => { - const url = 'https://custom.registry.com/tarball/path/@testScope%2fyarn.tgz'; - const config = { - '//custom.registry.com/meta/path/:_authToken': 'testScopedAuthToken', - '@testScope:registry': 'https://custom.registry.com/meta/path/', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBeUndefined(); - }); - - test('should add authorization header if request pathname matches registry pathname', () => { - const url = 'https://custom.registry.com/custom/path/@testScope%2fyarn.tgz'; - const config = { - '//custom.registry.com/custom/path/:_authToken': 'testScopedAuthToken', - '@testScope:registry': 'https://custom.registry.com/custom/path/', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); - }); - - test('should add authorization header if pathname does not match but custom-host-suffix is used', () => { - const url = 'https://some.other.registry/tarball/path/@testScope%2fyarn.tgz'; - const config = { - '//some.other.registry/some/path/:_authToken': 'testScopedAuthToken', - '@testScope:registry': 'https://some.other.registry/some/path/', - 'custom-host-suffix': 'some.other.registry', - }; - const requestParams = createRegistry(config).request(url); - expect(requestParams.headers.authorization).toBe('Bearer testScopedAuthToken'); - }); }); describe('isRequestToRegistry functional test', () => { From c1a10a28678c6c8468f1c7df492b3e0552456e4e Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Sun, 14 Jan 2018 12:54:05 +0000 Subject: [PATCH 4/7] Clarify the naming of the request url check --- src/registries/npm-registry.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registries/npm-registry.js b/src/registries/npm-registry.js index 2637169e67..a07fa7e3d8 100644 --- a/src/registries/npm-registry.js +++ b/src/registries/npm-registry.js @@ -111,10 +111,10 @@ export default class NpmRegistry extends Registry { const customHostSuffix = this.getRegistryOrGlobalOption(registryUrl, 'custom-host-suffix'); const requestToRegistryHost = () => requestHost === registryHost; - const requestToNpm = () => YARN_REGISTRY.includes(requestHost) && DEFAULT_REGISTRY.includes(registryHost); + const requestToYarn = () => YARN_REGISTRY.includes(requestHost) && DEFAULT_REGISTRY.includes(registryHost); return ( - (requestToRegistryHost() || requestToNpm()) && + (requestToRegistryHost() || requestToYarn()) && (requestPath.startsWith(registryPath) || // For some registries, the package path does not prefix with the registry path (typeof customHostSuffix === 'string' && requestHost.endsWith(customHostSuffix))) From 6191e8090d0c8fdf4fba576cebad40223e3676ef Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Sun, 14 Jan 2018 13:23:25 +0000 Subject: [PATCH 5/7] Alternative approach for supporting registries with multiple paths --- __tests__/registries/npm-registry.js | 3 +- src/registries/npm-registry.js | 48 ++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/__tests__/registries/npm-registry.js b/__tests__/registries/npm-registry.js index ef2b024996..0d2fdf6b9b 100644 --- a/__tests__/registries/npm-registry.js +++ b/__tests__/registries/npm-registry.js @@ -525,7 +525,7 @@ describe('request', () => { ], }, { - title: 'using multiple entries for registries where pathnames play a role', + title: 'using multiple config entries for registries where pathnames play a role', config: { '@private:registry': 'https://registry.myorg.com/api/npm/registry/', '//registry.myorg.com/api/npm/registry/:_authToken': 'scopedPrivateAuthToken', @@ -548,7 +548,6 @@ describe('request', () => { expect: {root: 'https://some.cdn.com', auth: false}, }, { - skip: true, url: 'https://registry.myorg.com/api/packages/private---pkg.tar.gz', pkg: '@private/pkg', expect: {root: 'https://registry.myorg.com/api/packages/', auth: 'scopedPrivateAuthToken'}, diff --git a/src/registries/npm-registry.js b/src/registries/npm-registry.js index a07fa7e3d8..3a553d1131 100644 --- a/src/registries/npm-registry.js +++ b/src/registries/npm-registry.js @@ -72,6 +72,19 @@ function normalizePath(val: mixed): ?string { return resolveWithHome(val); } +type UrlParts = { + host: string, + path: string, +}; + +function urlParts(requestUrl: string): UrlParts { + const normalizedUrl = normalizeUrl(requestUrl); + const parsed = url.parse(normalizedUrl); + const host = parsed.host || ''; + const path = parsed.path || ''; + return {host, path}; +} + export default class NpmRegistry extends Registry { constructor(cwd: string, registries: ConfigRegistries, requestManager: RequestManager, reporter: Reporter) { super(cwd, registries, requestManager, reporter); @@ -100,24 +113,18 @@ export default class NpmRegistry extends Registry { } isRequestToRegistry(requestUrl: string, registryUrl: string): boolean { - const normalizedRequestUrl = normalizeUrl(requestUrl); - const normalizedRegistryUrl = normalizeUrl(registryUrl); - const requestParsed = url.parse(normalizedRequestUrl); - const registryParsed = url.parse(normalizedRegistryUrl); - const requestHost = requestParsed.host || ''; - const registryHost = registryParsed.host || ''; - const requestPath = requestParsed.path || ''; - const registryPath = registryParsed.path || ''; + const request = urlParts(requestUrl); + const registry = urlParts(registryUrl); const customHostSuffix = this.getRegistryOrGlobalOption(registryUrl, 'custom-host-suffix'); - const requestToRegistryHost = () => requestHost === registryHost; - const requestToYarn = () => YARN_REGISTRY.includes(requestHost) && DEFAULT_REGISTRY.includes(registryHost); + const requestToRegistryHost = () => request.host === registry.host; + const requestToYarn = () => YARN_REGISTRY.includes(request.host) && DEFAULT_REGISTRY.includes(registry.host); return ( (requestToRegistryHost() || requestToYarn()) && - (requestPath.startsWith(registryPath) || + (request.path.startsWith(registry.path) || // For some registries, the package path does not prefix with the registry path - (typeof customHostSuffix === 'string' && requestHost.endsWith(customHostSuffix))) + (typeof customHostSuffix === 'string' && request.host.endsWith(customHostSuffix))) ); } @@ -136,7 +143,7 @@ export default class NpmRegistry extends Registry { opts.headers, ); - const isToRegistry = this.isRequestToRegistry(requestUrl, registry); + const isToRegistry = this.isRequestToRegistry(requestUrl, registry) || this.requestNeedsAuth(requestUrl); // this.token must be checked to account for publish requests on non-scopped packages if (this.token || (isToRegistry && (alwaysAuth || this.isScopedPackage(packageIdent)))) { @@ -159,6 +166,21 @@ export default class NpmRegistry extends Registry { }); } + requestNeedsAuth(requestUrl: string): boolean { + const config = this.config; + const requestParts = urlParts(requestUrl); + return !!Object.keys(config).find(option => { + const parts = option.split(':'); + if (parts.length === 2 && parts[1] === '_authToken') { + const registryParts = urlParts(parts[0]); + if (requestParts.host === registryParts.host && requestParts.path.startsWith(registryParts.path)) { + return true; + } + } + return false; + }); + } + async checkOutdated(config: Config, name: string, range: string): CheckOutdatedReturn { const req = await this.request(NpmRegistry.escapeName(name), { headers: {Accept: 'application/json'}, From afce6ff675b2c86447ce716a4010abbe2095aa4b Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Sun, 14 Jan 2018 13:29:24 +0000 Subject: [PATCH 6/7] Improve the naming and order of the test suites --- __tests__/registries/npm-registry.js | 62 ++++++++++++++-------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/__tests__/registries/npm-registry.js b/__tests__/registries/npm-registry.js index 0d2fdf6b9b..c3a088bc3f 100644 --- a/__tests__/registries/npm-registry.js +++ b/__tests__/registries/npm-registry.js @@ -98,7 +98,7 @@ describe('request', () => { const testCases = [ { - title: 'default registry is npm, scoped packages on private registry', + title: 'using npm as default registry and private registry for scoped packages', config: { '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', '@private:registry': 'https://registry.myorg.com/', @@ -172,7 +172,7 @@ describe('request', () => { ], }, { - title: 'default registry is npm, scoped packages in npm and private registry', + title: 'using scoped packages in both npm and private registry', config: { '//registry.npmjs.org/:_authToken': 'scopedNpmAuthToken', '@yarn:registry': 'https://registry.npmjs.org/', @@ -248,7 +248,7 @@ describe('request', () => { ], }, { - title: 'default registry is npm, global npm auth, and one scope on private registry', + title: 'using authenticated npm and private registry for scoped packages', config: { _authToken: 'scopedNpmAuthToken', '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', @@ -323,54 +323,53 @@ describe('request', () => { ], }, { - title: 'default registry is a private registry and one scope on npm registry', + title: 'using npm with always-auth and private registry for scoped packages', config: { 'always-auth': true, - registry: 'https://registry.myorg.com/', - '//registry.myorg.com/:_authToken': 'privateAuthToken', - '//registry.npmjs.org/:_authToken': 'scopedNpmAuthToken', - '@yarn:registry': 'https://registry.npmjs.org/', + '//registry.npmjs.org/:_authToken': 'npmAuthToken', + '@private:registry': 'https://registry.myorg.com/', + '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', }, requests: [ { url: 'yarn', pkg: 'yarn', - expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, }, { url: '@yarn%2fcore', pkg: '@yarn/core', - expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, }, { url: '-/package/yarn/dist-tags', pkg: 'yarn', - expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, }, { url: '-/package/@yarn%2fcore/dist-tags', pkg: '@yarn/core', - expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, }, { url: '-/user/token/abcdef', pkg: null, - expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, }, { url: 'https://registry.npmjs.org/dist/-/@yarn-core-1.0.0.tgz', pkg: '@yarn/core', - expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, + expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, }, { url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', pkg: '@yarn/core', - expect: {root: 'https://registry.yarnpkg.com', auth: 'scopedNpmAuthToken'}, + expect: {root: 'https://registry.yarnpkg.com', auth: 'npmAuthToken'}, }, { url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', pkg: null, - expect: {root: 'https://registry.yarnpkg.com', auth: false}, + expect: {root: 'https://registry.yarnpkg.com', auth: 'npmAuthToken'}, }, { url: 'https://some.cdn.com/@yarn/core.tgz', @@ -385,7 +384,7 @@ describe('request', () => { { url: '@private/pkg', pkg: '@private/pkg', - expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, + expect: {root: 'https://registry.myorg.com', auth: 'scopedPrivateAuthToken'}, }, { url: 'https://some.cdn.com/some-hash/@private-pkg-1.0.0.tar.gz', @@ -400,53 +399,54 @@ describe('request', () => { ], }, { - title: 'default registry is npm with always-auth and one scope on private registry', + title: 'using private registry as default registry and scoped packages on npm registry', config: { 'always-auth': true, - '//registry.npmjs.org/:_authToken': 'npmAuthToken', - '@private:registry': 'https://registry.myorg.com/', - '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', + registry: 'https://registry.myorg.com/', + '//registry.myorg.com/:_authToken': 'privateAuthToken', + '//registry.npmjs.org/:_authToken': 'scopedNpmAuthToken', + '@yarn:registry': 'https://registry.npmjs.org/', }, requests: [ { url: 'yarn', pkg: 'yarn', - expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, }, { url: '@yarn%2fcore', pkg: '@yarn/core', - expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, }, { url: '-/package/yarn/dist-tags', pkg: 'yarn', - expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, }, { url: '-/package/@yarn%2fcore/dist-tags', pkg: '@yarn/core', - expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, }, { url: '-/user/token/abcdef', pkg: null, - expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, }, { url: 'https://registry.npmjs.org/dist/-/@yarn-core-1.0.0.tgz', pkg: '@yarn/core', - expect: {root: 'https://registry.npmjs.org', auth: 'npmAuthToken'}, + expect: {root: 'https://registry.npmjs.org', auth: 'scopedNpmAuthToken'}, }, { url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', pkg: '@yarn/core', - expect: {root: 'https://registry.yarnpkg.com', auth: 'npmAuthToken'}, + expect: {root: 'https://registry.yarnpkg.com', auth: 'scopedNpmAuthToken'}, }, { url: 'https://registry.yarnpkg.com/dist/-/@yarn-core-1.0.0.tgz', pkg: null, - expect: {root: 'https://registry.yarnpkg.com', auth: 'npmAuthToken'}, + expect: {root: 'https://registry.yarnpkg.com', auth: false}, }, { url: 'https://some.cdn.com/@yarn/core.tgz', @@ -461,7 +461,7 @@ describe('request', () => { { url: '@private/pkg', pkg: '@private/pkg', - expect: {root: 'https://registry.myorg.com', auth: 'scopedPrivateAuthToken'}, + expect: {root: 'https://registry.myorg.com', auth: 'privateAuthToken'}, }, { url: 'https://some.cdn.com/some-hash/@private-pkg-1.0.0.tar.gz', @@ -476,7 +476,7 @@ describe('request', () => { ], }, { - title: 'mismatching registry and request paths', + title: 'registry url and request url path sensitivity', config: { '@private:registry': 'https://registry.myorg.com/api/npm/registry/', '//registry.myorg.com/api/npm/registry/:_authToken': 'scopedPrivateAuthToken', From 6a4b0d4b56b61affb50b9eda486dc05e237a92e8 Mon Sep 17 00:00:00 2001 From: Karolis Narkevicius Date: Sun, 14 Jan 2018 13:48:48 +0000 Subject: [PATCH 7/7] Clarify the registry request test suite names further --- __tests__/registries/npm-registry.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/__tests__/registries/npm-registry.js b/__tests__/registries/npm-registry.js index c3a088bc3f..ce0f97e464 100644 --- a/__tests__/registries/npm-registry.js +++ b/__tests__/registries/npm-registry.js @@ -98,7 +98,7 @@ describe('request', () => { const testCases = [ { - title: 'using npm as default registry and private registry for scoped packages', + title: 'using npm as default registry and using private registry for scoped packages', config: { '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', '@private:registry': 'https://registry.myorg.com/', @@ -248,7 +248,7 @@ describe('request', () => { ], }, { - title: 'using authenticated npm and private registry for scoped packages', + title: 'using authenticated npm and using private registry for scoped packages', config: { _authToken: 'scopedNpmAuthToken', '//registry.myorg.com/:_authToken': 'scopedPrivateAuthToken', @@ -323,7 +323,7 @@ describe('request', () => { ], }, { - title: 'using npm with always-auth and private registry for scoped packages', + title: 'using npm with always-auth and using private registry for scoped packages', config: { 'always-auth': true, '//registry.npmjs.org/:_authToken': 'npmAuthToken', @@ -399,7 +399,7 @@ describe('request', () => { ], }, { - title: 'using private registry as default registry and scoped packages on npm registry', + title: 'using private registry as default registry and using scoped packages on npm registry', config: { 'always-auth': true, registry: 'https://registry.myorg.com/',