From 7fd264440e1656071ccb3fc00fc59082c5aec2d0 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sat, 26 Sep 2015 22:13:55 +0800 Subject: [PATCH] feat: list packages by username GET /-/users/:user/packages return user packages list { "user": { "name": $name }, "packages": [ { "name": $name, "description": $description, "version": $version }, ... ], } closes #661 --- .jshintignore | 3 + .travis.yml | 5 +- Makefile | 4 +- README.md | 13 +-- config/index.js | 2 - controllers/registry/package/list_by_user.js | 29 +++++++ dispatch.js | 4 +- docs/web/readme.md | 2 +- index.js | 2 - models/index.js | 5 +- package.json | 2 +- routes/registry.js | 6 +- services/package.js | 2 +- sync/sync_exist.js | 3 - sync/sync_since.js | 4 +- .../registry/package/list_by_user.test.js | 87 +++++++++++++++++++ test/init_db.js | 1 + test/services/package.test.js | 2 +- test/utils.js | 6 +- view/web/profile.html | 8 +- worker.js | 2 - 21 files changed, 146 insertions(+), 46 deletions(-) create mode 100644 controllers/registry/package/list_by_user.js create mode 100644 test/controllers/registry/package/list_by_user.test.js diff --git a/.jshintignore b/.jshintignore index 63c6333..e6f448f 100644 --- a/.jshintignore +++ b/.jshintignore @@ -2,3 +2,6 @@ node_modules/ coverage/ .tmp/ .git/ +tools/ +public/ +test/ diff --git a/.travis.yml b/.travis.yml index aeb9538..14ff8fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,10 @@ sudo: false language: node_js node_js: - - 'iojs-2' + - '1' + - '2' + - '3' + - '4' addons: - postgresql: '9.3' script: 'make test-travis-all' diff --git a/Makefile b/Makefile index 39ba578..a68bbbd 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,12 @@ REPORTER = spec TIMEOUT = 30000 MOCHA_OPTS = DB = sqlite -DISTURL = http://npm.taobao.org/mirrors/iojs +DISTURL = https://npm.taobao.org/mirrors/iojs BIN = iojs ifeq ($(findstring io.js, $(shell which node)),) BIN = node - DISTURL = http://npm.taobao.org/mirrors/node + DISTURL = https://npm.taobao.org/mirrors/node endif install: diff --git a/README.md b/README.md index 671fcc4..01a8b0a 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,8 @@ cnpmjs.org [![NPM version][npm-image]][npm-url] [![build status][travis-image]][travis-url] [![Test coverage][cov-image]][cov-url] -[![Gittip][gittip-image]][gittip-url] [![David deps][david-image]][david-url] -[![node version][node-image]][node-url] [![npm download][download-image]][download-url] -[![gitter][gitter-image]][gitter-url] [npm-image]: http://cnpmjs.org/badge/v/cnpmjs.org.svg?style=flat-square [npm-url]: http://cnpmjs.org/package/cnpmjs.org @@ -16,16 +13,10 @@ cnpmjs.org [travis-url]: https://travis-ci.org/cnpm/cnpmjs.org [cov-image]: http://codecov.io/github/cnpm/cnpmjs.org/coverage.svg?branch=master [cov-url]: http://codecov.io/github/cnpm/cnpmjs.org?branch=master -[gittip-image]: https://img.shields.io/gittip/fengmk2.svg?style=flat-square -[gittip-url]: https://www.gittip.com/fengmk2/ [david-image]: https://img.shields.io/david/cnpm/cnpmjs.org.svg?style=flat-square [david-url]: https://david-dm.org/cnpm/cnpmjs.org -[node-image]: https://img.shields.io/badge/node.js-%3E=_0.11-red.svg?style=flat-square -[node-url]: http://nodejs.org/download/ [download-image]: https://img.shields.io/npm/dm/cnpmjs.org.svg?style=flat-square [download-url]: https://npmjs.org/package/cnpmjs.org -[gitter-image]: https://badges.gitter.im/Join%20Chat.svg -[gitter-url]: https://gitter.im/cnpm/cnpmjs.org?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge ![logo](https://raw.github.com/cnpm/cnpmjs.org/master/logo.png) @@ -120,8 +111,8 @@ Tips: make sure your code is following the [node-style-guide](https://github.com ## Sponsors -- [![UCloud云计算](https://www.ucloud.cn/www/img/www/logo.png)](http://www.ucloud.cn/sdk?sem=sdk-CNPMJS) +- [![UCloud云计算](https://www.ucloud.cn/static/style/images/about/logo.png)](http://www.ucloud.cn?sem=sdk-CNPMJS) ## License -MIT +[MIT](LICENSE.txt) diff --git a/config/index.js b/config/index.js index b2917f1..b5928e1 100644 --- a/config/index.js +++ b/config/index.js @@ -1,6 +1,4 @@ /**! - * cnpmjs.org - config/index.js - * * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed * diff --git a/controllers/registry/package/list_by_user.js b/controllers/registry/package/list_by_user.js new file mode 100644 index 0000000..be79f33 --- /dev/null +++ b/controllers/registry/package/list_by_user.js @@ -0,0 +1,29 @@ +/**! + * list packages by username + * + * Copyright(c) cnpmjs.org and other contributors. + * MIT Licensed + * + * Authors: + * fengmk2 (http://fengmk2.com) + */ + +'use strict'; + +/** + * Module dependencies. + */ + +const packageService = require('../../../services/package'); + +module.exports = function*() { + const username = this.params.user; + const packages = yield packageService.listModulesByUser(username); + + this.body = { + user: { + name: username, + }, + packages: packages, + }; +}; diff --git a/dispatch.js b/dispatch.js index 2a1c0bc..0db1c00 100644 --- a/dispatch.js +++ b/dispatch.js @@ -1,12 +1,10 @@ /**! - * cnpmjs.org - dispatch.js - * * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed * * Authors: * dead_horse - * fengmk2 (http://fengmk2.github.com) + * fengmk2 (http://fengmk2.com) */ 'use strict'; diff --git a/docs/web/readme.md b/docs/web/readme.md index 9893242..c8040c5 100644 --- a/docs/web/readme.md +++ b/docs/web/readme.md @@ -144,4 +144,4 @@ Release [History](/history). ## Sponsors -- [![UCloud云计算](https://www.ucloud.cn/www/img/www/logo.png)](http://www.ucloud.cn/sdk?sem=sdk-CNPMJS) +- [![UCloud云计算](https://www.ucloud.cn/static/style/images/about/logo.png)](http://www.ucloud.cn?sem=sdk-CNPMJS) diff --git a/index.js b/index.js index c4863b2..cdc513e 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,4 @@ /**! - * cnpmjs.org - index.js - * * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed * diff --git a/models/index.js b/models/index.js index 45bb288..c9c28a2 100644 --- a/models/index.js +++ b/models/index.js @@ -1,11 +1,9 @@ /**! - * cnpmjs.org - models/index.js - * * Copyright(c) fengmk2 and other contributors. * MIT Licensed * * Authors: - * fengmk2 (http://fengmk2.github.com) + * fengmk2 (http://fengmk2.com) */ 'use strict'; @@ -15,7 +13,6 @@ */ var path = require('path'); -var Sequelize = require('sequelize'); var sequelize = require('../common/sequelize'); function load(name) { diff --git a/package.json b/package.json index 156144e..5efcaf8 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "registry" ], "engines": { - "node": ">= 0.11.14" + "node": ">= 1.0.0" }, "author": [ "fengmk2 (http://fengmk2.github.com)", diff --git a/routes/registry.js b/routes/registry.js index c77813c..052f9d3 100644 --- a/routes/registry.js +++ b/routes/registry.js @@ -1,12 +1,10 @@ /**! - * cnpmjs.org - routes/registry.js - * * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed * * Authors: * dead_horse - * fengmk2 (http://fengmk2.github.com) + * fengmk2 (http://fengmk2.com) */ "use strict"; @@ -36,6 +34,7 @@ var removeOneVersion = require('../controllers/registry/package/remove_version') var updatePackage = require('../controllers/registry/package/update'); var downloadPackage = require('../controllers/registry/package/download'); var downloadTotal = require('../controllers/registry/package/download_total'); +var listPackagesByUser = require('../controllers/registry/package/list_by_user'); var addUser = require('../controllers/registry/user/add'); var showUser = require('../controllers/registry/user/show'); @@ -113,6 +112,7 @@ function routes(app) { // list all packages of user app.get('/-/by-user/:user', userPackage.list); + app.get('/-/users/:user/packages', listPackagesByUser); // download times app.get('/downloads/range/:range/:name', downloadTotal); diff --git a/services/package.js b/services/package.js index f1a55b3..bfa73d3 100644 --- a/services/package.js +++ b/services/package.js @@ -128,7 +128,7 @@ exports.listModules = function* (names) { id: ids }, attributes: [ - 'name', 'description' + 'name', 'description', 'version', ] }); return rows; diff --git a/sync/sync_exist.js b/sync/sync_exist.js index 1dd7cd4..ed9a887 100644 --- a/sync/sync_exist.js +++ b/sync/sync_exist.js @@ -1,6 +1,4 @@ /*! - * cnpmjs.org - sync/sync_exist.js - * * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed * @@ -16,7 +14,6 @@ var debug = require('debug')('cnpmjs.org:sync:sync_exist'); var Status = require('./status'); -var ms = require('humanize-ms'); var thunkify = require('thunkify-wrap'); var config = require('../config'); var npmService = require('../services/npm'); diff --git a/sync/sync_since.js b/sync/sync_since.js index 5962dba..2f47300 100644 --- a/sync/sync_since.js +++ b/sync/sync_since.js @@ -1,7 +1,7 @@ /**! * sync packages since by some days ago * - * Copyright(c) fengmk2 and other contributors. + * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed * * Authors: @@ -55,7 +55,7 @@ function* sync(sinceTimestamp) { console.log('All packages sync done, successes %d, fails %d', worker.successes.length, worker.fails.length); process.exit(0); -}; +} co(function* () { var timestamp = Date.now() - ms(process.argv[2] || '30d'); diff --git a/test/controllers/registry/package/list_by_user.test.js b/test/controllers/registry/package/list_by_user.test.js new file mode 100644 index 0000000..34a78e5 --- /dev/null +++ b/test/controllers/registry/package/list_by_user.test.js @@ -0,0 +1,87 @@ +/**! + * Copyright(c) cnpmjs.org and other contributors. + * MIT Licensed + * + * Authors: + * fengmk2 (http://fengmk2.com) + */ + +'use strict'; + +/** + * Module dependencies. + */ + +var request = require('supertest'); +var mm = require('mm'); +var should = require('should'); +var app = require('../../../../servers/registry'); +var utils = require('../../../utils'); + +describe('test/controllers/registry/package/list_by_user.test.js', function () { + var user = 'cnpmjstest_list_by_user'; + var userauth = 'Basic ' + new Buffer(user + ':' + user).toString('base64'); + + afterEach(mm.restore); + + before(function (done) { + var pkg = utils.getPackage('@cnpmtest/list_by_user_module1', '1.0.1', user); + request(app) + .put('/' + pkg.name) + .set('authorization', userauth) + .send(pkg) + .expect(201, function (err) { + should.not.exist(err); + + var pkg2 = utils.getPackage('@cnpmtest/list_by_user_module2', '2.0.0', user); + request(app) + .put('/' + pkg2.name) + .set('authorization', userauth) + .send(pkg2) + .expect(201, done); + }); + }); + + describe('GET /-/users/:user/packages', function () { + it('should get 200', function (done) { + var url = '/-/users/' + user + '/packages'; + request(app) + .get(url) + .expect(function(res) { + var data = res.body; + data.user.name.should.equal(user); + var map = {}; + data.packages.forEach(function(pkg) { + map[pkg.name] = pkg; + }); + map['@cnpmtest/list_by_user_module1'].should.be.an.Object; + map['@cnpmtest/list_by_user_module1'].should.eql({ + name: '@cnpmtest/list_by_user_module1', + description: '', + version: '1.0.1', + }); + + map['@cnpmtest/list_by_user_module2'].should.be.an.Object; + map['@cnpmtest/list_by_user_module2'].should.eql({ + name: '@cnpmtest/list_by_user_module2', + description: '', + version: '2.0.0', + }); + }) + .expect(200, done); + }); + + it('should get empty packages list when user not exists', function (done) { + var url = '/-/users/not-exist-username/packages'; + request(app) + .get(url) + .expect({ + user: { + name: 'not-exist-username', + }, + packages: [], + }) + .expect(200, done); + }); + }); +}); diff --git a/test/init_db.js b/test/init_db.js index 0ed5d23..5cf1e04 100644 --- a/test/init_db.js +++ b/test/init_db.js @@ -38,6 +38,7 @@ var usernames = [ 'cnpmjstest10', // admin 'cnpmjstestAdmin2', // other admin 'cnpmjstestAdmin3', // other admin + 'cnpmjstest_list_by_user', ]; var count = usernames.length; diff --git a/test/services/package.test.js b/test/services/package.test.js index 7aecda2..31dea41 100644 --- a/test/services/package.test.js +++ b/test/services/package.test.js @@ -124,7 +124,7 @@ describe('test/services/package.test.js', function () { var mods = yield* Package.listPublicModulesByUser('listPublicModuleNamesByUser-user'); mods.should.length(3); mods.forEach(function (mod) { - mod.toJSON().should.have.keys('name', 'description'); + mod.toJSON().should.have.keys('name', 'description', 'version'); mod.name.should.containEql('listPublicModuleNamesByUser-module'); }); }); diff --git a/test/utils.js b/test/utils.js index ccf44ad..21f9d10 100644 --- a/test/utils.js +++ b/test/utils.js @@ -1,11 +1,9 @@ /**! - * cnpmjs.org - test/utils.js - * - * Copyright(c) fengmk2 and other contributors. + * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed * * Authors: - * fengmk2 (http://fengmk2.github.com) + * fengmk2 (http://fengmk2.com) */ 'use strict'; diff --git a/view/web/profile.html b/view/web/profile.html index 8ec84aa..798101f 100644 --- a/view/web/profile.html +++ b/view/web/profile.html @@ -59,10 +59,12 @@ <% if (!packages.length) { %>
Can not found any package by <%= user.name %>.
<% } %> - <% for (var i = 0; i < packages.length; i++) { %> + <% for (var i = 0; i < packages.length; i++) { + var package = packages[i]; + %>
- <%= packages[i].name %> - <%= packages[i].description %> + <%= package.name %> + (latest: <%= package.version %>) <%= package.description %>
<% } %> diff --git a/worker.js b/worker.js index df6e16d..919b242 100644 --- a/worker.js +++ b/worker.js @@ -1,6 +1,4 @@ /**! - * cnpmjs.org - worker.js - * * Copyright(c) cnpmjs.org and other contributors. * MIT Licensed *