Ver código fonte

Add pagination to user page

sbkwgh 8 anos atrás
pai
commit
4698a1d331
3 arquivos alterados com 84 adições e 9 exclusões
  1. 10 0
      models/user.js
  2. 33 9
      routes/user.js
  3. 41 0
      test/user.js

+ 10 - 0
models/user.js

@@ -21,6 +21,16 @@ module.exports = (sequelize, DataTypes) => {
 		classMethods: {
 			associate (models) {
 				User.hasMany(models.Post)
+			},
+			includeOptions (lastId, limit) {
+				let models = sequelize.models
+				let options = models.Post.includeOptions()[0]
+
+				options.where = { id: { $gt: lastId } }
+				options.limit = limit
+				options.order = [['id', 'ASC']]
+
+				return [options]
 			}
 		}
 	})

+ 33 - 9
routes/user.js

@@ -3,9 +3,7 @@ let express = require('express')
 let router = express.Router()
 
 const Errors = require('../lib/errors.js')
-let Models = require('../models')
-let User = Models.User
-let AdminToken = Models.AdminToken
+let { User, Post, AdminToken } = require('../models')
 
 function setUserSession(req, res, username, admin) {
 	req.session.loggedIn = true
@@ -125,22 +123,48 @@ router.get('/:username', async (req, res) => {
 		}
 
 		if(req.query.posts) {
+			let lastId = 0
+			let limit = 10
+
+			if(+req.query.lastId > 0) lastId = +req.query.lastId
+			if(+req.query.limit > 0) limit = +req.query.limit
+
 			queryObj.include = [{
-				model: Models.Post,
-				include: Models.Post.includeOptions()
+				model: Post,
+				include: Post.includeOptions()
 			}]
-		}
 
-		let user = await User.findOne(queryObj)
+			let user = await User.findOne(queryObj)
+			if(!user) throw Errors.accountDoesNotExist
 
-		if(!user) throw Errors.accountDoesNotExist
+			let maxId = await Post.max('id', { where: { userId: user.id } })
 
-		res.json(user.toJSON())
+			let resUser = user.toJSON()
+			let lastPost = user.Posts.slice(-1)[0]
+			resUser.meta = {}
+
+			if(!lastPost || maxId === lastPost.id) {
+				resUser.meta.nextURL = null
+			} else {
+				resUser.meta.nextURL =
+					`/api/v1/user/${user.id}?posts?=true&limit=${limit}&lastId=${lastPost.id}`
+			}
+
+			res.json(user)
+		} else {
+			let user = await User.findOne(queryObj)
+			if(!user) throw Errors.accountDoesNotExist
+
+			res.json(user.toJSON())
+		}
+
+		
 	} catch (err) {
 		if(err === Errors.accountDoesNotExist) {
 			res.status(400)
 			res.json({ errors: [err] })
 		} else {
+			console.log(err)
 			res.status(500)
 			res.json({
 				errors: [Errors.unknown]

+ 41 - 0
test/user.js

@@ -4,6 +4,7 @@ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
 let chai = require('chai')
 let server = require('../server')
 let should = chai.should()
+let expect = chai.expect
 
 let { sequelize } = require('../models')
 const Errors = require('../lib/errors.js')
@@ -330,6 +331,46 @@ describe('User', () => {
 			res.body.should.have.property('Posts')
 			res.body.Posts.should.have.property('length', 2)
 		})
+
+		it('should allow pagination', async () => {
+			let agent = chai.request.agent(server)
+
+			await agent
+				.post('/api/v1/user/adminaccount/login')
+				.set('content-type', 'application/x-www-form-urlencoded')
+				.send({ password: 'password' })
+
+			let thread = await agent
+				.post('/api/v1/thread')
+				.set('content-type', 'application/json')
+				.send({ category: 'categorynamehere', name: 'pagination' })
+
+			for(var i = 0; i < 30; i++) {
+				await agent
+					.post('/api/v1/post')
+					.set('content-type', 'application/json')
+					.send({ threadId: thread.body.id, content: `POST ${i}` })
+			}
+
+			let pageOne = await agent.get('/api/v1/thread/' + thread.body.id)
+			let pageTwo = await agent.get(pageOne.body.meta.nextURL)
+			let pageThree = await agent.get(pageTwo.body.meta.nextURL)
+			let pageInvalid = await agent.get('/api/v1/thread/' + thread.body.id + '?lastId=' + 100)
+
+			pageOne.body.Posts.should.have.length(10)
+			pageOne.body.Posts[0].should.have.property('content', '<p>POST 0</p>\n')
+
+			pageTwo.body.Posts.should.have.length(10)
+			pageTwo.body.Posts[0].should.have.property('content', '<p>POST 10</p>\n')
+
+			pageThree.body.Posts.should.have.length(10)
+			pageThree.body.Posts[0].should.have.property('content', '<p>POST 20</p>\n')
+			pageThree.body.Posts[9].should.have.property('content', '<p>POST 29</p>\n')
+			expect(pageThree.body.meta.nextURL).to.be.null
+
+			pageInvalid.body.Posts.should.have.length(0)
+
+		})
 	})
 
 	describe('/:username/login POST user', () => {