mirror of
https://github.com/wassname/talk.git
synced 2026-06-30 19:26:42 +08:00
Merge branch 'master' of https://github.com/coralproject/talk into post-comment
This commit is contained in:
+14
-1
@@ -45,6 +45,19 @@
|
||||
"space-infix-ops": ["error"],
|
||||
"no-const-assign": [2],
|
||||
"no-duplicate-imports": [2],
|
||||
"prefer-template": [1]
|
||||
"prefer-template": [1],
|
||||
"comma-spacing": [
|
||||
"error",
|
||||
{
|
||||
"after": true
|
||||
}
|
||||
],
|
||||
"no-var": [2],
|
||||
"no-lonely-if": [2],
|
||||
"curly": [2],
|
||||
"no-multiple-empty-lines": [
|
||||
"error",
|
||||
{"max": 1}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
dist
|
||||
!dist/coral-admin
|
||||
dist/coral-admin/bundle.js
|
||||
.DS_Store
|
||||
*.iml
|
||||
.env
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
{
|
||||
"basePath": "http://localhost:3142",
|
||||
"talkHost": "http://localhost:16180",
|
||||
"xeniaHost": "http://localhost:16180"
|
||||
"base": "client/coral-admin"
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"coral-framework": "0.0.1",
|
||||
"hammerjs": "2.0.8",
|
||||
"immutable": "3.8.1",
|
||||
"keymaster": "1.6.2",
|
||||
@@ -23,8 +22,7 @@
|
||||
"react-router": "^3.0.0",
|
||||
"redux": "3.6.0",
|
||||
"redux-thunk": "2.1.0",
|
||||
"timeago.js": "2.0.2",
|
||||
"xenia-driver": "0.0.4"
|
||||
"timeago.js": "2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "6.5.0",
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="http://localhost:3142/bundle.js" charset="utf-8"></script>
|
||||
<script src="undefined/bundle.js" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import React from 'react'
|
||||
import { Provider } from 'react-redux'
|
||||
import { Layout, Content } from 'react-mdl'
|
||||
import { Layout } from 'react-mdl'
|
||||
import 'material-design-lite'
|
||||
import { Router, Route, browserHistory } from 'react-router'
|
||||
import ModerationQueue from 'containers/ModerationQueue'
|
||||
@@ -10,6 +10,7 @@ import store from 'services/store'
|
||||
import CommentStream from 'containers/CommentStream'
|
||||
import EmbedLink from 'components/EmbedLink'
|
||||
import Configure from 'containers/Configure'
|
||||
import config from 'services/config'
|
||||
|
||||
export default class App extends React.Component {
|
||||
render (props) {
|
||||
@@ -19,10 +20,10 @@ export default class App extends React.Component {
|
||||
<Header>
|
||||
<div>
|
||||
<Router history={browserHistory}>
|
||||
<Route path='/' component={ModerationQueue} />
|
||||
<Route path='embed' component={CommentStream} />
|
||||
<Route path='embedlink' compoent={EmbedLink} />
|
||||
<Route path='configure' component={Configure} />
|
||||
<Route path={config.base} component={ModerationQueue} />
|
||||
<Route path={`${config.base}/embed`} component={CommentStream} />
|
||||
<Route path={`${config.base}/embedlink`} component={EmbedLink} />
|
||||
<Route path={`${config.base}/configure`} component={Configure} />
|
||||
</Router>
|
||||
</div>
|
||||
</Header>
|
||||
|
||||
@@ -12,14 +12,14 @@ export default props => (
|
||||
<div className={styles.itemHeader}>
|
||||
<div className={styles.author}>
|
||||
<i className={`material-icons ${styles.avatar}`}>person</i>
|
||||
<span>{props.comment.get('data').get('name') || lang.t('comment.anon')}</span>
|
||||
<span className={styles.created}>{timeago().format(props.comment.get('data').get('createdAt') || (Date.now() - props.index * 60 * 1000), lang.getLocale().replace('-', '_'))}</span>
|
||||
{props.comment.get('data').get('flagged') ? <p className={styles.flagged}>{lang.t('comment.flagged')}</p> : null}
|
||||
<span>{props.comment.get('name') || lang.t('comment.anon')}</span>
|
||||
<span className={styles.created}>{timeago().format(props.comment.get('createdAt') || (Date.now() - props.index * 60 * 1000), lang.getLocale().replace('-', '_'))}</span>
|
||||
{props.comment.get('flagged') ? <p className={styles.flagged}>{lang.t('comment.flagged')}</p> : null}
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
{props.actions.map(action => canShowAction(action, props.comment) ? (
|
||||
<Button className={styles.actionButton}
|
||||
onClick={() => props.onClickAction(props.actionsMap[action].status, props.comment.get('item_id'))}
|
||||
onClick={() => props.onClickAction(props.actionsMap[action].status, props.comment.get('_id'))}
|
||||
fab colored>
|
||||
<Icon name={props.actionsMap[action].icon} />
|
||||
</Button>
|
||||
@@ -27,16 +27,17 @@ export default props => (
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.itemBody}>
|
||||
<span className={styles.body}>{props.comment.get('data').get('body')}</span>
|
||||
<span className={styles.body}>{props.comment.get('body')}</span>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
|
||||
// Check if an action can be performed over a comment
|
||||
const canShowAction = (action, comment) => {
|
||||
const status = comment.get('data').get('status')
|
||||
const flagged = comment.get('data').get('flagged')
|
||||
if (action === 'flag' && (status !== 'Untouched' || flagged === true)) {
|
||||
const status = comment.get('status')
|
||||
const flagged = comment.get('flagged')
|
||||
|
||||
if (action === 'flag' && (status || flagged === true)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -112,8 +112,9 @@ export default class CommentList extends React.Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const {singleView, actions, commentIds, comments, hideActive} = this.props
|
||||
const {singleView, commentIds, comments, hideActive} = this.props
|
||||
const {active} = this.state
|
||||
|
||||
return (
|
||||
<ul className={`${styles.list} ${singleView ? styles.singleView : ''}`}>
|
||||
{commentIds.map((commentId, index) => (
|
||||
@@ -122,7 +123,7 @@ export default class CommentList extends React.Component {
|
||||
key={index}
|
||||
index={index}
|
||||
onClickAction={this.onClickAction}
|
||||
actions={actions}
|
||||
actions={this.props.actions}
|
||||
actionsMap={actions}
|
||||
isActive={commentId === active}
|
||||
hideActive={hideActive} />
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import React from 'react'
|
||||
import { Layout, Navigation, Drawer, Header } from 'react-mdl'
|
||||
import { Link } from 'react-router'
|
||||
import styles from './Header.css'
|
||||
import config from 'services/config'
|
||||
|
||||
// App header. If we add a navbar it should be here
|
||||
export default (props) => (
|
||||
<Layout fixedDrawer>
|
||||
<Header title='Talk'>
|
||||
<Navigation>
|
||||
<a className={styles.navLink} href='/'>Moderate</a>
|
||||
<a className={styles.navLink} href='/configure'>Configure</a>
|
||||
<Link className={styles.navLink} href={`/${config.base}/`}>Moderate</Link>
|
||||
<Link className={styles.navLink} href={`/${config.base}/configure`}>Configure</Link>
|
||||
</Navigation>
|
||||
</Header>
|
||||
<Drawer>
|
||||
<Navigation>
|
||||
<a className={styles.navLink} href='/'>Moderate</a>
|
||||
<a className={styles.navLink} href='/configure'>Configure</a>
|
||||
<Link className={styles.navLink} href={`/${config.base}/`}>Moderate</Link>
|
||||
<Link className={styles.navLink} href={`/${config.base}/configure`}>Configure</Link>
|
||||
</Navigation>
|
||||
</Drawer>
|
||||
{props.children}
|
||||
|
||||
@@ -74,7 +74,7 @@ class ModerationQueue extends React.Component {
|
||||
<CommentList
|
||||
isActive={activeTab === 'pending'}
|
||||
singleView={singleView}
|
||||
commentIds={comments.get('ids').filter(id => comments.get('byId').get(id).get('data').get('status') === 'Untouched')}
|
||||
commentIds={comments.get('ids').filter(id => !comments.get('byId').get(id).get('status'))}
|
||||
comments={comments.get('byId')}
|
||||
onClickAction={(action, id) => this.onCommentAction(action, id)}
|
||||
actions={['reject', 'approve']}
|
||||
@@ -84,7 +84,7 @@ class ModerationQueue extends React.Component {
|
||||
<CommentList
|
||||
isActive={activeTab === 'rejected'}
|
||||
singleView={singleView}
|
||||
commentIds={comments.get('ids').filter(id => comments.get('byId').get(id).get('data').get('status') === 'Rejected')}
|
||||
commentIds={comments.get('ids').filter(id => comments.get('byId').get(id).get('status') === 'rejected')}
|
||||
comments={comments.get('byId')}
|
||||
onClickAction={(action, id) => this.onCommentAction(action, id)}
|
||||
actions={['approve']}
|
||||
@@ -95,8 +95,8 @@ class ModerationQueue extends React.Component {
|
||||
isActive={activeTab === 'rejected'}
|
||||
singleView={singleView}
|
||||
commentIds={comments.get('ids').filter(id => {
|
||||
const data = comments.get('byId').get(id).get('data')
|
||||
return data.get('status') === 'Untouched' && data.get('flagged') === true
|
||||
const data = comments.get('byId').get(id)
|
||||
return !data.get('status') && data.get('flagged') === true
|
||||
})}
|
||||
comments={comments.get('byId')}
|
||||
onClickAction={(action, id) => this.onCommentAction(action, id)}
|
||||
|
||||
@@ -46,7 +46,7 @@ const flag = (state, action) => {
|
||||
|
||||
// Replace the comment list with a new one
|
||||
const replaceComments = (action, state) => {
|
||||
const comments = fromJS(action.comments.reduce((prev, curr) => { prev[curr.item_id] = curr; return prev }, {}))
|
||||
const comments = fromJS(action.comments.reduce((prev, curr) => { prev[curr._id] = curr; return prev }, {}))
|
||||
return state.set('byId', comments).set('loading', false)
|
||||
.set('ids', List(comments.keys()))
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
* for the coral but also for wordpress comments, disqus and many more.
|
||||
*/
|
||||
|
||||
import { talkHost, xeniaHost } from 'services/config'
|
||||
import XeniaDriver from 'xenia-driver'
|
||||
|
||||
// Intercept redux actions and act over the ones we are interested
|
||||
export default store => next => action => {
|
||||
switch (action.type) {
|
||||
@@ -30,64 +27,34 @@ export default store => next => action => {
|
||||
next(action)
|
||||
}
|
||||
|
||||
// Setup xenia driver
|
||||
const xenia = XeniaDriver(`${xeniaHost}/v1`, {username: 'user', password: 'pass'})
|
||||
|
||||
// Get comments to fill each of the three lists on the mod queue
|
||||
const fetchModerationQueueComments = store => xenia()
|
||||
.collection('items')
|
||||
.match({type: 'comment', 'data.status': 'Untouched', 'data.createdAt': { $exists: true }})
|
||||
.sort(['data.createdAt', 1])
|
||||
.skip(0).limit(50)
|
||||
.addQuery().collection('items')
|
||||
.match({type: 'comment', 'data.status': 'Rejected', 'data.createdAt': { $exists: true }})
|
||||
.sort(['data.createdAt', 1])
|
||||
.skip(0).limit(50)
|
||||
.addQuery().collection('items')
|
||||
.match({type: 'comment', 'data.status': 'Untouched', 'data.flagged': true, 'data.createdAt': { $exists: true }})
|
||||
.sort(['data.createdAt', 1])
|
||||
.skip(0).limit(50)
|
||||
.exec()
|
||||
const fetchModerationQueueComments = store =>
|
||||
fetch(`/api/v1/queue`)
|
||||
.then(res => res.json())
|
||||
.then(res => store.dispatch({ type: 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS',
|
||||
comments: res.results.map(res => res.Docs).reduce((p, c) => p.concat(c), []) }))
|
||||
comments: res }))
|
||||
.catch(error => store.dispatch({ type: 'COMMENTS_MODERATION_QUEUE_FETCH_FAILED', error }))
|
||||
|
||||
// Update a comment. Now to update a comment we need to send back the whole object
|
||||
const updateComment = (store, comment) =>
|
||||
fetch(`${talkHost}/v1/item`, {
|
||||
method: 'PUT',
|
||||
mode: 'cors',
|
||||
body: JSON.stringify(comment)
|
||||
fetch(`/api/v1/comments/${comment._id}/status`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ status: comment.status })
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => store.dispatch({ type: 'COMMENT_UPDATE_SUCCESS', res }))
|
||||
.catch(error => store.dispatch({ type: 'COMMENT_UPDATE_FAILED', error }))
|
||||
|
||||
// Create a new comment
|
||||
const createComment = (store, name, comment) =>
|
||||
fetch(`${talkHost}/v1/item`, {
|
||||
fetch(`/api/v1/comments`, {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
body: JSON.stringify({
|
||||
type: 'comment',
|
||||
version: 1,
|
||||
data: {
|
||||
status: 'Untouched',
|
||||
body: comment,
|
||||
name: name,
|
||||
createdAt: Date.now()
|
||||
}
|
||||
status: 'Untouched',
|
||||
body: comment,
|
||||
name: name,
|
||||
createdAt: Date.now()
|
||||
})
|
||||
}).then(res => res.json())
|
||||
.then(res => store.dispatch({ type: 'COMMENT_CREATE_SUCCESS', comment: res }))
|
||||
.catch(error => store.dispatch({ type: 'COMMENT_CREATE_FAILED', error }))
|
||||
|
||||
// Get a comment stream. Now we don't have the concept of assets, this should
|
||||
// be adapted to retrieve the current asset when the backend supports it
|
||||
const fetchCommentStream = store => xenia()
|
||||
.collection('items')
|
||||
.match({type: 'comment', 'data.status': { $ne: 'Rejected' }, 'data.createdAt': { $exists: true }})
|
||||
.sort(['data.createdAt', 1])
|
||||
.skip(0).limit(100)
|
||||
.exec()
|
||||
.then(res => store.dispatch({ type: 'COMMENT_STREAM_FETCH_SUCCESS', comments: res.results[0].Docs }))
|
||||
.catch(error => store.dispatch({ type: 'COMMENT_STREAM_FETCH_FAILED', error }))
|
||||
|
||||
@@ -20,7 +20,7 @@ module.exports = {
|
||||
'bundle': path.join(__dirname, 'src', 'index')
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, 'public'),
|
||||
path: path.join(__dirname, '..', '..', 'dist', 'coral-admin'),
|
||||
filename: '[name].js'
|
||||
},
|
||||
module: {
|
||||
@@ -41,6 +41,7 @@ module.exports = {
|
||||
resolve: {
|
||||
modules: [
|
||||
path.resolve('./src'),
|
||||
path.resolve('../'),
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
|
||||
<title>Talk - Coral Admin</title>
|
||||
<base href="/client/coral-admin/" />
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
<link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
|
||||
<style media="screen">
|
||||
body, #root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="bundle.js" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
+1
-1
@@ -12,7 +12,7 @@ const ActionSchema = new Schema({
|
||||
item_type: String,
|
||||
item_id: String,
|
||||
user_id: String
|
||||
},{
|
||||
}, {
|
||||
timestamps: {
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at'
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
const mongoose = require('../mongoose');
|
||||
const uuid = require('uuid');
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const AssetSchema = new Schema({
|
||||
|
||||
id: {
|
||||
type: String,
|
||||
default: uuid.v4,
|
||||
unique: true,
|
||||
index: true
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
unique: true,
|
||||
index: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'article'
|
||||
},
|
||||
headline: String,
|
||||
summary: String,
|
||||
section: String,
|
||||
subsection: String,
|
||||
authors: [String],
|
||||
publication_date: Date
|
||||
}, {
|
||||
versionKey: false,
|
||||
timestamps: {
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at'
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Search for assets. Currently only returns all.
|
||||
*/
|
||||
AssetSchema.statics.search = function(query) {
|
||||
|
||||
return Asset.find(query).exec();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds an asset by its id.
|
||||
* @param {String} id identifier of the asset (uuid).
|
||||
*/
|
||||
AssetSchema.statics.findById = function(id) {
|
||||
|
||||
return Asset.findOne({id}).exec();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds a asset by its url.
|
||||
* @param {String} url identifier of the asset (uuid).
|
||||
*/
|
||||
AssetSchema.statics.findByUrl = function(url) {
|
||||
|
||||
return Asset.findOne({'url': url}).exec();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Upserts an asset.
|
||||
*/
|
||||
AssetSchema.statics.upsert = function(data) {
|
||||
|
||||
// If an id is not sent, create one.
|
||||
if (typeof data.id === 'undefined') {
|
||||
data.id = uuid.v4();
|
||||
}
|
||||
|
||||
// Perform the upsert against the id field.
|
||||
let updatePromise = Asset.update({id: data.id}, data, {upsert: true}).exec()
|
||||
.then(() => {
|
||||
|
||||
// Pull the freshly minted asset out and return.
|
||||
return Asset.findById(data.id);
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
|
||||
console.error('Error upserting asset.', err);
|
||||
//return new Promise(); // ??? what do we return on error?
|
||||
|
||||
});
|
||||
|
||||
return updatePromise;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove assets from the db.
|
||||
* @param {String} query bson query to identify assets to be removed.
|
||||
*/
|
||||
AssetSchema.statics.removeAll = function(query) {
|
||||
|
||||
return Asset.remove(query).exec();
|
||||
|
||||
};
|
||||
|
||||
const Asset = mongoose.model('Asset', AssetSchema);
|
||||
|
||||
module.exports = Asset;
|
||||
+3
-11
@@ -24,7 +24,7 @@ const CommentSchema = new Schema({
|
||||
default: ''
|
||||
},
|
||||
parent_id: String
|
||||
},{
|
||||
}, {
|
||||
timestamps: {
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at'
|
||||
@@ -53,15 +53,7 @@ CommentSchema.statics.findByAssetId = function(asset_id) {
|
||||
* @param {String} status the new status of the comment
|
||||
*/
|
||||
CommentSchema.statics.changeStatus = function(id, status) {
|
||||
return Comment.update({'id': id}, {$set: {'status': status}}, {upsert: false}).then(() => {
|
||||
Comment.findById(id).then((comment) => {
|
||||
return comment;
|
||||
}).catch((err) => {
|
||||
console.log('Error updating status for the comment.', err);
|
||||
});
|
||||
}).catch((err) => {
|
||||
console.log('Error updating status for the comment.', err);
|
||||
});
|
||||
return Comment.findOneAndUpdate({'id': id}, {$set: {'status': status}}, {upsert: false, new: true});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -71,7 +63,7 @@ CommentSchema.statics.changeStatus = function(id, status) {
|
||||
*/
|
||||
CommentSchema.statics.addAction = function(id, user_id, action_type) {
|
||||
// check that the comment exist
|
||||
var action = new Action({
|
||||
let action = new Action({
|
||||
action_type: action_type,
|
||||
item_type: 'comment',
|
||||
item_id: id,
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ const UserProfileSchema = new Schema({
|
||||
},
|
||||
display_name: String,
|
||||
auth_user_id: String
|
||||
},{
|
||||
}, {
|
||||
timestamps: {
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at'
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ if (enabled('talk:db')) {
|
||||
|
||||
try {
|
||||
mongoose.connect(url, (err) => {
|
||||
if (err) throw err;
|
||||
if (err) {throw err;}
|
||||
console.log('Connected to MongoDB!');
|
||||
});
|
||||
} catch (err) {
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@
|
||||
"babel-preset-es2015-minimal": "^2.1.0",
|
||||
"babel-preset-stage-0": "^6.16.0",
|
||||
"chai": "^3.5.0",
|
||||
"chai-http": "^1.0.0",
|
||||
"chai-http": "^3.0.0",
|
||||
"copy-webpack-plugin": "^3.0.1",
|
||||
"eslint": "^3.9.1",
|
||||
"exports-loader": "^0.6.3",
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const Asset = require('../../../models/asset');
|
||||
|
||||
// Search assets.
|
||||
router.get('/', (req, res, next) => {
|
||||
|
||||
let query = {};
|
||||
|
||||
if (typeof req.query.url !== 'undefined') {
|
||||
query.url = req.query.url;
|
||||
}
|
||||
|
||||
Asset.search(query)
|
||||
.then((asset) => {
|
||||
res.json(asset);
|
||||
})
|
||||
.catch(next);
|
||||
|
||||
});
|
||||
|
||||
// Get an asset by id
|
||||
router.get('/:id', (req, res, next) => {
|
||||
|
||||
Asset.findById(req.params.id)
|
||||
.then((asset) => {
|
||||
res.json(asset);
|
||||
})
|
||||
.catch(next);
|
||||
|
||||
});
|
||||
|
||||
// Upsert an asset and return the affected document.
|
||||
router.put('/', (req, res, next) => {
|
||||
|
||||
Asset.upsert(req.body)
|
||||
.then((asset) => {
|
||||
res.json(asset);
|
||||
})
|
||||
.catch(next);
|
||||
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -7,7 +7,6 @@ const router = express.Router();
|
||||
// Routes
|
||||
//==============================================================================
|
||||
|
||||
|
||||
router.get('/', (req, res, next) => {
|
||||
Comment.find({}).then((comments) => {
|
||||
res.status(200).json(comments);
|
||||
@@ -25,16 +24,10 @@ router.get('/:comment_id', (req, res, next) => {
|
||||
});
|
||||
|
||||
router.post('/', (req, res, next) => {
|
||||
let comment = new Comment({
|
||||
body: req.body.body,
|
||||
author_id: req.body.author_id,
|
||||
asset_id: req.body.asset_id,
|
||||
parent_id: req.body.parent_id,
|
||||
status: req.body.status,
|
||||
username: req.body.username
|
||||
});
|
||||
const {body, author_id, asset_id, parent_id, status, username} = req.body;
|
||||
let comment = new Comment({body, author_id, asset_id, parent_id, status, username});
|
||||
comment.save().then(({id}) => {
|
||||
res.status(200).send(id);
|
||||
res.status(200).send({'id': id});
|
||||
}).catch(error => {
|
||||
next(error);
|
||||
});
|
||||
@@ -47,20 +40,17 @@ router.post('/:comment_id', (req, res, next) => {
|
||||
comment.asset_id = req.body.asset_id;
|
||||
comment.parent_id = req.body.parent_id;
|
||||
comment.status = req.body.status;
|
||||
|
||||
comment.save().then((comment) => {
|
||||
res.status(200).send(comment);
|
||||
});
|
||||
return comment.save();
|
||||
}).then((comment) => {
|
||||
res.status(200).send(comment);
|
||||
}).catch(error => {
|
||||
next(error);
|
||||
});
|
||||
});
|
||||
|
||||
router.delete('/:comment_id', (req, res, next) => {
|
||||
Comment.findById(req.params.comment_id).then((comment) => {
|
||||
comment.remove().then(() => {
|
||||
res.status(201).send('OK. Deleted');
|
||||
});
|
||||
Comment.remove(req.params.comment_id).then(() => {
|
||||
res.status(201).send('OK. Deleted');
|
||||
}).catch(error => {
|
||||
next(error);
|
||||
});
|
||||
|
||||
+3
-2
@@ -2,9 +2,10 @@ const express = require('express');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.use('/asset', require('./asset'));
|
||||
router.use('/comments', require('./comments'));
|
||||
router.use('/stream', require('./stream'));
|
||||
router.use('/settings', require('./settings'));
|
||||
router.use('/queue', require('./queue'));
|
||||
router.use('/settings', require('./settings'));
|
||||
router.use('/stream', require('./stream'));
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -3,13 +3,14 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
const defaultComment = {
|
||||
_id: '23423423432aa',
|
||||
body: 'This is a comment!',
|
||||
name: 'John Doe',
|
||||
createdAt: Date.now()
|
||||
};
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
const status = req.query.type || 'pending';
|
||||
const status = req.query.type;
|
||||
res.json([Object.assign({}, defaultComment, {status})]);
|
||||
});
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ router.get('/', (req, res, next) => {
|
||||
Action.findByItemIdArray(comments.map((comment) => comment.id))
|
||||
]);
|
||||
}).then(([comments, users, actions]) => {
|
||||
res.json([...comments,...users,...actions]);
|
||||
res.json([...comments, ...users, ...actions]);
|
||||
}).catch(error => {
|
||||
next(error);
|
||||
});
|
||||
|
||||
+62
-8
@@ -3,10 +3,10 @@ info:
|
||||
title: Talk API
|
||||
description: A commenting platform from The Coral Project. https://coralproject.net
|
||||
version: "0.0.1"
|
||||
host: api.talk-coralproject.net
|
||||
host: talk-stg.coralproject.net
|
||||
schemes:
|
||||
- https
|
||||
basePath: /v1
|
||||
basePath: /api/v1
|
||||
produces:
|
||||
- application/json
|
||||
paths:
|
||||
@@ -161,7 +161,35 @@ paths:
|
||||
description: Settings
|
||||
responses:
|
||||
204:
|
||||
description: Updated Setting
|
||||
description: OK
|
||||
/asset:
|
||||
get:
|
||||
tags:
|
||||
- Asset
|
||||
description: Get an asset by id.
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
put:
|
||||
tags:
|
||||
- Asset
|
||||
description: Upsert an asset.
|
||||
responses:
|
||||
204:
|
||||
description: OK
|
||||
/asset?url={url}:
|
||||
get:
|
||||
tags:
|
||||
- Asset
|
||||
parameters:
|
||||
- name: url
|
||||
in: query
|
||||
description: The url of the asset.
|
||||
required: true
|
||||
description: Get an asset by its url.
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
|
||||
definitions:
|
||||
Item:
|
||||
@@ -214,11 +242,6 @@ definitions:
|
||||
type: string
|
||||
user_id:
|
||||
type: string
|
||||
Setting:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
moderation:
|
||||
type: string
|
||||
enum:
|
||||
@@ -232,3 +255,34 @@ definitions:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Updated Date-Time
|
||||
Asset:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: The uuid.v4 id of the asset.
|
||||
url:
|
||||
type: string
|
||||
description: The url where the asset is found.
|
||||
type:
|
||||
type: string
|
||||
description: What kind of asset it is.
|
||||
default: article
|
||||
headline:
|
||||
type: string
|
||||
description: The headline of the asset, inferred on initial load.
|
||||
summary:
|
||||
type: string
|
||||
description: A summary of the asset, inferred on initial load.
|
||||
section:
|
||||
type: string
|
||||
description: The section the asset is in.
|
||||
subsection:
|
||||
type: string
|
||||
description: The subsection that the asset is in.
|
||||
authors:
|
||||
type: string
|
||||
description: An array of the authors for this asset.
|
||||
publication_date:
|
||||
type: date
|
||||
desctipion: When this asset was published.
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
"node": true,
|
||||
"mocha": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"extends": "../.eslintrc.json",
|
||||
"rules": {
|
||||
"no-undef": [0]
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
/* eslint-env node, mocha */
|
||||
'use strict';
|
||||
|
||||
// require('./utils/mongoose')
|
||||
const expect = require('chai').expect;
|
||||
|
||||
|
||||
describe('Comment', () => {
|
||||
describe('#add', () => {
|
||||
it('should add a comment', () => {
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/* eslint-env node, mocha */
|
||||
|
||||
require('../utils/mongoose');
|
||||
|
||||
const Action = require('../../models/action');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
describe('Action: models', () => {
|
||||
var mockActions;
|
||||
let mockActions;
|
||||
beforeEach(() => {
|
||||
return Action.create([{
|
||||
action_type: 'flag',
|
||||
item_id: '123'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: '789'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'flag',
|
||||
item_id: '456'
|
||||
}]).then((actions) => {
|
||||
@@ -32,7 +31,7 @@ describe('Action: models', () => {
|
||||
|
||||
describe('#findByItemIdArray()', () => {
|
||||
it('should find an array of actions from an array of item_ids', () => {
|
||||
return Action.findByItemIdArray(['123','456']).then((result) => {
|
||||
return Action.findByItemIdArray(['123', '456']).then((result) => {
|
||||
expect(result).to.have.length(2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
require('../utils/mongoose');
|
||||
|
||||
const chai = require('chai');
|
||||
const expect = chai.expect;
|
||||
const server = require('../../app');
|
||||
|
||||
// Setup chai.
|
||||
chai.should();
|
||||
chai.use(require('chai-http'));
|
||||
|
||||
let fixture = {
|
||||
'url': 'http://hhgg.com/total-perspective-vortex',
|
||||
'type': 'article',
|
||||
'headline': 'The Total Perspective Vortex',
|
||||
'summary': 'You are an insignificant dot on an insignificant dot.',
|
||||
'section': 'Everything',
|
||||
'authors': ['Ford Prefect']
|
||||
};
|
||||
|
||||
describe('Asset: models', () => {
|
||||
|
||||
describe('/GET Asset', () => {
|
||||
describe('#get', () => {
|
||||
it('It should get an empty array when there are no assets.', (done) => {
|
||||
|
||||
chai.request(server)
|
||||
.get('/api/v1/asset')
|
||||
.end((err, res) => {
|
||||
|
||||
if (err) {
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
res.should.have.status(200);
|
||||
res.body.should.be.a('array');
|
||||
res.body.length.should.be.eql(0);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// This test checks PUT and read
|
||||
describe('/PUT Asset', () => {
|
||||
describe('#put', () => {
|
||||
it('It should save an asset and load it again.', (done) => {
|
||||
|
||||
chai.request(server)
|
||||
.put('/api/v1/asset')
|
||||
.send(fixture)
|
||||
.end((err, res) => {
|
||||
|
||||
if (err) {
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
res.should.have.status(200);
|
||||
res.body.should.be.a('object');
|
||||
|
||||
// Id should be generated by the model if absent.
|
||||
res.body.should.have.property('id');
|
||||
|
||||
// Save the asset id to compare with GET result.
|
||||
let assetId = res.body.id;
|
||||
|
||||
// Load the asset to make sure it's really there.
|
||||
chai.request(server)
|
||||
.get(`/api/v1/asset?url=${encodeURIComponent(fixture.url)}`)
|
||||
.end((err, res) => {
|
||||
|
||||
if (err) {
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
res.should.have.status(200);
|
||||
res.body.should.be.an('array');
|
||||
|
||||
let asset = res.body[0];
|
||||
|
||||
expect(asset).to.have.property('id');
|
||||
|
||||
// Ensure the asset has the same id as above.
|
||||
// This tests the single url per Id concept.
|
||||
expect(assetId).to.equal(asset.id);
|
||||
|
||||
done();
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}); // End describe /PUT Asset
|
||||
|
||||
});
|
||||
@@ -1,20 +1,18 @@
|
||||
/* eslint-env node, mocha */
|
||||
|
||||
require('../utils/mongoose');
|
||||
|
||||
const Comment = require('../../models/comment');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
describe('Comment: models', () => {
|
||||
var mockComments;
|
||||
let mockComments;
|
||||
beforeEach(() => {
|
||||
return Comment.create([{
|
||||
body: 'comment 10',
|
||||
asset_id: '123'
|
||||
},{
|
||||
}, {
|
||||
body: 'comment 20',
|
||||
asset_id: '123'
|
||||
},{
|
||||
}, {
|
||||
body: 'comment 30',
|
||||
asset_id: '456'
|
||||
}]).then((comments) => {
|
||||
@@ -35,7 +33,7 @@ describe('Comment: models', () => {
|
||||
it('should find an array of comments by asset id', () => {
|
||||
return Comment.findByAssetId('123').then((result) => {
|
||||
expect(result).to.have.length(2);
|
||||
result.sort((a,b) => {
|
||||
result.sort((a, b) => {
|
||||
if (a.body < b.body) {return -1;}
|
||||
else {return 1;}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/* eslint-env node, mocha */
|
||||
|
||||
require('../utils/mongoose');
|
||||
|
||||
const Setting = require('../../models/setting');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
describe('Setting: model', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
const defaults = {id: 1, moderation: 'pre'};
|
||||
return Setting.update({id: '1'}, {$setOnInsert: defaults}, {upsert: true});
|
||||
});
|
||||
|
||||
describe('#getSettings()', () => {
|
||||
it('should have a moderation field defined', () => {
|
||||
return Setting.getSettings().then(settings => {
|
||||
expect(settings).to.have.property('moderation').and.to.equal('pre');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#updateSettings()', () => {
|
||||
it('should update the settings with a passed object', () => {
|
||||
const mockSettings = {moderation: 'post'};
|
||||
return Setting.updateSettings(mockSettings).then(updatedSettings => {
|
||||
expect(updatedSettings).to.have.property('moderation').and.to.equal('post');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,17 +1,16 @@
|
||||
/* eslint-env node, mocha */
|
||||
|
||||
require('../utils/mongoose');
|
||||
|
||||
const User = require('../../models/user');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
describe('User: models', () => {
|
||||
var mockUsers;
|
||||
let mockUsers;
|
||||
beforeEach(() => {
|
||||
return User.create([{
|
||||
display_name: 'Stampi',
|
||||
},{
|
||||
}, {
|
||||
display_name: 'Sockmonster',
|
||||
},{
|
||||
}, {
|
||||
display_name: 'Marvel',
|
||||
}]).then((users) => {
|
||||
mockUsers = users;
|
||||
@@ -29,12 +28,10 @@ describe('User: models', () => {
|
||||
|
||||
describe('#findByIdArray()', () => {
|
||||
it('should find an array of users from an array of ids', () => {
|
||||
const ids = mockUsers.map((user) => user.id)
|
||||
const ids = mockUsers.map((user) => user.id);
|
||||
return User.findByIdArray(ids).then((result) => {
|
||||
expect(result).to.have.length(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// });
|
||||
});
|
||||
|
||||
+133
-116
@@ -4,56 +4,56 @@ require('../../../utils/mongoose');
|
||||
|
||||
const app = require('../../../../app');
|
||||
const chai = require('chai');
|
||||
const chaiHttp = require('chai-http');
|
||||
chai.use(chaiHttp);
|
||||
var expect = chai.expect;
|
||||
const expect = chai.expect;
|
||||
|
||||
// Setup chai.
|
||||
chai.should();
|
||||
chai.use(require('chai-http'));
|
||||
|
||||
const Comment = require('../../../../models/comment');
|
||||
const Action = require('../../../../models/action');
|
||||
const User = require('../../../../models/user');
|
||||
|
||||
|
||||
describe('Get /:comment_id', () => {
|
||||
describe('Get /comments', () => {
|
||||
const comments = [{
|
||||
id: 'abc',
|
||||
body: 'comment 10',
|
||||
asset_id: 'asset',
|
||||
author_id: '123'
|
||||
},{
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456'
|
||||
},{
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 30',
|
||||
asset_id: '456'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
id: '123',
|
||||
display_name: 'Ana',
|
||||
},{
|
||||
}, {
|
||||
id: '456',
|
||||
display_name: 'Maria',
|
||||
}]
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij'
|
||||
}]
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Comment.create(comments).then(() => {
|
||||
return User.create(users)
|
||||
return User.create(users);
|
||||
}).then(() => {
|
||||
return Action.create(actions)
|
||||
})
|
||||
})
|
||||
return Action.create(actions);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return all the comments', function(done){
|
||||
chai.request(app)
|
||||
@@ -61,46 +61,45 @@ describe('Get /:comment_id', () => {
|
||||
.end(function(err, res){
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(200);
|
||||
//expect(res).to.have.a.length(3); // it fails
|
||||
if (err) return done(err);
|
||||
done();
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post /comments', () => {
|
||||
const users = [{
|
||||
id: '123',
|
||||
display_name: 'Ana',
|
||||
},{
|
||||
}, {
|
||||
id: '456',
|
||||
display_name: 'Maria',
|
||||
}]
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij'
|
||||
}]
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return User.create(users).then(() => {
|
||||
return Action.create(actions)
|
||||
})
|
||||
})
|
||||
return Action.create(actions);
|
||||
});
|
||||
});
|
||||
|
||||
it('it should create a comment', function(done) {
|
||||
chai.request(app)
|
||||
.post('/api/v1/comments')
|
||||
.send({'body': 'Something body.', 'author_id': '123', 'asset_id': '1', 'parent_id': ''})
|
||||
.end(function(err, res){
|
||||
expect(res).to.have.status(200)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
expect(res).to.have.status(200);
|
||||
expect(res.body).to.have.property('id');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Get /:comment_id', () => {
|
||||
const comments = [{
|
||||
@@ -108,40 +107,40 @@ describe('Get /:comment_id', () => {
|
||||
body: 'comment 10',
|
||||
asset_id: 'asset',
|
||||
author_id: '123'
|
||||
},{
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456'
|
||||
},{
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 30',
|
||||
asset_id: '456'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
id: '123',
|
||||
display_name: 'Ana',
|
||||
},{
|
||||
}, {
|
||||
id: '456',
|
||||
display_name: 'Maria',
|
||||
}]
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij'
|
||||
}]
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Comment.create(comments).then(() => {
|
||||
return User.create(users)
|
||||
return User.create(users);
|
||||
}).then(() => {
|
||||
return Action.create(actions)
|
||||
})
|
||||
})
|
||||
return Action.create(actions);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the right comment for the comment_id', function(done){
|
||||
chai.request(app)
|
||||
@@ -150,11 +149,12 @@ describe('Get /:comment_id', () => {
|
||||
.end(function(err, res){
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(200);
|
||||
if (err) return done(err);
|
||||
expect(res.body[0]).to.have.property('body');
|
||||
expect(res.body[0].body).to.equal('comment 10');
|
||||
done();
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe('Put /:comment_id', () => {
|
||||
|
||||
@@ -163,51 +163,54 @@ describe('Put /:comment_id', () => {
|
||||
body: 'comment 10',
|
||||
asset_id: 'asset',
|
||||
author_id: '123'
|
||||
},{
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456'
|
||||
},{
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 30',
|
||||
asset_id: '456'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
id: '123',
|
||||
display_name: 'Ana',
|
||||
},{
|
||||
}, {
|
||||
id: '456',
|
||||
display_name: 'Maria',
|
||||
}]
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij'
|
||||
}]
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Comment.create(comments).then(() => {
|
||||
return User.create(users)
|
||||
return User.create(users);
|
||||
}).then(() => {
|
||||
return Action.create(actions)
|
||||
})
|
||||
})
|
||||
return Action.create(actions);
|
||||
});
|
||||
});
|
||||
|
||||
it('it should update comment', function(done) {
|
||||
chai.request(app)
|
||||
.post('/api/v1/comments/abc')
|
||||
.send({'body': 'Something body.', 'author_id': '123', 'asset_id': '1', 'parent_id': ''})
|
||||
.end(function(err, res){
|
||||
expect(res).to.have.status(200)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(200);
|
||||
expect(res.body).to.have.property('body');
|
||||
expect(res.body.body).to.equal('Something body.');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Delete /:comment_id', () => {
|
||||
|
||||
@@ -216,51 +219,53 @@ describe('Delete /:comment_id', () => {
|
||||
body: 'comment 10',
|
||||
asset_id: 'asset',
|
||||
author_id: '123'
|
||||
},{
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456'
|
||||
},{
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 30',
|
||||
asset_id: '456'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
id: '123',
|
||||
display_name: 'Ana',
|
||||
},{
|
||||
}, {
|
||||
id: '456',
|
||||
display_name: 'Maria',
|
||||
}]
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij'
|
||||
}]
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Comment.create(comments).then(() => {
|
||||
return User.create(users)
|
||||
return User.create(users);
|
||||
}).then(() => {
|
||||
return Action.create(actions)
|
||||
})
|
||||
})
|
||||
return Action.create(actions);
|
||||
});
|
||||
});
|
||||
|
||||
it('it should remove comment', function(done) {
|
||||
chai.request(app)
|
||||
.delete('/api/v1/comments/abc')
|
||||
.end(function(err, res){
|
||||
expect(res).to.have.status(201)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
expect(res).to.have.status(201);
|
||||
Comment.findById({'id': 'abc'}).then((comment) => {
|
||||
expect(comment).to.be.null;
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post /:comment_id/status', () => {
|
||||
|
||||
@@ -270,55 +275,57 @@ describe('Post /:comment_id/status', () => {
|
||||
asset_id: 'asset',
|
||||
author_id: '123',
|
||||
status: ''
|
||||
},{
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456',
|
||||
status: 'rejected'
|
||||
},{
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 30',
|
||||
asset_id: '456',
|
||||
status: 'accepted'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
id: '123',
|
||||
display_name: 'Ana',
|
||||
},{
|
||||
}, {
|
||||
id: '456',
|
||||
display_name: 'Maria',
|
||||
}]
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij'
|
||||
}]
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Comment.create(comments).then(() => {
|
||||
return User.create(users)
|
||||
return User.create(users);
|
||||
}).then(() => {
|
||||
return Action.create(actions)
|
||||
})
|
||||
})
|
||||
return Action.create(actions);
|
||||
});
|
||||
});
|
||||
|
||||
it('it should update status', function(done) {
|
||||
chai.request(app)
|
||||
.post('/api/v1/comments/abc/status')
|
||||
.send({'status': 'accepted'})
|
||||
.end(function(res){
|
||||
expect(res).to.have.status(200)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
.end(function(err, res){
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(200);
|
||||
expect(res).to.have.body;
|
||||
expect(res.body).to.have.property('status');
|
||||
expect(res.body.status).to.equal('accepted');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post /:comment_id/actions', () => {
|
||||
|
||||
@@ -328,50 +335,60 @@ describe('Post /:comment_id/actions', () => {
|
||||
asset_id: 'asset',
|
||||
author_id: '123',
|
||||
status: ''
|
||||
},{
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456',
|
||||
status: 'rejected'
|
||||
},{
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 30',
|
||||
asset_id: '456',
|
||||
status: 'accepted'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
id: '123',
|
||||
display_name: 'Ana',
|
||||
},{
|
||||
}, {
|
||||
id: '456',
|
||||
display_name: 'Maria',
|
||||
}]
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij'
|
||||
}]
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Comment.create(comments).then(() => {
|
||||
return User.create(users)
|
||||
return User.create(users);
|
||||
}).then(() => {
|
||||
return Action.create(actions)
|
||||
})
|
||||
})
|
||||
return Action.create(actions);
|
||||
});
|
||||
});
|
||||
|
||||
it('it should update status', function(done) {
|
||||
it('it should update actions', function(done) {
|
||||
chai.request(app)
|
||||
.post('/api/v1/comments/abc/actions')
|
||||
.send({'user_id': '456', 'action_type': 'flag'})
|
||||
.end(function(res){
|
||||
expect(res).to.have.status(200)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
.end(function(err, res){
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(200);
|
||||
expect(res).to.have.body;
|
||||
expect(res.body).to.have.property('item_type');
|
||||
expect(res.body.item_type).to.equal('comment');
|
||||
expect(res.body).to.have.property('action_type');
|
||||
expect(res.body.action_type).to.equal('flag');
|
||||
expect(res.body).to.have.property('item_id');
|
||||
expect(res.body.item_id).to.equal('abc');
|
||||
expect(res.body).to.have.property('user_id');
|
||||
expect(res.body.user_id).to.equal('456');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
require('../../../utils/mongoose');
|
||||
|
||||
const app = require('../../../../app');
|
||||
const chai = require('chai');
|
||||
const chaiHttp = require('chai-http');
|
||||
chai.use(chaiHttp);
|
||||
const expect = chai.expect;
|
||||
|
||||
const Setting = require('../../../../models/setting');
|
||||
const defaults = {id: '1', moderation: 'pre'};
|
||||
|
||||
describe('GET /settings', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
return Setting.update({id: '1'}, {$setOnInsert: defaults}, {upsert: true});
|
||||
});
|
||||
|
||||
it('should return a settings object', done => {
|
||||
chai.request(app)
|
||||
.get('/api/v1/settings')
|
||||
.end((err, res) => {
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(200);
|
||||
expect(res).to.be.json;
|
||||
expect(res.body).to.have.property('moderation');
|
||||
expect(res.body.moderation).to.equal('pre');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// update the settings.
|
||||
describe('update settings', () => {
|
||||
|
||||
before(() => {
|
||||
return Setting.update({id: '1'}, {$setOnInsert: defaults}, {upsert: true});
|
||||
});
|
||||
|
||||
it('should respond to a PUT with new settings', () => {
|
||||
chai.request(app)
|
||||
.put('/api/v1/settings')
|
||||
.send({moderation: 'post'}, (err, res) => {
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(204);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('should have updates settings', () => {
|
||||
chai.request(app)
|
||||
.get('/api/v1/settings')
|
||||
.end((err, res) => {
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(200);
|
||||
expect(res).to.be.json;
|
||||
expect(res.body).to.have.property('moderation');
|
||||
expect(res.body.moderation).to.equal('post');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2,9 +2,11 @@ require('../../../utils/mongoose');
|
||||
|
||||
const app = require('../../../../app');
|
||||
const chai = require('chai');
|
||||
const chaiHttp = require('chai-http');
|
||||
chai.use(chaiHttp);
|
||||
var expect = chai.expect;
|
||||
const expect = chai.expect;
|
||||
|
||||
// Setup chai.
|
||||
chai.should();
|
||||
chai.use(require('chai-http'));
|
||||
|
||||
const Action = require('../../../../models/action');
|
||||
const User = require('../../../../models/user');
|
||||
@@ -16,40 +18,40 @@ describe('api/stream: routes', () => {
|
||||
body: 'comment 10',
|
||||
asset_id: 'asset',
|
||||
author_id: '123'
|
||||
},{
|
||||
}, {
|
||||
id: 'def',
|
||||
body: 'comment 20',
|
||||
asset_id: 'asset',
|
||||
author_id: '456'
|
||||
},{
|
||||
}, {
|
||||
id: 'hij',
|
||||
body: 'comment 30',
|
||||
asset_id: '456'
|
||||
}]
|
||||
}];
|
||||
|
||||
const users = [{
|
||||
id: '123',
|
||||
display_name: 'John',
|
||||
},{
|
||||
}, {
|
||||
id: '456',
|
||||
display_name: 'Paul',
|
||||
}]
|
||||
}];
|
||||
|
||||
const actions = [{
|
||||
action_type: 'flag',
|
||||
item_id: 'abc'
|
||||
},{
|
||||
}, {
|
||||
action_type: 'like',
|
||||
item_id: 'hij'
|
||||
}]
|
||||
}];
|
||||
|
||||
beforeEach(() => {
|
||||
return Comment.create(comments).then(() => {
|
||||
return User.create(users)
|
||||
return User.create(users);
|
||||
}).then(() => {
|
||||
return Action.create(actions)
|
||||
})
|
||||
})
|
||||
return Action.create(actions);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a stream with comments, users and actions', function(done){
|
||||
chai.request(app)
|
||||
@@ -58,8 +60,8 @@ describe('api/stream: routes', () => {
|
||||
.end(function(err, res){
|
||||
expect(err).to.be.null;
|
||||
expect(res).to.have.status(200);
|
||||
if (err) return done(err);
|
||||
if (err) {return done(err);}
|
||||
done();
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var mongoose = require('mongoose');
|
||||
const mongoose = require('../../mongoose');
|
||||
|
||||
// Ensure the NODE_ENV is set to 'test',
|
||||
// this is helpful when you would like to change behavior when testing.
|
||||
@@ -6,18 +6,18 @@ process.env.NODE_ENV = 'test';
|
||||
|
||||
beforeEach(function (done) {
|
||||
function clearDB() {
|
||||
for (var i in mongoose.connection.collections) {
|
||||
for (let i in mongoose.connection.collections) {
|
||||
mongoose.connection.collections[i].remove(function() {});
|
||||
}
|
||||
return done();
|
||||
}
|
||||
|
||||
|
||||
if (mongoose.connection.readyState === 0) {
|
||||
mongoose.connect('coral-talk-test', function (err) {
|
||||
mongoose.on('open', function() {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
return clearDB();
|
||||
});
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user