Merge branch 'master' into story-134624635

This commit is contained in:
gaba
2017-01-31 15:00:14 -08:00
113 changed files with 2255 additions and 1670 deletions
@@ -1,198 +0,0 @@
import 'react';
import 'redux';
import {expect} from 'chai';
import fetchMock from 'fetch-mock';
import * as actions from '../../../../client/coral-framework/actions/items';
import {Map} from 'immutable';
import configureStore from 'redux-mock-store';
const mockStore = configureStore();
describe('itemActions', () => {
let store;
beforeEach(() => {
store = mockStore(new Map({}));
fetchMock.restore();
});
describe('getStream', () => {
const assetUrl = 'http://www.test.com';
const response = {
assets: [{
id: '1234', url: assetUrl
}],
comments: [
{body: 'stuff', id: '123'},
{body: 'morestuff', id: '456'}
],
actions: [
{
action_type: 'like',
item_id: '123',
count: 1,
id: 'like_123',
current_user: false
},
{
action_type: 'flag',
item_id: '456',
count: 5,
id: 'flag_456',
current_user: true
}
]
};
it('should get an stream from an asset_url and send the appropriate dispatches', () => {
fetchMock.get('*', JSON.stringify(response));
return actions.getStream(assetUrl)(store.dispatch)
.then((res) => {
expect(fetchMock.calls().matched[0][0]).to.equal('/api/v1/stream?asset_url=http%3A%2F%2Fwww.test.com');
expect(res).to.deep.equal(response);
expect(store.getActions()[1]).to.deep.equal({
type: actions.ADD_ITEM,
item: response.comments[0],
item_type: 'comments',
id: '123'
});
expect(store.getActions()[2]).to.deep.equal({
type: actions.ADD_ITEM,
item: response.comments[1],
item_type: 'comments',
id: '456'
});
});
});
it('should handle an error', () => {
fetchMock.get('*', 404);
return actions.getStream(assetUrl)(store.dispatch)
.catch((err) => {
expect(err).to.be.truthy;
});
});
});
// Disabling tests for this function until is is used again.
xdescribe('getItemsArray', () => {
const response = {items: [{type: 'comment', id: '123'}, {type: 'comment', id: '456'}]};
const ids = [1, 2];
it('should get an item from an array of ids and send the appropriate dispatches', () => {
fetchMock.get('*', JSON.stringify(response));
return actions.getItemsArray(ids)(store.dispatch)
.then((res) => {
expect(res).to.deep.equal(response.items);
expect(store.getActions()[0]).to.deep.equal({
type: actions.ADD_ITEM,
item: {
type: 'comment',
id: '123'
},
id: '123'
});
expect(store.getActions()[1]).to.deep.equal({
type: actions.ADD_ITEM,
item: {
type: 'comment', id: '456'
},
id: '456'
});
});
});
it('should handle an error', () => {
fetchMock.get('*', 404);
return actions.getItemsArray(ids)(store.dispatch)
.catch((err) => {
expect(err).to.be.truthy;
});
});
});
// NEED TO FIGURE OUT HOW TO TEST WITH CSRF TOKEN IN.
xdescribe('postItem', () => {
const item = {
type: 'comments',
data: {body: 'stuff'}
};
it ('should post an item, return an id, then dispatch that item to the store', () => {
fetchMock.post('*', {id: '123'});
return actions.postItem(item.data, item.type, undefined)(store.dispatch, store.getState)
.then((id) => {
expect(fetchMock.calls().matched[0][1]).to.deep.equal(
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type':'application/json'
},
credentials: 'same-origin',
body: JSON.stringify(item.data)
}
);
expect(id).to.deep.equal({id: '123'});
expect(store.getActions()[0]).to.deep.equal({
type: actions.ADD_ITEM,
item: {
body: 'stuff',
id: '123'
},
item_type: 'comments',
id: '123'
});
});
});
it('should handle an error', () => {
fetchMock.post('*', 404);
return actions.postItem(item)(store.dispatch, store.getState)
.catch((err) => {
expect(err).to.be.truthy;
});
});
});
xdescribe('postAction', () => {
it ('should post an action', () => {
fetchMock.post('*', {id: '456'});
const action = {
action_type: 'flag',
detail: 'Comment smells funny'
};
return actions.postAction('abc', 'comments', action)(store.dispatch, store.getState)
.then(response => {
expect(fetchMock.calls().matched[0][0]).to.equal('/api/v1/comments/abc/actions');
expect(response).to.deep.equal({id:'456'});
});
});
it('should handle an error', () => {
fetchMock.post('*', 404);
return actions.postAction('abc', 'flag', '123')(store.dispatch, store.getState)
.catch((err) => {
expect(err).to.be.truthy;
});
});
});
describe('deleteAction', () => {
it ('should remove an action', () => {
fetchMock.delete('*', {});
return actions.deleteAction('abc', 'flag', '123', 'comments')(store.dispatch)
.then(response => {
expect(fetchMock.calls().matched[0][0]).to.equal('/api/v1/actions/abc');
expect(response).to.deep.equal({});
});
});
xit('should handle an error', () => {
fetchMock.post('*', 404);
return actions.postAction('abc', 'flag', '123')(store.dispatch, store.getState)
.catch((err) => {
expect(err).to.be.truthy;
});
});
});
});
@@ -1,95 +0,0 @@
import {Map, fromJS} from 'immutable';
import {expect} from 'chai';
import itemsReducer from '../../../../client/coral-framework/reducers/items';
describe ('itemsReducer', () => {
describe('ADD_ITEM', () => {
it('should add an item', () => {
const action = {
type: 'ADD_ITEM',
item: {
body: 'stuff',
id: '123'
},
item_type: 'comments',
id: '123'
};
const store = new Map({});
const result = itemsReducer(store, action);
expect(result.getIn(['comments', '123']).toJS()).to.deep.equal({
body: 'stuff',
id: '123'
});
});
});
describe ('UPDATE_ITEM', () => {
it ('should update an item', () => {
const action = {
type: 'UPDATE_ITEM',
property: 'stuff',
value: 'things',
item_type: 'comments',
id: '123'
};
const store = fromJS({
'comments': {
'123': {
id: '123',
stuff: 'morestuff'
}
}
});
const result = itemsReducer(store, action);
expect(result.getIn(['comments', '123']).toJS()).to.deep.equal({
id: '123',
stuff: 'things'
});
});
});
describe('APPEND_ITEM_ARRAY', () => {
let action;
let store;
beforeEach (() => {
action = {
type: 'APPEND_ITEM_ARRAY',
property: 'stuff',
value: 'things',
id: '123',
item_type: 'comments'
};
store = fromJS({
'comments': {
'123': {
id: '123',
stuff: ['morestuff']
}
}
});
});
it ('should append to an existing array', () => {
const result = itemsReducer(store, action);
expect(result.getIn(['comments', '123']).toJS()).to.deep.equal({
id: '123',
stuff: ['morestuff', 'things']
});
});
it ('should create a new array', () => {
store = fromJS({
'comments': {
'123': {
id: '123'
}
}
});
const result = itemsReducer(store, action);
expect(result.getIn(['comments', '123']).toJS()).to.deep.equal({
id: '123',
stuff: ['things']
});
});
});
});
@@ -6,14 +6,26 @@ import CommentHistory from '../../../client/coral-plugin-history/CommentHistory'
describe('coral-plugin-history/CommentHistory', () => {
let render;
const comments = [{body: 'a comment or something', 'status_history':[{'type':'premod', 'created_at':'2016-12-09T01:40:53.327Z', 'assigned_by':null}, {'created_at':'2016-12-09T22:52:44.888Z', 'type':'accepted', 'assigned_by':'92256159-1164-4f66-9970-c7f23de7e461'}], 'asset_id':'96fddf96-7c83-4008-80ad-50091997d006', 'created_at':'2016-12-09T01:40:53.360Z', 'author_id':'92256159-1164-4f66-9970-c7f23de7e461', 'status':'accepted', '__v':0, 'updated_at':'2016-12-09T22:52:44.893Z', 'id':'3962c2ea-4ec4-42e4-b9bd-c571ff30f56b'}, {'body':'another comment', 'status_history':[{'type':'premod', 'created_at':'2016-12-09T22:53:43.148Z', 'assigned_by':null}], 'asset_id':'96fddf96-7c83-4008-80ad-50091997d006', 'created_at':'2016-12-09T22:53:43.158Z', 'author_id':'92256159-1164-4f66-9970-c7f23de7e461', 'status':'premod', '__v':0, 'updated_at':'2016-12-09T22:53:43.158Z', 'id':'b51e27af-bcfd-4932-91be-e3f01a4802e6'}, {'body':'can I comment?', 'status_history':[{'type':'premod', 'created_at':'2016-12-13T23:23:47.123Z', 'assigned_by':null}, {'created_at':'2016-12-13T23:23:58.487Z', 'type':'accepted', 'assigned_by':'92256159-1164-4f66-9970-c7f23de7e461'}], 'asset_id':'cef81015-1b53-4d70-b9af-6eca680f22fc', 'created_at':'2016-12-13T23:23:47.131Z', 'author_id':'92256159-1164-4f66-9970-c7f23de7e461', 'status':'accepted', '__v':0, 'updated_at':'2016-12-13T23:23:58.493Z', 'id':'dc9d7be1-b911-4dc3-8e1e-400e8b8d110e'}, {'body':'pre-mod comment', 'status_history':[{'type':'premod', 'created_at':'2016-12-08T21:34:56.994Z', 'assigned_by':null}, {'created_at':'2016-12-08T21:38:04.961Z', 'type':'rejected', 'assigned_by':'92256159-1164-4f66-9970-c7f23de7e461'}], 'asset_id':'96fddf96-7c83-4008-80ad-50091997d006', 'created_at':'2016-12-08T21:34:56.997Z', 'author_id':'92256159-1164-4f66-9970-c7f23de7e461', 'status':'rejected', '__v':0, 'updated_at':'2016-12-08T21:38:04.965Z', 'id':'6f02af16-a8f8-4ead-80ea-0d48824eb74d'}, {'body':'a flagged commetn', 'status_history':[{'type':'premod', 'created_at':'2016-12-08T21:38:26.342Z', 'assigned_by':null}, {'created_at':'2016-12-09T23:47:27.009Z', 'type':'accepted', 'assigned_by':'92256159-1164-4f66-9970-c7f23de7e461'}], 'asset_id':'96fddf96-7c83-4008-80ad-50091997d006', 'created_at':'2016-12-08T21:38:26.344Z', 'author_id':'92256159-1164-4f66-9970-c7f23de7e461', 'status':'accepted', '__v':0, 'updated_at':'2016-12-09T23:47:27.018Z', 'id':'784c5f91-36b9-4bda-b4ca-a114cef2c9f0'}, {'body':'a post mod comment', 'status_history':[{'type':'premod', 'created_at':'2016-12-08T22:19:05.870Z', 'assigned_by':null}, {'created_at':'2016-12-09T23:26:41.427Z', 'type':'accepted', 'assigned_by':'92256159-1164-4f66-9970-c7f23de7e461'}], 'asset_id':'96fddf96-7c83-4008-80ad-50091997d006', 'created_at':'2016-12-08T22:19:05.874Z', 'author_id':'92256159-1164-4f66-9970-c7f23de7e461', 'status':'accepted', '__v':0, 'updated_at':'2016-12-09T23:26:41.450Z', 'id':'e8b86039-f850-4e53-bd9d-f8c9186a9637'}, {'body':'an actual post-mod comment here', 'status_history':[], 'asset_id':'96fddf96-7c83-4008-80ad-50091997d006', 'created_at':'2016-12-08T22:20:11.147Z', 'author_id':'92256159-1164-4f66-9970-c7f23de7e461', 'status':null, '__v':0, 'updated_at':'2016-12-08T22:20:11.147Z', 'id':'cff1a318-50c6-431e-9a63-de7a7b7136bf'}];
const assets = [{'settings': null, 'created_at':'2016-12-06T21:36:09.302Z', 'url':'localhost:3000/', 'scraped':null, 'status':'open', 'updated_at':'2016-12-08T02:11:15.943Z', '_id':'58472f499e775a38f23d5da0', 'type':'article', 'closedMessage':null, 'id':'7302e637-f884-47c0-9723-02cc10a18617', 'closedAt':null}, {'settings':null, 'created_at':'2016-12-07T02:25:31.983Z', 'url':'http://localhost:3000/', 'scraped':null, 'status':'open', 'updated_at':'2016-12-13T22:58:36.061Z', '_id':'5847731b9e775a38f23d5da1', 'type':'article', 'closedMessage':null, 'id':'96fddf96-7c83-4008-80ad-50091997d006', 'closedAt':null}, {'settings':null, 'created_at':'2016-12-12T19:04:05.770Z', 'url':'http://localhost:3000/embed/stream', 'scraped':null, 'updated_at':'2016-12-14T20:13:21.934Z', '_id':'584ef4a59e775a38f23d5e86', 'type':'article', 'closedMessage':null, 'id':'cef81015-1b53-4d70-b9af-6eca680f22fc', 'closedAt':null}];
const asset = {
'settings': null,
'created_at':'2016-12-06T21:36:09.302Z',
'url':'localhost:3000/',
'scraped':null,
'status':'open',
'updated_at':'2016-12-08T02:11:15.943Z',
'_id':'58472f499e775a38f23d5da0',
'type':'article',
'closedMessage':null,
'id':'7302e637-f884-47c0-9723-02cc10a18617',
'closedAt':null
};
beforeEach(() => {
render = shallow(<CommentHistory comments={comments} assets={assets} link={()=>{}}/>);
render = shallow(<CommentHistory comments={comments} asset={asset} link={()=>{}}/>);
});
it('should render Comments as children when given comments and assets', () => {
const wrapper = mount(<CommentHistory comments={comments} assets={assets} link={()=>{}}/>);
const wrapper = mount(<CommentHistory comments={comments} asset={asset} link={()=>{}}/>);
expect(wrapper.find('.commentHistory__list').children()).to.have.length(7);
});
+3 -3
View File
@@ -4,15 +4,15 @@ module.exports = {
users: {
admin: {
email: 'admin@test.com',
pass: 'test'
pass: 'testtest'
},
moderator: {
email: 'moderator@test.com',
pass: 'test'
pass: 'testtest'
},
commenter: {
email: 'commenter@test.com',
pass: 'test'
pass: 'testtest'
}
},
};
+7 -6
View File
@@ -1,8 +1,8 @@
const Comments = require('../../models/comment');
const Users = require('../../models/user');
const Actions = require('../../models/action');
const Assets = require('../../models/asset');
const Settings = require('../../models/setting');
const Comments = require('../../services/comments');
const Users = require('../../services/users');
const Actions = require('../../services/actions');
const Assets = require('../../services/assets');
const Settings = require('../../services/settings');
const globals = require('./globals');
/* Create an array of comments */
@@ -22,4 +22,5 @@ module.exports.users = (users) => Users.createLocalUsers(users);
module.exports.actions = (actions) => Actions.create(actions);
/* Update a setting */
module.exports.settings = (setting) => Settings.init().then(() => Settings.updateSettings(setting));
module.exports.settings = (setting) => Settings.init().then(() =>
Settings.update(setting));
+8 -7
View File
@@ -8,26 +8,27 @@ const embedStreamCommands = {
},
approveComment() {
return this
.waitForElementVisible('@commentList')
.waitForElementVisible('@moderationList')
.waitForElementVisible('@approveButton')
.click('@approveButton');
.click('@approveButton')
.waitForElementNotPresent('@approveButton');
}
};
module.exports = {
commands: [embedStreamCommands],
elements: {
commentList: {
selector: '#commentList'
moderationList: {
selector: '#moderationList'
},
banButton: {
selector: '#commentList .actions:first-child .ban'
selector: '#moderationList .actions:first-child .ban'
},
rejectButton: {
selector: '#commentList .actions:first-child .reject'
selector: '#moderationList .actions:first-child .reject'
},
approveButton: {
selector: '#commentList .actions:first-child .approve'
selector: '#moderationList .actions:first-child .approve'
}
}
};
+2 -2
View File
@@ -127,10 +127,10 @@ module.exports = {
selector: '.comment .coral-plugin-flags-popup'
},
flagCommentOption: {
selector: '.comment .coral-plugin-flags-popup .coral-plugin-flags-popup-radio-label[for="comments"]'
selector: '.comment .coral-plugin-flags-popup .coral-plugin-flags-popup-radio-label[for="COMMENTS"]'
},
flagUsernameOption: {
selector: '.comment .coral-plugin-flags-popup .coral-plugin-flags-popup-radio-label[for="user"]'
selector: '.comment .coral-plugin-flags-popup .coral-plugin-flags-popup-radio-label[for="USERS"]'
},
flagOtherOption: {
selector: '.comment .coral-plugin-flags-popup .coral-plugin-flags-popup-radio-label[for="other"]'
+12 -4
View File
@@ -1,10 +1,18 @@
const mocks = require('../mocks');
module.exports = {
'@tags': ['embedStream'],
before: client => {
const embedStreamPage = client.page.embedStreamPage();
embedStreamPage
.navigate()
.ready();
client.perform((client, done) => {
mocks.settings({moderation: 'PRE'})
.then(() => {
const embedStreamPage = client.page.embedStreamPage();
embedStreamPage
.navigate()
.ready();
done();
});
});
},
'Login as commenter': client => {
const embedStreamPage = client.page.embedStreamPage();
+18 -23
View File
@@ -1,12 +1,12 @@
const mongoose = require('../../helpers/mongoose');
const mocks = require('../mocks');
const mockComment = 'This is a test comment.';
const mockComment = 'I read the comments';
const mockReply = 'This is a test reply';
const mockUser = {
email: `${new Date().getTime()}@test.com`,
name: 'Test User',
pw: 'testtesttest'
name: 'testuser',
pw: 'testtest'
};
module.exports = {
@@ -29,7 +29,6 @@ module.exports = {
.frame('coralStreamIframe')
// Register and Log In
.waitForElementVisible('#commentBox', 1000)
.waitForElementVisible('#coralSignInButton', 2000)
.click('#coralSignInButton')
.waitForElementVisible('#coralRegister', 1000)
@@ -47,10 +46,10 @@ module.exports = {
// Post a comment
.setValue('.coral-plugin-commentbox-textarea', mockComment)
.click('.coral-plugin-commentbox-button')
.waitForElementVisible('.comment', 1000)
.waitForElementVisible('.coral-plugin-content-text', 1000)
// Verify that it appears
.assert.containsText('.comment', mockComment);
.assert.containsText('.coral-plugin-content-text', mockComment);
done();
})
.catch((err) => {
@@ -104,8 +103,8 @@ module.exports = {
.click('.coral-plugin-replies-reply-button')
.waitForElementVisible('#replyText')
.setValue('#replyText', mockReply)
.click('.coral-plugin-replies-textarea button')
.waitForElementVisible('.reply', 2000)
.click('.coral-plugin-replies-textarea .coral-plugin-commentbox-button')
.waitForElementVisible('.reply', 20000)
// Verify that it appears
.assert.containsText('.reply', mockReply);
@@ -122,22 +121,18 @@ module.exports = {
mocks.settings({moderation: 'PRE'})
// Add a mock user
.then(() => {
return mocks.users([{
displayName: 'Baby Blue',
email: 'whale@tale.sea',
password: 'krill'
}]);
})
.then(() => mocks.users([{
displayName: 'Baby Blue',
email: 'whale@tale.sea',
password: 'krill'
}]))
// Add a mock preapproved comment by that user
.then((user) => {
return mocks.comments([{
body: 'Whales are not fish.',
status: 'accepted',
author_id: user.id
}]);
})
.then((user) => mocks.comments([{
body: 'Whales are not fish.',
status: 'accepted',
author_id: user.id
}]))
.then(() => {
// Load Page
@@ -170,7 +165,7 @@ module.exports = {
// Verify that comment count is correct
client.waitForElementVisible('.coral-plugin-comment-count-text', 2000)
.assert.containsText('.coral-plugin-comment-count-text', '1 Comment');
.assert.containsText('.coral-plugin-comment-count-text', '4 Comments');
done();
});
},
+2 -4
View File
@@ -1,5 +1,3 @@
const uuid = require('uuid');
module.exports = {
'@tags': ['signup', 'visitor'],
before: client => {
@@ -14,8 +12,8 @@ module.exports = {
embedStreamPage
.signUp({
email: `visitor_${uuid.v4()}@test.com`,
displayName: 'Visitor',
email: `visitor_${Date.now()}@test.com`,
displayName: `visitor${Date.now()}`,
pass: 'testtest'
});
},
+2 -2
View File
@@ -66,7 +66,7 @@ describe('/api/v1/auth/local', () => {
describe('email confirmation enabled', () => {
beforeEach(() => SettingsService.init({requireEmailConfirmation: true}));
beforeEach(() => SettingsService.update({requireEmailConfirmation: true}));
describe('#post', () => {
it('should not allow a login from a user that is not confirmed', () => {
@@ -74,7 +74,7 @@ describe('/api/v1/auth/local', () => {
.post('/api/v1/auth/local')
.send({email: 'maria@gmail.com', password: 'password!'})
.catch((err) => {
err.response.should.have.status(401);
expect(err).to.have.status(401);
return UsersService.createEmailConfirmToken(mockUser.id, mockUser.profiles[0].id);
})
+24 -2
View File
@@ -62,6 +62,10 @@ describe('/api/v1/queue', () => {
action_type: 'LIKE',
item_id: 'hij',
item_type: 'COMMENTS'
}, {
action_type: 'FLAG',
item_id: '123',
item_type: 'USERS'
}];
beforeEach(() => {
@@ -72,11 +76,16 @@ describe('/api/v1/queue', () => {
comments[1].author_id = u[1].id;
comments[2].author_id = u[1].id;
return Comment.create(comments);
return Promise.all([
Comment.create(comments),
u,
...u.map((user) => UsersService.setStatus(user.id, 'PENDING'))
]);
})
.then((c) => {
.then(([c, u]) => {
actions[0].item_id = c[0].id;
actions[1].item_id = c[1].id;
actions[2].item_id = u[0].id;
return Promise.all([
Action.create(actions),
@@ -98,4 +107,17 @@ describe('/api/v1/queue', () => {
expect(res.body.actions[0]).to.have.property('action_type');
});
});
it('should return all pending users and actions', function(done){
chai.request(app)
.get('/api/v1/queue/users/pending')
.set(passport.inject({roles: ['ADMIN']}))
.end(function(err, res){
expect(err).to.be.null;
expect(res).to.have.status(200);
expect(res.body.users[0]).to.have.property('displayName');
expect(res.body.actions[0]).to.have.property('action_type');
done();
});
});
});
+2 -4
View File
@@ -73,13 +73,11 @@ describe('/api/v1/users/:user_id/actions', () => {
return chai.request(app)
.post('/api/v1/users/abc/actions')
.set(passport.inject({id: '456', roles: ['ADMIN']}))
.send({'action_type': 'flag', metadata: {reason: 'Bio is too awesome.'}})
.send({'action_type': 'FLAG', metadata: {reason: 'Bio is too awesome.'}})
.then((res) => {
expect(res).to.have.status(201);
expect(res).to.have.body;
expect(res.body).to.have.property('action_type', 'flag');
expect(res.body).to.have.property('metadata')
.and.to.deep.equal({'reason': 'Bio is too awesome.'});
expect(res.body).to.have.property('action_type', 'FLAG');
expect(res.body).to.have.property('item_id', 'abc');
});
});