Ver Fonte

Move logic to pagination functions in lib folder; at threads query route

sbkwgh há 8 anos atrás
pai
commit
ef5111cf53
5 ficheiros alterados com 103 adições e 15 exclusões
  1. 30 0
      lib/pagination.js
  2. 1 0
      models/user.js
  3. 1 1
      package.json
  4. 36 13
      routes/user.js
  5. 35 1
      test/user.js

+ 30 - 0
lib/pagination.js

@@ -0,0 +1,30 @@
+async function getNextId(Model, where, items) {
+	try {
+		let maxId = await Model.max('id', { where })
+		let lastItem = items.slice(-1)[0]
+
+		if(!lastItem || maxId === lastItem.id) {
+			return null
+		} else {
+			return lastItem.id
+		}
+	} catch (e) {
+		console.log(e)
+		return null
+	}
+}
+
+function getPaginationProps(query) {
+	let lastId = 0
+	let limit = 10
+
+	if(+query.lastId > 0) lastId = +query.lastId
+	if(+query.limit > 0) limit = +query.limit
+
+	return { lastId, limit }
+}
+
+module.exports = {
+	getNextId,
+	getPaginationProps
+}

+ 1 - 0
models/user.js

@@ -21,6 +21,7 @@ module.exports = (sequelize, DataTypes) => {
 		classMethods: {
 			associate (models) {
 				User.hasMany(models.Post)
+				User.hasMany(models.Thread)
 			},
 			includeOptions (lastId, limit) {
 				let models = sequelize.models

+ 1 - 1
package.json

@@ -4,7 +4,7 @@
   "description": "Backend for forum",
   "main": "server.js",
   "scripts": {
-    "test": "cross-env NODE_ENV=test && node ./node_modules/mocha/bin/mocha  --harmony --timeout 10000",
+    "test": "cross-env NODE_ENV=test && node ./node_modules/mocha/bin/mocha  --harmony --timeout 30000",
     "start": "cross-env NODE_ENV=development && node --harmony server.js"
   },
   "author": "",

+ 36 - 13
routes/user.js

@@ -3,7 +3,8 @@ let express = require('express')
 let router = express.Router()
 
 const Errors = require('../lib/errors.js')
-let { User, Post, AdminToken } = require('../models')
+let { User, Post, AdminToken, Thread, Category } = require('../models')
+let pagination = require('../lib/pagination.js')
 
 function setUserSession(req, res, username, admin) {
 	req.session.loggedIn = true
@@ -11,7 +12,6 @@ function setUserSession(req, res, username, admin) {
 	res.cookie('username', username)
 	if(admin) req.session.admin = true
 }
-
 router.post('/', async (req, res) => {
 	let user, adminUser, hash, token
 	let validationErrors = []
@@ -123,28 +123,51 @@ 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
+			
+			let { lastId, limit } = pagination.getPaginationProps(req.query)
 
 			queryObj.include = User.includeOptions(lastId, limit)
 
 			let user = await User.findOne(queryObj)
 			if(!user) throw Errors.accountDoesNotExist
 
-			let maxId = await Post.max('id', { where: { userId: user.id } })
-
 			let resUser = user.toJSON()
-			let lastPost = user.Posts.slice(-1)[0]
 			resUser.meta = {}
 
-			if(!lastPost || maxId === lastPost.id) {
-				resUser.meta.nextURL = null
+			let nextId = await pagination.getNextId(Post, { userId: user.id }, resUser.Posts)
+
+			if(nextId) {
+				resUser.meta.nextURL =
+					`/api/v1/user/${user.username}?posts=true&limit=${limit}&lastId=${nextId}`
 			} else {
+				resUser.meta.nextURL = null
+			}
+
+			res.json(resUser)
+		} else if(req.query.threads) {
+			let { lastId, limit } = pagination.getPaginationProps(req.query)
+
+			queryObj.include = [{
+				model: Thread,
+				include: [Category],
+				limit,
+				where: { id: { $gt: lastId } },
+				order: [['id', 'ASC']]
+			}]
+
+			let user = await User.findOne(queryObj)
+			if(!user) throw Errors.accountDoesNotExist
+
+			let resUser = user.toJSON()
+			resUser.meta = {}
+
+			let nextId = await pagination.getNextId(Thread, { userId: user.id }, resUser.Threads)
+
+			if(nextId) {
 				resUser.meta.nextURL =
-					`/api/v1/user/${user.username}?posts=true&limit=${limit}&lastId=${lastPost.id}`
+					`/api/v1/user/${user.username}?threads=true&limit=${limit}&lastId=${nextId}`
+			} else {
+				resUser.meta.nextURL = null
 			}
 
 			res.json(resUser)

+ 35 - 1
test/user.js

@@ -332,7 +332,7 @@ describe('User', () => {
 			res.body.Posts.should.have.property('length', 2)
 			res.body.Posts[0].should.have.deep.property('Thread.id', 1)
 			res.body.Posts[0].should.have.deep.property('User.username', 'adminaccount')
-		})
+		})	
 
 		it('should allow pagination', async () => {
 			let agent = chai.request.agent(server)
@@ -373,6 +373,40 @@ describe('User', () => {
 			pageInvalid.body.Posts.should.have.length(0)
 
 		})
+
+		it('should get threads as well if threads query is appended', async () => {
+			let agent = chai.request.agent(server)
+
+			await agent
+				.post('/api/v1/user')
+				.set('content-type', 'application/x-www-form-urlencoded')
+				.send({ username: 'threadaccount', password: 'password' })
+
+			for(var i = 0; i < 20; i++) {
+				let thread = await agent
+					.post('/api/v1/thread')
+					.set('content-type', 'application/json')
+					.send({ category: 'categorynamehere', name: 'THREAD ' + 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/user/threadaccount?threads=true')
+			let pageTwo = await agent.get(pageOne.body.meta.nextURL)
+			let pageInvalid = await agent.get('/api/v1/user/threadaccount?threads=true&lastId=100')
+
+			pageOne.body.Threads.should.have.length(10)
+			pageOne.body.Threads[0].should.have.property('name', 'THREAD 0')
+
+			pageTwo.body.Threads.should.have.length(10)
+			pageTwo.body.Threads[0].should.have.property('name', 'THREAD 10')
+			expect(pageTwo.body.meta.nextURL).to.be.null
+
+			pageInvalid.body.Threads.should.have.length(0)
+		})
 	})
 
 	describe('/:username/login POST user', () => {