- {props.actions.map((action, i) => canShowAction(action, props.comment) ? (
+ {props.actions.map((action, i) => canShowAction(action, comment) ? (
props.onClickAction(props.actionsMap[action].status, props.comment.get('id'))}
+ onClick={() => props.onClickAction(props.actionsMap[action].status, comment.get('id'))}
/>
) : null)}
diff --git a/client/coral-admin/src/components/CommentList.js b/client/coral-admin/src/components/CommentList.js
index e4682252d..40b99b892 100644
--- a/client/coral-admin/src/components/CommentList.js
+++ b/client/coral-admin/src/components/CommentList.js
@@ -112,13 +112,15 @@ export default class CommentList extends React.Component {
}
render () {
- const {singleView, commentIds, comments, hideActive, key} = this.props;
+ const {singleView, commentIds, comments, users, hideActive, key} = this.props;
const {active} = this.state;
return (
);
}
diff --git a/client/coral-admin/src/containers/CommentStream/CommentStream.js b/client/coral-admin/src/containers/CommentStream/CommentStream.js
index b1e002549..113a7bc86 100644
--- a/client/coral-admin/src/containers/CommentStream/CommentStream.js
+++ b/client/coral-admin/src/containers/CommentStream/CommentStream.js
@@ -40,7 +40,7 @@ class CommentStream extends React.Component {
}
// Render the comment box along with the CommentList
- render ({comments}, {snackbar, snackbarMsg}) {
+ render ({comments, users}, {snackbar, snackbarMsg}) {
return (
@@ -48,6 +48,7 @@ class CommentStream extends React.Component {
singleView={false}
commentIds={comments.get('ids')}
comments={comments.get('byId')}
+ users={users.get('byId')}
onClickAction={this.onClickAction}
actions={['flag']}
loading={comments.loading} />
@@ -57,4 +58,4 @@ class CommentStream extends React.Component {
}
}
-export default connect(({comments}) => ({comments}))(CommentStream);
+export default connect(({comments, users}) => ({comments, users}))(CommentStream);
diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js b/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js
index a4d82fddc..e5670d169 100644
--- a/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js
+++ b/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js
@@ -61,7 +61,7 @@ class ModerationQueue extends React.Component {
// Render the tabbed lists moderation queues
render () {
- const {comments} = this.props;
+ const {comments, users} = this.props;
const {activeTab, singleView, modalOpen} = this.state;
return (
@@ -82,10 +82,11 @@ class ModerationQueue extends React.Component {
commentIds={
comments.get('ids')
.filter(id => !comments.get('byId')
- .get(id)
- .get('status'))
+ .get(id)
+ .get('status'))
}
comments={comments.get('byId')}
+ users={users.get('byId')}
onClickAction={(action, id) => this.onCommentAction(action, id)}
actions={['reject', 'approve']}
loading={comments.loading} />
@@ -104,6 +105,7 @@ class ModerationQueue extends React.Component {
.get('status') === 'rejected')
}
comments={comments.get('byId')}
+ users={users.get('byId')}
onClickAction={(action, id) => this.onCommentAction(action, id)}
actions={['approve']}
loading={comments.loading} />
@@ -117,6 +119,7 @@ class ModerationQueue extends React.Component {
return !data.get('status') && data.get('flagged') === true;
})}
comments={comments.get('byId')}
+ users={users.get('byId')}
onClickAction={(action, id) => this.onCommentAction(action, id)}
actions={['reject', 'approve']}
loading={comments.loading} />
@@ -129,6 +132,6 @@ class ModerationQueue extends React.Component {
}
}
-export default connect(({comments}) => ({comments}))(ModerationQueue);
+export default connect(({comments, users}) => ({comments, users}))(ModerationQueue);
const lang = new I18n(translations);
diff --git a/client/coral-admin/src/reducers/auth.js b/client/coral-admin/src/reducers/auth.js
index f897c1bae..095ef7aac 100644
--- a/client/coral-admin/src/reducers/auth.js
+++ b/client/coral-admin/src/reducers/auth.js
@@ -24,10 +24,7 @@ export default function auth (state = initialState, action) {
.set('isAdmin', action.isAdmin)
.set('user', action.user);
case actions.LOGOUT_SUCCESS:
- return state
- .set('loggedIn', false)
- .set('user', null)
- .set('isAdmin', false);
+ return initialState;
default :
return state;
}
diff --git a/client/coral-admin/src/reducers/index.js b/client/coral-admin/src/reducers/index.js
index 61029539a..1f1b444fc 100644
--- a/client/coral-admin/src/reducers/index.js
+++ b/client/coral-admin/src/reducers/index.js
@@ -2,6 +2,7 @@ import {combineReducers} from 'redux';
import comments from 'reducers/comments';
import settings from 'reducers/settings';
import community from 'reducers/community';
+import users from 'reducers/users';
import auth from 'reducers/auth';
// Combine all reducers into a main one
@@ -9,6 +10,6 @@ export default combineReducers({
settings,
comments,
community,
- auth
+ auth,
+ users
});
-
diff --git a/client/coral-admin/src/reducers/users.js b/client/coral-admin/src/reducers/users.js
new file mode 100644
index 000000000..872ae904a
--- /dev/null
+++ b/client/coral-admin/src/reducers/users.js
@@ -0,0 +1,20 @@
+import {Map, List, fromJS} from 'immutable';
+
+const initialState = Map({
+ byId: Map(),
+ ids: List()
+});
+
+export default (state = initialState, action) => {
+ switch (action.type) {
+ case 'USERS_MODERATION_QUEUE_FETCH_SUCCESS': return replaceUsers(action, state);
+ default: return state;
+ }
+};
+
+// Replace the comment list with a new one
+const replaceUsers = (action, state) => {
+ const users = fromJS(action.users.reduce((prev, curr) => { prev[curr.id] = curr; return prev; }, {}));
+ return state.set('byId', users)
+ .set('ids', List(users.keys()));
+};
diff --git a/client/coral-admin/src/services/talk-adapter.js b/client/coral-admin/src/services/talk-adapter.js
index 15c9cf76a..5502df7ed 100644
--- a/client/coral-admin/src/services/talk-adapter.js
+++ b/client/coral-admin/src/services/talk-adapter.js
@@ -15,9 +15,6 @@ export default store => next => action => {
case 'COMMENTS_MODERATION_QUEUE_FETCH':
fetchModerationQueueComments(store);
break;
- // case 'COMMENT_STREAM_FETCH':
- // fetchCommentStream(store);
- // break;
case 'COMMENT_UPDATE':
updateComment(store, action.comment);
break;
@@ -38,12 +35,31 @@ Promise.all([
coralApi('/comments?action_type=flag')
])
.then(([pending, rejected, flagged]) => {
- flagged.forEach(comment => comment.flagged = true);
- return [...pending, ...rejected, ...flagged];
+ /* Combine seperate calls into a single object */
+ let all = {};
+ all.comments = pending.comments
+ .concat(rejected.comments)
+ .concat(flagged.comments.map(comment => {
+ comment.flagged = true;
+ return comment;
+ }));
+ all.users = pending.users
+ .concat(rejected.users)
+ .concat(flagged.users);
+ all.actions = pending.actions
+ .concat(rejected.actions)
+ .concat(flagged.actions);
+ return all;
})
-.then(res => store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS',
- comments: res}))
-.catch(error => store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_FAILED', error}));
+.then(all => {
+ /* Post comments and users to redux store. Actions will be posted when they are needed. */
+ store.dispatch({type: 'USERS_MODERATION_QUEUE_FETCH_SUCCESS',
+ users: all.users});
+ store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS',
+ comments: all.comments});
+
+});
+// .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
diff --git a/client/coral-embed-stream/src/CommentStream.js b/client/coral-embed-stream/src/CommentStream.js
index d2a7ddd18..7973c2a85 100644
--- a/client/coral-embed-stream/src/CommentStream.js
+++ b/client/coral-embed-stream/src/CommentStream.js
@@ -1,4 +1,7 @@
import React, {Component, PropTypes} from 'react';
+import Pym from 'pym.js';
+import {connect} from 'react-redux';
+
import {
itemActions,
Notification,
@@ -6,7 +9,7 @@ import {
authActions,
configActions
} from '../../coral-framework';
-import {connect} from 'react-redux';
+
import CommentBox from '../../coral-plugin-commentbox/CommentBox';
import InfoBox from '../../coral-plugin-infobox/InfoBox';
import Content from '../../coral-plugin-commentcontent/CommentContent';
@@ -14,47 +17,22 @@ import PubDate from '../../coral-plugin-pubdate/PubDate';
import Count from '../../coral-plugin-comment-count/CommentCount';
import AuthorName from '../../coral-plugin-author-name/AuthorName';
import {ReplyBox, ReplyButton} from '../../coral-plugin-replies';
-import Pym from 'pym.js';
import FlagButton from '../../coral-plugin-flags/FlagButton';
import LikeButton from '../../coral-plugin-likes/LikeButton';
import PermalinkButton from '../../coral-plugin-permalinks/PermalinkButton';
import SignInContainer from '../../coral-sign-in/containers/SignInContainer';
import UserBox from '../../coral-sign-in/components/UserBox';
-import {TabBar, Tab, TabContent, Button} from '../../coral-ui';
+
+import {TabBar, Tab, TabContent, Spinner, Button} from '../../coral-ui';
import SettingsContainer from '../../coral-settings/containers/SettingsContainer';
-import {Icon} from 'react-mdl';
+import RestrictedContent from '../../coral-framework/components/RestrictedContent';
+import SuspendedAccount from '../../coral-framework/components/SuspendedAccount';
const {addItem, updateItem, postItem, getStream, postAction, deleteAction, appendItemArray} = itemActions;
const {addNotification, clearNotification} = notificationActions;
-const {logout} = authActions;
+const {logout, showSignInDialog} = authActions;
const {updateOpenStatus} = configActions;
-const mapStateToProps = (state) => {
- return {
- config: state.config.toJS(),
- items: state.items.toJS(),
- notification: state.notification.toJS(),
- auth: state.auth.toJS()
- };
-};
-
-const mapDispatchToProps = (dispatch) => ({
- addItem: (item, itemType) => dispatch(addItem(item, itemType)),
- updateItem: (id, property, value, itemType) => dispatch(updateItem(id, property, value, itemType)),
- postItem: (data, type, id) => dispatch(postItem(data, type, id)),
- getStream: (rootId) => dispatch(getStream(rootId)),
- addNotification: (type, text) => dispatch(addNotification(type, text)),
- clearNotification: () => dispatch(clearNotification()),
- postAction: (item, action, user, itemType) => dispatch(postAction(item, action, user, itemType)),
- deleteAction: (item, action, user, itemType) => {
- return dispatch(deleteAction(item, action, user, itemType));
- },
- appendItemArray: (item, property, value, addToFront, itemType) =>
- dispatch(appendItemArray(item, property, value, addToFront, itemType)),
- logout: () => dispatch(logout()),
- updateStatus: status => dispatch(updateOpenStatus(status))
-});
-
class CommentStream extends Component {
constructor (props) {
@@ -87,47 +65,22 @@ class CommentStream extends Component {
componentDidMount () {
// Set up messaging between embedded Iframe an parent component
// Using recommended Pym init code which violates .eslint standards
- this.pym = new Pym.Child({polling: 100});
+ const pym = new Pym.Child({polling: 100});
- const path = this.pym.parentUrl.split('#')[0];
-
- this.props.getStream(path || window.location);
- this.path = path;
-
- this.pym.sendMessage('childReady');
-
- this.pym.onMessage('DOMContentLoaded', hash => {
- // the comment ids can start with numbers, which is invalid for DOM id attributes
- const commentId = hash.replace('#', 'c_');
- let count = 0;
- const interval = setInterval(() => {
- if (document.getElementById(commentId)) {
- window.clearInterval(interval);
- this.pym.scrollParentToChildEl(commentId);
- }
-
- if (++count > 100) { // ~10 seconds
- // give up waiting for the comments to load.
- // it would be weird for the page to jump after that long.
- window.clearInterval(interval);
- }
- }, 100);
- });
+ if (/https?\:\/\/([^?]+)/.test(pym.parentUrl)) {
+ this.props.getStream(pym.parentUrl);
+ } else {
+ this.props.getStream(window.location);
+ }
}
render () {
if (Object.keys(this.props.items).length === 0) {
- // Loading mock asset
+ // Loading mock asset
this.props.postItem({
comments: [],
url: 'http://coralproject.net'
}, 'asset', 'assetTest');
-
- // Loading mock user
- //this.props.postItem({name: 'Ban Ki-Moon'}, 'user', 'user_8989')
- // .then((id) => {
- // this.props.setLoggedInUser(id);
- // });
}
// TODO: Replace teststream id with id from params
@@ -142,73 +95,76 @@ class CommentStream extends Component {
return
{
rootItem
- ?
+ ?
Settings
Configure Stream
-
-
- {
- status === 'open'
- ?
- : Comments are closed for this thread
- }
- {
- rootItem.comments && rootItem.comments.map((commentId) => {
- const comment = comments[commentId];
- return
- : 'Loading'
+ :
+
}
;
}
@@ -315,4 +284,28 @@ const CloseCommentsInfo = ({ status, onClick }) => status === 'open' ? (
)
+const mapStateToProps = state => ({
+ config: state.config.toJS(),
+ items: state.items.toJS(),
+ notification: state.notification.toJS(),
+ auth: state.auth.toJS(),
+ userData: state.user.toJS()
+});
+
+const mapDispatchToProps = (dispatch) => ({
+ addItem: (item, itemType) => dispatch(addItem(item, itemType)),
+ updateItem: (id, property, value, itemType) => dispatch(updateItem(id, property, value, itemType)),
+ postItem: (data, type, id) => dispatch(postItem(data, type, id)),
+ getStream: (rootId) => dispatch(getStream(rootId)),
+ addNotification: (type, text) => dispatch(addNotification(type, text)),
+ clearNotification: () => dispatch(clearNotification()),
+ showSignInDialog: () => dispatch(showSignInDialog()),
+ postAction: (item, action, user, itemType) => dispatch(postAction(item, action, user, itemType)),
+ deleteAction: (item, action, user, itemType) => dispatch(deleteAction(item, action, user, itemType)),
+ appendItemArray: (item, property, value, addToFront, itemType) => dispatch(appendItemArray(item, property, value, addToFront, itemType)),
+ handleSignInDialog: () => dispatch(authActions.showSignInDialog()),
+ logout: () => dispatch(logout()),
+ updateStatus: status => dispatch(updateOpenStatus(status))
+});
+
export default connect(mapStateToProps, mapDispatchToProps)(CommentStream);
diff --git a/client/coral-embed-stream/style/default.css b/client/coral-embed-stream/style/default.css
index f83541527..59efc3dc8 100644
--- a/client/coral-embed-stream/style/default.css
+++ b/client/coral-embed-stream/style/default.css
@@ -56,12 +56,14 @@ hr {
/* Info Box Styles */
.coral-plugin-infobox-info {
- position: fixed;
top: 0;
border: 0;
background: rgb(105,105,105);
color: white;
- border-radius: 2px;
+ width: 100%;
+ text-align: center;
+ padding: 10px;
+ margin-bottom: 10px;
font-weight: bold;
display: block;
}
@@ -84,6 +86,7 @@ hr {
.coral-plugin-commentbox-textarea {
flex: 1;
padding: 5px;
+ min-height: 100px;
}
.coral-plugin-commentbox-button-container {
@@ -110,6 +113,7 @@ hr {
/* Comment styles */
.comment {
+ position: relative;
margin-bottom: 10px;
position: relative;
}
diff --git a/client/coral-framework/actions/user.js b/client/coral-framework/actions/user.js
new file mode 100644
index 000000000..72075e6db
--- /dev/null
+++ b/client/coral-framework/actions/user.js
@@ -0,0 +1,21 @@
+import * as actions from '../constants/user';
+import {addNotification} from '../actions/notification';
+import coralApi from '../helpers/response';
+
+import I18n from 'coral-framework/modules/i18n/i18n';
+import translations from './../translations';
+const lang = new I18n(translations);
+
+const saveBioRequest = () => ({type: actions.SAVE_BIO_REQUEST});
+const saveBioSuccess = settings => ({type: actions.SAVE_BIO_SUCCESS, settings});
+const saveBioFailure = error => ({type: actions.SAVE_BIO_FAILURE, error});
+
+export const saveBio = (user_id, formData) => dispatch => {
+ dispatch(saveBioRequest());
+ coralApi(`/user/${user_id}/bio`, {method: 'PUT', body: formData})
+ .then(({settings}) => {
+ dispatch(addNotification('success', lang.t('successBioUpdate')));
+ dispatch(saveBioSuccess(settings));
+ })
+ .catch(error => dispatch(saveBioFailure(error)));
+};
diff --git a/client/coral-framework/components/RestrictedContent.css b/client/coral-framework/components/RestrictedContent.css
new file mode 100644
index 000000000..47ced7b0b
--- /dev/null
+++ b/client/coral-framework/components/RestrictedContent.css
@@ -0,0 +1,4 @@
+.message {
+ background: #D8D8D8;
+ padding: 25px;
+}
diff --git a/client/coral-framework/components/RestrictedContent.js b/client/coral-framework/components/RestrictedContent.js
new file mode 100644
index 000000000..32aaf632d
--- /dev/null
+++ b/client/coral-framework/components/RestrictedContent.js
@@ -0,0 +1,20 @@
+import React from 'react';
+import styles from './RestrictedContent.css';
+
+import I18n from 'coral-framework/modules/i18n/i18n';
+import translations from 'coral-framework/translations.json';
+const lang = new I18n(translations);
+
+export default ({children, restricted, message = lang.t('contentNotAvailable'), restrictedComp}) => {
+ if (restricted) {
+ return restrictedComp ? restrictedComp : messageBox(message);
+ } else {
+ return (
+
+ {children}
+
+ );
+ }
+};
+
+const messageBox = (message) =>
{message}
;
diff --git a/client/coral-framework/components/SuspendedAccount.js b/client/coral-framework/components/SuspendedAccount.js
new file mode 100644
index 000000000..5a23b77a2
--- /dev/null
+++ b/client/coral-framework/components/SuspendedAccount.js
@@ -0,0 +1,8 @@
+import React from 'react';
+import I18n from 'coral-framework/modules/i18n/i18n';
+import translations from 'coral-framework/translations.json';
+const lang = new I18n(translations);
+
+export default () => (
+
{lang.t('suspendedAccountMsg')}
+);
diff --git a/client/coral-framework/constants/user.js b/client/coral-framework/constants/user.js
new file mode 100644
index 000000000..0c316d48a
--- /dev/null
+++ b/client/coral-framework/constants/user.js
@@ -0,0 +1,3 @@
+export const SAVE_BIO_REQUEST = 'SAVE_BIO_REQUEST';
+export const SAVE_BIO_SUCCESS = 'SAVE_BIO_SUCCESS';
+export const SAVE_BIO_FAILURE = 'SAVE_BIO_FAILURE';
diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js
index a445fc663..a4803fa96 100644
--- a/client/coral-framework/reducers/auth.js
+++ b/client/coral-framework/reducers/auth.js
@@ -13,6 +13,11 @@ const initialState = Map({
successSignUp: false
});
+const purge = user => {
+ const {settings, profiles, ...userData} = user; // eslint-disable-line
+ return userData;
+};
+
export default function auth (state = initialState, action) {
switch (action.type) {
case actions.SHOW_SIGNIN_DIALOG :
@@ -44,11 +49,11 @@ export default function auth (state = initialState, action) {
case actions.CHECK_LOGIN_SUCCESS:
return state
.set('loggedIn', true)
- .set('user', action.user);
+ .set('user', purge(action.user));
case actions.FETCH_SIGNIN_SUCCESS:
return state
.set('loggedIn', true)
- .set('user', action.user);
+ .set('user', purge(action.user));
case actions.FETCH_SIGNIN_FAILURE:
return state
.set('isLoading', false)
@@ -56,7 +61,7 @@ export default function auth (state = initialState, action) {
.set('user', null);
case actions.FETCH_SIGNIN_FACEBOOK_SUCCESS:
return state
- .set('user', action.user)
+ .set('user', purge(action.user))
.set('loggedIn', true);
case actions.FETCH_SIGNIN_FACEBOOK_FAILURE:
return state
diff --git a/client/coral-framework/reducers/index.js b/client/coral-framework/reducers/index.js
index 90eaa7cb7..a2f439028 100644
--- a/client/coral-framework/reducers/index.js
+++ b/client/coral-framework/reducers/index.js
@@ -5,6 +5,7 @@ import config from './config';
import items from './items';
import notification from './notification';
import auth from './auth';
+import user from './user';
/**
* Expose the combined main reducer
@@ -15,4 +16,5 @@ export default combineReducers({
items,
notification,
auth,
+ user
});
diff --git a/client/coral-framework/reducers/user.js b/client/coral-framework/reducers/user.js
new file mode 100644
index 000000000..11b57fc15
--- /dev/null
+++ b/client/coral-framework/reducers/user.js
@@ -0,0 +1,36 @@
+import {Map} from 'immutable';
+import * as authActions from '../constants/auth';
+import * as actions from '../constants/user';
+
+const initialState = Map({
+ displayName: '',
+ profiles: [],
+ settings: {}
+});
+
+const purge = user => {
+ const {_id, created_at, updated_at, __v, roles, ...userData} = user; // eslint-disable-line
+ return userData;
+};
+
+export default function user (state = initialState, action) {
+ switch (action.type) {
+ case authActions.CHECK_LOGIN_SUCCESS:
+ return state.merge(Map(purge(action.user)));
+ case authActions.CHECK_LOGIN_FAILURE:
+ return initialState;
+ case authActions.FETCH_SIGNIN_SUCCESS:
+ return state.merge(Map(purge(action.user)));
+ case authActions.FETCH_SIGNIN_FAILURE:
+ return initialState;
+ case authActions.FETCH_SIGNIN_FACEBOOK_SUCCESS:
+ return state.merge(Map(purge(action.user)));
+ case authActions.FETCH_SIGNIN_FACEBOOK_FAILURE:
+ return initialState;
+ case actions.SAVE_BIO_SUCCESS:
+ return state
+ .set('settings', action.settings);
+ default :
+ return state;
+ }
+}
diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json
index 4abd1ed03..ab65ba565 100644
--- a/client/coral-framework/translations.json
+++ b/client/coral-framework/translations.json
@@ -1,5 +1,8 @@
{
"en": {
+ "successBioUpdate": "Your Bio has been updated",
+ "contentNotAvailable": "This content is not available",
+ "suspendedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Flag, or write comments. Please contact moderator@fakeurl.com for more information",
"error": {
"email": "Not a valid E-Mail",
"password": "Password must be at least 8 characters",
@@ -10,6 +13,9 @@
}
},
"es": {
+ "successBioUpdate": "Tu bio fue actualizada",
+ "contentNotAvailable": "El contenido no se encuentra disponible",
+ "suspendedAccountMsg": "Tu cuenta se encuentra suspendida. Esto significa que no puedes dar Like, Marcar o escribir commentarios. Por favor, contacta moderator@fakeurl for more information",
"error": {
"email": "No es un email válido",
"password": "La contraseña debe tener por lo menos 8 caracteres",
@@ -19,4 +25,4 @@
"emailInUse": "Email address already in use"
}
}
-}
\ No newline at end of file
+}
diff --git a/client/coral-plugin-author-name/AuthorName.js b/client/coral-plugin-author-name/AuthorName.js
index aef819468..56b868726 100644
--- a/client/coral-plugin-author-name/AuthorName.js
+++ b/client/coral-plugin-author-name/AuthorName.js
@@ -1,9 +1,43 @@
-import React from 'react';
+import React, {Component} from 'react';
+import {Tooltip} from 'coral-ui';
const packagename = 'coral-plugin-author-name';
-const AuthorName = ({author}) =>
-
- {author && author.displayName}
-
;
+export default class AuthorName extends Component {
+ constructor (props) {
+ super(props);
-export default AuthorName;
+ this.state = {
+ showTooltip: false
+ };
+
+ this.handleMouseOver = this.handleMouseOver.bind(this);
+ this.handleMouseLeave = this.handleMouseLeave.bind(this);
+ }
+
+ handleMouseOver () {
+ this.setState({
+ showTooltip: true
+ });
+ }
+
+ handleMouseLeave () {
+ this.setState({
+ showTooltip: false
+ });
+ }
+
+ render () {
+ const {author} = this.props;
+ const {showTooltip} = this.state;
+ return (
+
+ {author && author.displayName}
+ { showTooltip && {author.settings.bio} }
+
+ );
+ }
+}
diff --git a/client/coral-plugin-commentbox/CommentBox.js b/client/coral-plugin-commentbox/CommentBox.js
index 79641d856..9ae524652 100644
--- a/client/coral-plugin-commentbox/CommentBox.js
+++ b/client/coral-plugin-commentbox/CommentBox.js
@@ -1,6 +1,7 @@
import React, {Component, PropTypes} from 'react';
import {I18n} from '../coral-framework';
import translations from './translations.json';
+import {Button} from 'coral-ui';
const name = 'coral-plugin-commentbox';
@@ -75,12 +76,11 @@ class CommentBox extends Component {
{ author && (
-
{lang.t('post')}
-
+
)
}
diff --git a/client/coral-plugin-flags/FlagButton.js b/client/coral-plugin-flags/FlagButton.js
index cbb0fef63..f0ab1b22f 100644
--- a/client/coral-plugin-flags/FlagButton.js
+++ b/client/coral-plugin-flags/FlagButton.js
@@ -4,10 +4,11 @@ import translations from './translations.json';
const name = 'coral-plugin-flags';
-const FlagButton = ({flag, id, postAction, deleteAction, addItem, updateItem, addNotification, currentUser}) => {
+const FlagButton = ({flag, id, postAction, deleteAction, addItem, showSignInDialog, updateItem, addNotification, currentUser}) => {
const flagged = flag && flag.current_user;
const onFlagClick = () => {
if (!currentUser) {
+ showSignInDialog();
return;
}
if (!flagged) {
diff --git a/client/coral-plugin-likes/LikeButton.js b/client/coral-plugin-likes/LikeButton.js
index 07f27c426..b3d31fbf4 100644
--- a/client/coral-plugin-likes/LikeButton.js
+++ b/client/coral-plugin-likes/LikeButton.js
@@ -4,10 +4,11 @@ import translations from './translations.json';
const name = 'coral-plugin-flags';
-const LikeButton = ({like, id, postAction, deleteAction, addItem, updateItem, currentUser}) => {
+const LikeButton = ({like, id, postAction, deleteAction, addItem, showSignInDialog, updateItem, currentUser}) => {
const liked = like && like.current_user;
const onLikeClick = () => {
if (!currentUser) {
+ showSignInDialog();
return;
}
if (!liked) {
diff --git a/client/coral-settings/components/Bio.js b/client/coral-settings/components/Bio.js
index b82587322..cd1347781 100644
--- a/client/coral-settings/components/Bio.js
+++ b/client/coral-settings/components/Bio.js
@@ -2,15 +2,17 @@ import React from 'react';
import styles from './Bio.css';
import {Button} from '../../coral-ui';
-export default () => (
+export default ({bio, handleSave, handleInput, handleCancel}) => (
Bio
Tell the community about yourself
-
-
- Cancel
- Save Changes
-
+
);
diff --git a/client/coral-settings/components/NotLoggedIn.css b/client/coral-settings/components/NotLoggedIn.css
new file mode 100644
index 000000000..f65e96507
--- /dev/null
+++ b/client/coral-settings/components/NotLoggedIn.css
@@ -0,0 +1,15 @@
+.message {
+ padding: 10px 0 20px;
+ letter-spacing: 0.1px;
+ font-size: 13px;
+ line-height: 33px;
+}
+
+.message a {
+ color: black;
+ font-weight: bold;
+ cursor: pointer;
+ margin: 0px;
+ padding-bottom: 2px;
+ border-bottom: solid 1px black;
+}
diff --git a/client/coral-settings/components/NotLoggedIn.js b/client/coral-settings/components/NotLoggedIn.js
new file mode 100644
index 000000000..d7bf467e8
--- /dev/null
+++ b/client/coral-settings/components/NotLoggedIn.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import styles from './NotLoggedIn.css';
+
+export default ({showSignInDialog}) => (
+
+
+
+ From the Settings Page you can
+
+ See your comment history
+ Write a bio about yourself to display to the community
+
+
+
+);
diff --git a/client/coral-settings/components/SettingsHeader.js b/client/coral-settings/components/SettingsHeader.js
index 24d68af9a..b55f008ad 100644
--- a/client/coral-settings/components/SettingsHeader.js
+++ b/client/coral-settings/components/SettingsHeader.js
@@ -1,10 +1,10 @@
import React from 'react';
import styles from './SettingsHeader.css';
-export default () => (
+export default ({userData}) => (
-
Jackson
- jackson_persona@gmail.com
+ {userData.displayName}
+ {userData.profiles.map(profile => profile.id)}
);
diff --git a/client/coral-settings/containers/BioContainer.js b/client/coral-settings/containers/BioContainer.js
new file mode 100644
index 000000000..b7c9611d4
--- /dev/null
+++ b/client/coral-settings/containers/BioContainer.js
@@ -0,0 +1,45 @@
+import React, {Component} from 'react';
+import Bio from '../components/Bio';
+
+export default class BioContainer extends Component {
+ constructor (props) {
+ super(props);
+
+ this.state = {
+ bio: props.bio
+ };
+
+ this.handleSave = this.handleSave.bind(this);
+ this.handleInput = this.handleInput.bind(this);
+ this.handleCancel = this.handleCancel.bind(this);
+ }
+
+ handleInput(e) {
+ this.setState({
+ bio: e.target.value
+ });
+ }
+
+ handleSave (e) {
+ e.preventDefault();
+ const {userData, saveBio} = this.props;
+ const {bio} = this.state;
+ saveBio(userData.id, {bio});
+ }
+
+ handleCancel () {
+ this.setState({
+ bio: this.props.bio
+ });
+ }
+
+ render () {
+ return
;
+ }
+}
diff --git a/client/coral-settings/containers/SettingsContainer.js b/client/coral-settings/containers/SettingsContainer.js
index 224eb6c6a..96020a10c 100644
--- a/client/coral-settings/containers/SettingsContainer.js
+++ b/client/coral-settings/containers/SettingsContainer.js
@@ -1,24 +1,26 @@
import React, {Component} from 'react';
import {connect} from 'react-redux';
-import {TabBar, Tab} from '../../coral-ui';
+import {saveBio} from 'coral-framework/actions/user';
-import Bio from '../components/Bio';
+import BioContainer from './BioContainer';
+import NotLoggedIn from '../components/NotLoggedIn';
+import {TabBar, Tab, TabContent} from '../../coral-ui';
import CommentHistory from '../components/CommentHistory';
import SettingsHeader from '../components/SettingsHeader';
+import RestrictedContent from 'coral-framework/components/RestrictedContent';
class SignInContainer extends Component {
constructor (props) {
super(props);
this.state = {
- activeTab: 0
+ activeTab: 0,
};
this.handleTabChange = this.handleTabChange.bind(this);
}
componentWillMount () {
- // Get Bio
// Fetch commentHistory
}
@@ -29,18 +31,22 @@ class SignInContainer extends Component {
}
render() {
- //const {embedStream} = this.props;
+ const {loggedIn, userData, showSignInDialog} = this.props;
const {activeTab} = this.state;
return (
-
-
+ }>
+
All Comments (120)
Profile Settings
- { activeTab === 0 && }
- { activeTab === 1 && }
-
+
+
+
+
+
+
+
);
}
}
@@ -49,10 +55,8 @@ const mapStateToProps = () => ({
});
const mapDispatchToProps = dispatch => ({
- getBio: () => dispatch(),
+ saveBio: (user_id, formData) => dispatch(saveBio(user_id, formData)),
getHistory: () => dispatch(),
- handleSaveChanges: () => dispatch(),
- handleCancel: () => dispatch()
});
export default connect(
diff --git a/client/coral-sign-in/components/UserBox.js b/client/coral-sign-in/components/UserBox.js
index 17c8453fb..11badfaef 100644
--- a/client/coral-sign-in/components/UserBox.js
+++ b/client/coral-sign-in/components/UserBox.js
@@ -1,12 +1,15 @@
import React from 'react';
import styles from './styles.css';
+import I18n from 'coral-framework/modules/i18n/i18n';
+import translations from '../translations';
+const lang = new I18n(translations);
const UserBox = ({className, user, logout, ...props}) => (
);
diff --git a/client/coral-sign-in/components/styles.css b/client/coral-sign-in/components/styles.css
index e645885ce..2bec52b45 100644
--- a/client/coral-sign-in/components/styles.css
+++ b/client/coral-sign-in/components/styles.css
@@ -103,10 +103,18 @@ input.error{
color: #B71C1C;
}
+.userBox {
+ padding: 10px 0 20px;
+ letter-spacing: 0.1px;
+}
+
.userBox a {
- color: #2c69b6;
+ color: black;
+ font-weight: bold;
cursor: pointer;
margin: 0px;
+ padding-bottom: 2px;
+ border-bottom: solid 1px black;
}
.attention {
diff --git a/client/coral-sign-in/containers/SignInContainer.js b/client/coral-sign-in/containers/SignInContainer.js
index c2b8c7836..c201a3863 100644
--- a/client/coral-sign-in/containers/SignInContainer.js
+++ b/client/coral-sign-in/containers/SignInContainer.js
@@ -129,12 +129,10 @@ class SignInContainer extends Component {
}
render() {
- const {auth, showSignInDialog} = this.props;
+ const {auth, showSignInDialog, noButton} = this.props;
return (
-
- Sign in to comment
-
+ {!noButton && Sign in to comment }
(
+ {children}
+);
diff --git a/client/coral-ui/index.js b/client/coral-ui/index.js
index 6f2192cc4..ffdb3bbd2 100644
--- a/client/coral-ui/index.js
+++ b/client/coral-ui/index.js
@@ -5,3 +5,5 @@ export {default as TabBar} from './components/TabBar';
export {default as Tab} from './components/Tab';
export {default as TabContent} from './components/TabContent';
export {default as Button} from './components/Button';
+export {default as Spinner} from './components/Spinner';
+export {default as Tooltip} from './components/Tooltip';
diff --git a/models/setting.js b/models/setting.js
index f0c6a1abc..bf5ac290a 100644
--- a/models/setting.js
+++ b/models/setting.js
@@ -38,11 +38,11 @@ SettingSchema.statics.getSettings = function () {
};
/**
- * Gets the moderation settings and sends it back
+ * Gets the settings visible to the public
* @return {Promise} moderation the settings for how to moderate comments
*/
-SettingSchema.statics.getModerationSetting = function () {
- return this.findOne({id: '1'}).select('moderation');
+SettingSchema.statics.getPublicSettings = function () {
+ return this.findOne({id: '1'}).select('moderation infoBoxEnable infoBoxContent');
};
/**
@@ -50,7 +50,7 @@ SettingSchema.statics.getModerationSetting = function () {
* @return {Promise} content the content of the info Box
*/
SettingSchema.statics.getInfoBoxSetting = function () {
- return this.findOne({id: '1'}).select('infoBoxEnable', 'infoBoxContent');
+ return this.findOne({id: '1'}).select('infoBoxEnable infoBoxContent');
};
/**
diff --git a/models/user.js b/models/user.js
index 845b84d19..86908ab42 100644
--- a/models/user.js
+++ b/models/user.js
@@ -74,7 +74,15 @@ const UserSchema = new mongoose.Schema({
// Roles provides an array of roles (as strings) that is associated with a
// user.
- roles: [String]
+ roles: [String],
+
+ // User's settings
+ settings: {
+ bio: {
+ type: String,
+ default: ''
+ }
+ }
}, {
// This will ensure that we have proper timestamps available on this model.
@@ -522,3 +530,20 @@ UserService.count = () => {
UserService.all = () => {
return UserModel.find();
};
+
+/**
+ * Adds a new User bio
+ * @return {Promise}
+ */
+
+UserService.addBio = (id, bio) => (
+ UserModel.findOneAndUpdate({
+ id
+ }, {
+ $set: {
+ 'settings.bio': bio
+ }
+ }, {
+ new: true
+ })
+);
diff --git a/routes/api/comments/index.js b/routes/api/comments/index.js
index bfb3d67ab..3bdf4afc6 100644
--- a/routes/api/comments/index.js
+++ b/routes/api/comments/index.js
@@ -1,7 +1,10 @@
const express = require('express');
const Comment = require('../../../models/comment');
+const User = require('../../../models/user');
+const Action = require('../../../models/action');
const wordlist = require('../../../services/wordlist');
const authorization = require('../../../middleware/authorization');
+const _ = require('lodash');
const router = express.Router();
@@ -16,9 +19,22 @@ router.get('/', authorization.needed('admin'), (req, res, next) => {
query = Comment.all();
}
- query.then(comments => {
- res.json(comments);
+ query.then((comments) => {
+ return Promise.all([
+ comments,
+ User.findByIdArray(_.uniq(comments.map((comment) => comment.author_id))),
+ Action.getActionSummaries(_.uniq([
+ ...comments.map((comment) => comment.id),
+ ...comments.map((comment) => comment.author_id)
+ ]))
+ ]);
})
+ .then(([comments, users, actions])=>
+ res.status(200).json({
+ comments,
+ users,
+ actions
+ }))
.catch((err) => {
next(err);
});
diff --git a/routes/api/queue/index.js b/routes/api/queue/index.js
index f661992f1..b38d1b763 100644
--- a/routes/api/queue/index.js
+++ b/routes/api/queue/index.js
@@ -1,6 +1,9 @@
const express = require('express');
const Comment = require('../../../models/comment');
+const User = require('../../../models/user');
+const Action = require('../../../models/action');
const Setting = require('../../../models/setting');
+const _ = require('lodash');
const router = express.Router();
@@ -13,11 +16,24 @@ const router = express.Router();
// Pre-moderation: New comments are shown in the moderator queues immediately.
// Post-moderation: New comments do not appear in moderation queues unless they are flagged by other users.
router.get('/comments/pending', (req, res, next) => {
- Setting.getModerationSetting().then(function({moderation}){
- Comment.moderationQueue(moderation).then((comments) => {
- res.status(200).json(comments);
- });
+ Setting.getPublicSettings().then(({moderation}) =>
+ Comment.moderationQueue(moderation))
+ .then((comments) => {
+ return Promise.all([
+ comments,
+ User.findByIdArray(_.uniq(comments.map((comment) => comment.author_id))),
+ Action.getActionSummaries(_.uniq([
+ ...comments.map((comment) => comment.id),
+ ...comments.map((comment) => comment.author_id)
+ ]))
+ ]);
})
+ .then(([comments, users, actions])=>
+ res.status(200).json({
+ comments,
+ users,
+ actions
+ }))
.catch(error => {
next(error);
});
diff --git a/routes/api/stream/index.js b/routes/api/stream/index.js
index 5a110e2d6..4e8373999 100644
--- a/routes/api/stream/index.js
+++ b/routes/api/stream/index.js
@@ -26,15 +26,15 @@ router.get('/', (req, res, next) => {
return asset;
}),
- // Get the moderation setting from the settings.
- Setting.getModerationSetting()
+ // Get the public settings.
+ Setting.getPublicSettings()
])
.then(([asset, settings]) => {
// Merge the asset specific settings with the returned settings object in
// the event that the asset that was returned also had settings.
if (asset.settings) {
- settings = Object.assign(settings, asset.settings);
+ settings = Object.assign({}, settings, asset.settings);
}
// Fetch the appropriate comments stream.
diff --git a/routes/api/user/index.js b/routes/api/user/index.js
index 43d3b8ac0..1765809ad 100644
--- a/routes/api/user/index.js
+++ b/routes/api/user/index.js
@@ -140,4 +140,21 @@ router.post('/request-password-reset', (req, res, next) => {
});
});
+router.put('/:user_id/bio', (req, res, next) => {
+ const {user_id} = req.params;
+ const {bio} = req.body;
+
+ if (!bio) {
+ return next('You must submit a new bio');
+ }
+
+ User
+ .addBio(user_id, bio)
+ .then(user => res.status(200).send(user))
+ .catch(error => {
+ const errorMsg = typeof error === 'string' ? error : error.message;
+ res.status(500).json({error: errorMsg});
+ });
+});
+
module.exports = router;
diff --git a/tests/models/setting.js b/tests/models/setting.js
index 08a47d7a1..186a65245 100644
--- a/tests/models/setting.js
+++ b/tests/models/setting.js
@@ -4,7 +4,9 @@ const expect = require('chai').expect;
describe('Setting: model', () => {
beforeEach(() => {
- const defaults = {id: 1};
+ const defaults = {
+ id: 1
+ };
return Setting.update({id: '1'}, {$setOnInsert: defaults}, {upsert: true});
});
@@ -35,10 +37,13 @@ describe('Setting: model', () => {
});
});
- describe('#getModerationSetting', () => {
+ describe('#getPublicSettings', () => {
it('should return the moderation settings', () => {
- return Setting.getModerationSetting().then(({moderation}) => {
+ return Setting.getPublicSettings().then(({moderation, infoBoxEnable, infoBoxContent, wordlist}) => {
expect(moderation).not.to.be.null;
+ expect(infoBoxEnable).not.to.be.null;
+ expect(infoBoxContent).not.to.be.null;
+ expect(wordlist).to.be.undefined;
});
});
});
diff --git a/tests/routes/api/comments/index.js b/tests/routes/api/comments/index.js
index 5ac9af7b7..bc8b67bc1 100644
--- a/tests/routes/api/comments/index.js
+++ b/tests/routes/api/comments/index.js
@@ -37,6 +37,7 @@ describe('/api/v1/comments', () => {
id: 'hij',
body: 'comment 30',
asset_id: '456',
+ author_id: '456',
status: 'accepted'
}];
@@ -90,7 +91,7 @@ describe('/api/v1/comments', () => {
.set(passport.inject({roles: ['admin']}))
.then((res) => {
expect(res).to.have.status(200);
- expect(res.body[0]).to.have.property('id', 'def-rejected');
+ expect(res.body.comments[0]).to.have.property('id', 'def-rejected');
});
});
@@ -100,8 +101,8 @@ describe('/api/v1/comments', () => {
.set(passport.inject({roles: ['admin']}))
.then((res) => {
expect(res).to.have.status(200);
- expect(res.body).to.have.length(1);
- expect(res.body[0]).to.have.property('id', 'hij');
+ expect(res.body.comments).to.have.length(1);
+ expect(res.body.comments[0]).to.have.property('id', 'hij');
});
});
@@ -111,7 +112,7 @@ describe('/api/v1/comments', () => {
.set(passport.inject({roles: ['admin']}))
.then((res) => {
expect(res).to.have.status(200);
- expect(res.body).to.have.length(2);
+ expect(res.body.comments).to.have.length(2);
});
});
@@ -122,8 +123,8 @@ describe('/api/v1/comments', () => {
.then((res) => {
expect(res).to.have.status(200);
- expect(res.body).to.have.length(1);
- expect(res.body[0]).to.have.property('id', 'abc');
+ expect(res.body.comments).to.have.length(1);
+ expect(res.body.comments[0]).to.have.property('id', 'abc');
});
});
diff --git a/tests/routes/api/queue/index.js b/tests/routes/api/queue/index.js
index 733e5a1be..1e99ae61e 100644
--- a/tests/routes/api/queue/index.js
+++ b/tests/routes/api/queue/index.js
@@ -15,63 +15,81 @@ const User = require('../../../../models/user');
const Setting = require('../../../../models/setting');
const settings = {id: '1', moderation: 'pre'};
-describe('/api/v1/queue', () => {
- const comments = [{
- id: 'abc',
- body: 'comment 10',
- asset_id: 'asset',
- author_id: '123',
- status: 'rejected'
- }, {
- id: 'def',
- body: 'comment 20',
- asset_id: 'asset',
- author_id: '456'
- }, {
- id: 'hij',
- body: 'comment 30',
- asset_id: '456',
- status: 'accepted'
- }];
+beforeEach(() => {
+ return Setting.create(settings);
+});
- const users = [{
- displayName: 'Ana',
- email: 'ana@gmail.com',
- password: '123'
- }, {
- displayName: 'Maria',
- email: 'maria@gmail.com',
- password: '123'
- }];
+describe('Get moderation queues rejected, pending, flags', () => {
- const actions = [{
- action_type: 'flag',
- item_id: 'abc',
- item_type: 'comment'
- }, {
- action_type: 'like',
- item_id: 'hij',
- item_type: 'comment'
- }];
+ describe('/api/v1/queue', () => {
+ let comments;
- beforeEach(() => {
- return Promise.all([
- Comment.create(comments),
- User.createLocalUsers(users),
- Action.create(actions),
- Setting.create(settings)
- ]);
- });
+ const users = [{
+ id: '456',
+ displayName: 'Ana',
+ email: 'ana@gmail.com',
+ password: '123'
+ }, {
+ id: '123',
+ displayName: 'Maria',
+ email: 'maria@gmail.com',
+ password: '123'
+ }];
- describe('#get', () => {
- it('should return all the pending comments', function(done){
+ let actions;
+
+ beforeEach(() => {
+
+ comments = [{
+ id: 'abc',
+ body: 'comment 10',
+ asset_id: 'asset',
+ status: 'rejected'
+ }, {
+ id: 'def',
+ body: 'comment 20',
+ asset_id: 'asset'
+ }, {
+ id: 'hij',
+ body: 'comment 30',
+ asset_id: '456',
+ status: 'accepted'
+ }];
+
+ actions = [{
+ action_type: 'flag',
+ item_type: 'comment'
+ }, {
+ action_type: 'like',
+ item_type: 'comment'
+ }];
+
+ return User.createLocalUsers(users)
+ .then((u) => {
+ comments[0].author_id = u[0].id;
+ comments[1].author_id = u[1].id;
+ comments[2].author_id = u[1].id;
+
+ return Comment.create(comments);
+ })
+ .then((c) => {
+ actions[0].item_id = c[0].id;
+ actions[1].item_id = c[1].id;
+
+ return Action.create(actions);
+ });
+ });
+
+ it('should return all the pending comments, users and actions', function(done){
chai.request(app)
.get('/api/v1/queue/comments/pending')
.set(passport.inject({roles: ['admin']}))
.end(function(err, res){
expect(err).to.be.null;
expect(res).to.have.status(200);
- expect(res.body[0]).to.have.property('id', 'def');
+ expect(res.body.comments[0]).to.have.property('body');
+ expect(res.body.users[0]).to.have.property('displayName');
+ expect(res.body.actions[0]).to.have.property('action_type');
done();
});
});
diff --git a/tests/routes/api/stream/index.js b/tests/routes/api/stream/index.js
index ea08ceebb..6484fdc12 100644
--- a/tests/routes/api/stream/index.js
+++ b/tests/routes/api/stream/index.js
@@ -14,90 +14,90 @@ const Asset = require('../../../../models/asset');
const Setting = require('../../../../models/setting');
describe('/api/v1/stream', () => {
+ describe('#get', () => {
+ const settings = {
+ id: '1',
+ moderation: 'post'
+ };
- const settings = {
- id: '1',
- moderation: 'post'
- };
+ let comments;
- const comments = [{
- id: 'abc',
- body: 'comment 10',
- author_id: '',
- parent_id: '',
- status: 'accepted'
- }, {
- id: 'def',
- body: 'comment 20',
- author_id: '',
- parent_id: '',
- status: ''
- }, {
- id: 'uio',
- body: 'comment 30',
- asset_id: 'asset',
- author_id: '456',
- parent_id: '',
- status: 'accepted'
- }, {
- id: 'hij',
- body: 'comment 40',
- asset_id: '456',
- status: 'rejected'
- }];
+ const users = [{
+ displayName: 'Ana',
+ email: 'ana@gmail.com',
+ password: '123'
+ }, {
+ displayName: 'Maria',
+ email: 'maria@gmail.com',
+ password: '123'
+ }];
- const users = [{
- displayName: 'Ana',
- email: 'ana@gmail.com',
- password: '123'
- }, {
- displayName: 'Maria',
- email: 'maria@gmail.com',
- password: '123'
- }];
+ const actions = [{
+ action_type: 'flag',
+ item_id: 'abc'
+ }, {
+ action_type: 'like',
+ item_id: 'hij'
+ }];
- const actions = [{
- action_type: 'flag',
- item_id: 'abc'
- }, {
- action_type: 'like',
- item_id: 'hij'
- }];
+ beforeEach(() => {
- beforeEach(() => {
-
- return Promise.all([
- User.createLocalUsers(users),
- Asset.findOrCreateByUrl('http://test.com'),
- Asset
- .findOrCreateByUrl('http://coralproject.net/asset2')
- .then((asset) => {
- return Asset
- .overrideSettings(asset.id, {moderation: 'pre'})
- .then(() => asset);
- })
- ])
- .then(([users, asset1, asset2]) => {
-
- comments[0].author_id = users[0].id;
- comments[1].author_id = users[1].id;
- comments[2].author_id = users[0].id;
- comments[3].author_id = users[1].id;
-
- comments[0].asset_id = asset1.id;
- comments[1].asset_id = asset1.id;
- comments[2].asset_id = asset2.id;
- comments[3].asset_id = asset2.id;
+ comments = [{
+ id: 'abc',
+ body: 'comment 10',
+ author_id: '',
+ parent_id: '',
+ status: 'accepted'
+ }, {
+ id: 'def',
+ body: 'comment 20',
+ author_id: '',
+ parent_id: '',
+ status: ''
+ }, {
+ id: 'uio',
+ body: 'comment 30',
+ asset_id: 'asset',
+ author_id: '456',
+ parent_id: '',
+ status: 'accepted'
+ }, {
+ id: 'hij',
+ body: 'comment 40',
+ asset_id: '456',
+ status: 'rejected'
+ }];
return Promise.all([
- Comment.create(comments),
- Action.create(actions),
- Setting.create(settings)
- ]);
- });
- });
+ User.createLocalUsers(users),
+ Asset.findOrCreateByUrl('http://test.com'),
+ Asset
+ .findOrCreateByUrl('http://coralproject.net/asset2')
+ .then((asset) => {
+ return Asset
+ .overrideSettings(asset.id, {moderation: 'pre'})
+ .then(() => asset);
+ })
+ ])
+ .then(([users, asset1, asset2]) => {
- describe('#get', () => {
+ comments[0].author_id = users[0].id;
+ comments[1].author_id = users[1].id;
+ comments[2].author_id = users[0].id;
+ comments[3].author_id = users[1].id;
+
+ comments[0].asset_id = asset1.id;
+ comments[1].asset_id = asset1.id;
+ comments[2].asset_id = asset2.id;
+ comments[3].asset_id = asset2.id;
+
+ return Promise.all([
+ Comment.create(comments),
+ Action.create(actions),
+ Setting.init().then(() => Setting.updateSettings(settings))
+ ]);
+ });
+ });
it('should return a stream with comments, users and actions for an existing asset', () => {
return chai.request(app)
.get('/api/v1/stream')