diff --git a/config/website.js b/config/website.js index 660c306..7020f24 100644 --- a/config/website.js +++ b/config/website.js @@ -1,6 +1,5 @@ module.exports = { title: 'Putong OJ', - discussOnProblem: true, semi_restful: false, } diff --git a/controllers/discuss.js b/controllers/discuss.js index 6e8a0ec..c841b84 100644 --- a/controllers/discuss.js +++ b/controllers/discuss.js @@ -1,6 +1,7 @@ const Discuss = require('../models/Discuss') const logger = require('../utils/logger') const redis = require('../config/redis') +const { isLogined, isAdmin } = require('../utils/helper') const preload = async (ctx, next) => { const did = Number.parseInt(ctx.params.did) @@ -12,7 +13,17 @@ const preload = async (ctx, next) => { } const find = async (ctx) => { - const list = await Discuss.find().exec() + if (!isLogined(ctx)) { + ctx.body = { list: [] } + return + } + + let list + if (isAdmin(ctx.session.profile)) { + list = await Discuss.find().exec() + } else { + list = await Discuss.find({ uid: ctx.session.profile.uid }).exec() + } ctx.body = { list, @@ -21,6 +32,11 @@ const find = async (ctx) => { const findOne = async (ctx) => { const discuss = ctx.state.discuss + + if (discuss.uid !== ctx.session.profile.uid && !isAdmin(ctx.session.profile)) { + ctx.throw(400, 'You do not have permission to enter this discuss!') + } + ctx.body = { discuss, } @@ -54,6 +70,11 @@ const create = async (ctx) => { const update = async (ctx) => { const opt = ctx.request.body const discuss = ctx.state.discuss + + if (discuss.uid !== ctx.session.profile.uid && !isAdmin(ctx.session.profile)) { + ctx.throw(400, 'You do not have permission to reply this discuss!') + } + try { discuss.comments.push({ uid: ctx.session.profile.uid, diff --git a/routes/discuss.js b/routes/discuss.js index e4e246c..7a7959d 100644 --- a/routes/discuss.js +++ b/routes/discuss.js @@ -7,7 +7,7 @@ const router = new Router({ }) router.get('/list', discuss.find) -router.get('/:did', discuss.preload, discuss.findOne) +router.get('/:did', auth.login, discuss.preload, discuss.findOne) router.post('/', auth.login, discuss.create) router.put('/:did', auth.login, discuss.preload, discuss.update) router.del('/:did', auth.login, auth.admin, discuss.del) diff --git a/test/controllers/discuss/admin.test.js b/test/controllers/discuss/admin.test.js new file mode 100644 index 0000000..6e1789f --- /dev/null +++ b/test/controllers/discuss/admin.test.js @@ -0,0 +1,77 @@ +const test = require('ava') +const supertest = require('supertest') +const app = require('../../../app') +const only = require('only') +const config = require('../../../config') +const discuss = require('../../seed/discuss') + +const server = app.listen() +const request = supertest.agent(server) + +test.before('Login', async (t) => { + const login = await request + .post('/api/session') + .send({ + uid: 'admin', + pwd: config.deploy.adminInitPwd, + }) + + t.is(login.status, 200) +}) + +test('Discuss list', async (t) => { + const res = await request + .get('/api/discuss/list') + + t.is(res.status, 200) + t.is(res.type, 'application/json') + t.truthy(Array.isArray(res.body.list)) + res.body.list.forEach((item) => { + t.truthy(item.title) + t.truthy(item.uid) + t.truthy(item.update) + }) +}) + +test('Find Discuss 1', async (t) => { + const res = await request + .get('/api/discuss/1') + + t.is(res.status, 200) + t.is(res.type, 'application/json') + + const select = discuss.data.find(item => item.title === res.body.discuss.title) + const com = res.body.discuss.comments + + t.deepEqual(only(res.body.discuss, 'create title uid create update'), only(select, 'create title uid create update')) + com.forEach((item, index) => { + t.deepEqual(only(item, 'content create uid'), select.comments[index]) + }) +}) + +test('Find non-exist Discuss', async (t) => { + const res = await request + .get('/api/discuss/1000') + + t.is(res.status, 400) + t.truthy(res.body.error) +}) + +test('Delete Discuss 2', async (t) => { + const res = await request + .delete('/api/discuss/2') + + t.is(res.status, 200) +}) + +test('Delete with invalid did', async (t) => { + const del = await request + .delete('/api/discuss/invalid') + + t.is(del.status, 400) + t.truthy(del.body.error) +}) + +test.after.always('close server', () => { + server.close() +}) diff --git a/test/controllers/discuss/user.test.js b/test/controllers/discuss/user.test.js index b9021b3..035438b 100644 --- a/test/controllers/discuss/user.test.js +++ b/test/controllers/discuss/user.test.js @@ -61,6 +61,53 @@ test.serial('Add a comment', async (t) => { t.is(comments[comments.length - 1].content, 'nothing') }) +test('Discuss list', async (t) => { + const res = await request + .get('/api/discuss/list') + + t.is(res.status, 200) + t.is(res.type, 'application/json') + t.truthy(Array.isArray(res.body.list)) + res.body.list.forEach((item) => { + t.truthy(item.title) + t.truthy(item.uid) + t.is(item.uid, user.uid) + t.truthy(item.update) + }) +}) + +test('Reply other\'s discuss should fail', async (t) => { + const update = await request + .put(`/api/discuss/1`) + .send({ content: 'nothing' }) + + t.is(update.status, 400) + t.is(update.type, 'application/json') + + t.truthy(update.body.error) +}) + + +test('Did is not a number', async (t) => { + const res = await request + .get('/api/discuss/xx') + + t.is(res.status, 400) + t.is(res.type, 'application/json') + + t.truthy(res.body.error) +}) + +test('Find Discuss 1 should fail', async (t) => { + const res = await request + .get('/api/discuss/1') + + t.is(res.status, 400) + t.is(res.type, 'application/json') + + t.truthy(res.body.error) +}) + test('Title can not be empty', async (t) => { const res = await request .post('/api/discuss') diff --git a/test/controllers/discuss/visitor.test.js b/test/controllers/discuss/visitor.test.js index 95d1105..4f7c38d 100644 --- a/test/controllers/discuss/visitor.test.js +++ b/test/controllers/discuss/visitor.test.js @@ -1,8 +1,6 @@ const test = require('ava') const supertest = require('supertest') -const only = require('only') const app = require('../../../app') -const discuss = require('../../seed/discuss') const server = app.listen() const request = supertest.agent(server) @@ -14,44 +12,14 @@ test('Discuss list', async (t) => { t.is(res.status, 200) t.is(res.type, 'application/json') t.truthy(Array.isArray(res.body.list)) - res.body.list.forEach((item) => { - t.truthy(item.title) - t.truthy(item.uid) - t.truthy(item.update) - }) -}) - -test('Find Discuss 1', async (t) => { - const res = await request - .get('/api/discuss/1') - - t.is(res.status, 200) - t.is(res.type, 'application/json') - - const select = discuss.data.find(item => item.title === res.body.discuss.title) - const com = res.body.discuss.comments - - t.deepEqual(only(res.body.discuss, 'create title uid create update'), only(select, 'create title uid create update')) - com.forEach((item, index) => { - t.deepEqual(only(item, 'content create uid'), select.comments[index]) - }) + t.is(res.body.list.length, 0) }) test('Discuss should fail to find one', async (t) => { const res = await request - .get('/api/discuss/10000') - - t.is(res.status, 400) - t.is(res.type, 'application/json') - - t.truthy(res.body.error) -}) - -test('Did is not a number', async (t) => { - const res = await request - .get('/api/discuss/xx') + .get('/api/discuss/1') - t.is(res.status, 400) + t.is(res.status, 401) t.is(res.type, 'application/json') t.truthy(res.body.error)