Skip to content
This repository was archived by the owner on Oct 11, 2022. It is now read-only.

Commit eee9f5c

Browse files
authored
Merge pull request #4488 from withspectrum/2.5.4
v2.5.4
2 parents e15a965 + f21d47c commit eee9f5c

File tree

26 files changed

+548
-312
lines changed

26 files changed

+548
-312
lines changed

api/loaders/create-loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const createLoader = (
2525
// https://github.com/facebook/dataloader/blob/master/examples/RethinkDB.md
2626
function indexResults(results, indexField, cacheKeyFn) {
2727
var indexedResults = new Map();
28-
results.forEach(res => {
28+
results.filter(Boolean).forEach(res => {
2929
const key =
3030
typeof indexField === 'function' ? indexField(res) : res[indexField];
3131
indexedResults.set(cacheKeyFn(key), res);

api/migrations/seed/default/directMessageThreads.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,10 @@ module.exports = [
99
name: null,
1010
threadLastActive: new Date(DATE),
1111
},
12+
{
13+
id: 'dm-2',
14+
createdAt: new Date(DATE - 1),
15+
name: null,
16+
threadLastActive: new Date(DATE - 1),
17+
},
1218
];

api/migrations/seed/default/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const defaultUsersChannels = require('./usersChannels');
1212
const defaultUsersSettings = require('./usersSettings')();
1313
const defaultMessages = require('./messages');
1414
const defaultReactions = require('./reactions');
15+
const defaultUsersNotifications = require('./usersNotifications');
16+
const defaultNotifications = require('./notifications');
1517

1618
module.exports = {
1719
constants,
@@ -26,7 +28,8 @@ module.exports = {
2628
defaultUsersChannels,
2729
defaultMessages,
2830
defaultUsersSettings,
29-
defaultNotifications: [],
31+
defaultNotifications,
32+
defaultUsersNotifications,
3033
defaultCommunitySettings: [],
3134
defaultChannelSettings: [],
3235
defaultReactions,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// @flow
2+
const constants = require('./constants');
3+
const users = require('./users');
4+
5+
const { DATE, BRIAN_ID, PREVIOUS_MEMBER_USER_ID } = constants;
6+
7+
module.exports = [
8+
{
9+
actors: [
10+
{
11+
id: PREVIOUS_MEMBER_USER_ID,
12+
payload: JSON.stringify(
13+
users.find(u => u.id === PREVIOUS_MEMBER_USER_ID)
14+
),
15+
type: 'USER',
16+
},
17+
],
18+
context: {
19+
id: 'dm-2',
20+
payload: '',
21+
type: 'DIRECT_MESSAGE_THREAD',
22+
},
23+
createdAt: new Date(DATE + 1),
24+
entities: [
25+
{
26+
id: '1',
27+
payload: '',
28+
type: 'MESSAGE',
29+
},
30+
],
31+
event: 'MESSAGE_CREATED',
32+
id: '1',
33+
modifiedAt: new Date(DATE + 1),
34+
},
35+
];

api/migrations/seed/default/usersDirectMessageThreads.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @flow
22
const constants = require('./constants');
3-
const { DATE, BRIAN_ID, MAX_ID, BRYN_ID } = constants;
3+
const { DATE, BRIAN_ID, MAX_ID, BRYN_ID, PREVIOUS_MEMBER_USER_ID } = constants;
44

55
module.exports = [
66
{
@@ -30,4 +30,22 @@ module.exports = [
3030
lastSeen: new Date(DATE),
3131
receiveNotifications: true,
3232
},
33+
{
34+
id: '4',
35+
createdAt: new Date(DATE),
36+
userId: BRIAN_ID,
37+
threadId: 'dm-2',
38+
lastActive: new Date(DATE - 1),
39+
lastSeen: null,
40+
receiveNotifications: true,
41+
},
42+
{
43+
id: '5',
44+
createdAt: new Date(DATE),
45+
userId: PREVIOUS_MEMBER_USER_ID,
46+
threadId: 'dm-2',
47+
lastActive: new Date(DATE - 1),
48+
lastSeen: new Date(DATE - 1),
49+
receiveNotifications: true,
50+
},
3351
];
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @flow
2+
const constants = require('./constants');
3+
const { DATE, BRIAN_ID } = constants;
4+
5+
module.exports = [
6+
{
7+
id: '1',
8+
notificationId: '1',
9+
createdAt: new Date(DATE),
10+
userId: BRIAN_ID,
11+
entityAddedAt: new Date(DATE + 1),
12+
isRead: false,
13+
isSeen: false,
14+
},
15+
];

api/routes/middlewares/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { Router } from 'express';
22

33
const middlewares = Router();
44

5+
import bodyParser from 'body-parser';
6+
middlewares.use(bodyParser.json());
7+
58
if (process.env.NODE_ENV === 'development') {
69
const logging = require('shared/middlewares/logging');
710
middlewares.use(logging);
@@ -21,9 +24,6 @@ middlewares.options('*', cors);
2124
import cookieParser from 'cookie-parser';
2225
middlewares.use(cookieParser());
2326

24-
import bodyParser from 'body-parser';
25-
middlewares.use(bodyParser.json());
26-
2727
import session from 'shared/middlewares/session';
2828
middlewares.use(session);
2929

api/utils/permissions.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,24 @@ export const canViewThread = async (
178178
loaders.userPermissionsInCommunity.load([userId, thread.communityId]),
179179
]);
180180

181+
if (!channel || !community) return false;
182+
if (channel.deletedAt || community.deletedAt) return false;
183+
181184
if (!channel.isPrivate && !community.isPrivate) return true;
185+
182186
if (channel.isPrivate)
183-
return channelPermissions.isMember && !channelPermissions.isBlocked;
187+
return (
188+
channelPermissions &&
189+
channelPermissions.isMember &&
190+
!channelPermissions.isBlocked
191+
);
184192
if (community.isPrivate)
185-
return communityPermissions.isMember && !communityPermissions.isBlocked;
193+
return (
194+
communityPermissions &&
195+
communityPermissions.isMember &&
196+
!communityPermissions.isBlocked
197+
);
198+
186199
return false;
187200
};
188201

cypress/integration/messages_spec.js

Lines changed: 141 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import data from '../../shared/testing/data';
22

3-
const thread = data.threads[0];
4-
const community = data.communities.find(
5-
community => community.id === thread.communityId
3+
const user = data.users.find(user => user.username === 'brian');
4+
const directMessages = data.usersDirectMessageThreads.filter(
5+
udm => udm.userId === user.id
66
);
7-
const author = data.users.find(user => user.id === thread.creatorId);
87

98
describe('/messages/new', () => {
109
beforeEach(() => {
11-
cy.auth(author.id).then(() => cy.visit('/messages/new'));
10+
cy.auth(user.id).then(() => cy.visit('/messages/new'));
1211
});
1312

1413
it('should allow to continue composing message incase of crash or reload', () => {
@@ -22,3 +21,140 @@ describe('/messages/new', () => {
2221
cy.get('[contenteditable="true"]').contains(newMessage);
2322
});
2423
});
24+
25+
describe('/messages', () => {
26+
beforeEach(() => {
27+
cy.auth(user.id).then(() => cy.visit('/messages'));
28+
});
29+
30+
it('should load list of direct messages', () => {
31+
cy.contains('Max Stoiber and Bryn Jackson').should('be.visible');
32+
cy.contains('A fifth one').should('be.visible');
33+
34+
cy.contains('Previous member').should('be.visible');
35+
cy.contains('No messages yet...').should('be.visible');
36+
37+
cy.get('[data-cy="unread-dm-list-item"]').should($p => {
38+
expect($p).to.have.length(1);
39+
});
40+
cy.get('[data-cy="dm-list-item"]').should($p => {
41+
expect($p).to.have.length(1);
42+
});
43+
});
44+
45+
it('should open conversation composer', () => {
46+
cy.get('[data-cy="compose-dm"]')
47+
.should('be.visible')
48+
.click();
49+
cy.url().should('eq', 'http://localhost:3000/messages/new');
50+
});
51+
52+
it('should select an individual conversation', () => {
53+
cy.contains('Max Stoiber and Bryn Jackson')
54+
.should('be.visible')
55+
.click();
56+
cy.get('[data-cy="dm-header"]').should('be.visible');
57+
cy.get('[data-cy="dm-header"]').contains('Max Stoiber, Bryn Jackson');
58+
cy.get('[data-cy="message"]').should($p => {
59+
expect($p).to.have.length(5);
60+
});
61+
});
62+
63+
it('should switch conversations', () => {
64+
cy.contains('Max Stoiber and Bryn Jackson')
65+
.should('be.visible')
66+
.click();
67+
cy.get('[data-cy="dm-header"]').should('be.visible');
68+
cy.get('[data-cy="dm-header"]').contains('Max Stoiber, Bryn Jackson');
69+
cy.get('[data-cy="message"]').should($p => {
70+
expect($p).to.have.length(5);
71+
});
72+
73+
cy.contains('Previous member')
74+
.should('be.visible')
75+
.click();
76+
cy.get('[data-cy="dm-header"]').should('be.visible');
77+
cy.get('[data-cy="dm-header"]').contains('Previous member');
78+
cy.get('[data-cy="message"]').should($p => {
79+
expect($p).to.have.length(0);
80+
});
81+
});
82+
83+
it('should send a message in a conversation', () => {
84+
cy.contains('Previous member')
85+
.should('be.visible')
86+
.click();
87+
88+
const newMessage = 'A new message!';
89+
cy.get('[contenteditable="true"]').type(newMessage);
90+
cy.get('[data-cy="chat-input-send-button"]').click();
91+
cy.get('[contenteditable="true"]').type('');
92+
cy.contains(newMessage);
93+
94+
cy.get('[data-cy="unread-dm-list-item"]').should($p => {
95+
expect($p).to.have.length(0);
96+
});
97+
98+
cy.get('[data-cy="dm-list-item"]').should($p => {
99+
expect($p).to.have.length(2);
100+
});
101+
102+
cy.wait(2000);
103+
104+
cy.get('[data-cy="dm-list-item"]')
105+
.first()
106+
.contains('Previous member');
107+
});
108+
});
109+
110+
describe('messages tab badge count', () => {
111+
beforeEach(() => {
112+
cy.auth(user.id).then(() => cy.visit('/'));
113+
});
114+
115+
it('should show a badge for unread direct messages', () => {
116+
cy.get('[data-cy="unread-badge-1"]').should('be.visible');
117+
});
118+
119+
it('should clear the badge when messages tab clicked', () => {
120+
cy.get('[data-cy="unread-badge-1"]').should('be.visible');
121+
cy.get('[data-cy="navbar-messages"]').click();
122+
cy.get('[data-cy="dm-list-item"]').should($p => {
123+
expect($p).to.have.length(1);
124+
});
125+
cy.get('[data-cy="unread-dm-list-item"]').should($p => {
126+
expect($p).to.have.length(1);
127+
});
128+
cy.get('[data-cy="unread-badge-0"]').should('be.visible');
129+
});
130+
131+
it('should not show an unread badge after leaving messages tab', () => {
132+
cy.get('[data-cy="unread-badge-1"]').should('be.visible');
133+
cy.get('[data-cy="navbar-messages"]').click();
134+
cy.get('[data-cy="dm-list-item"]').should($p => {
135+
expect($p).to.have.length(1);
136+
});
137+
cy.get('[data-cy="unread-dm-list-item"]').should($p => {
138+
expect($p).to.have.length(1);
139+
});
140+
cy.get('[data-cy="unread-badge-0"]').should('be.visible');
141+
cy.get('[data-cy="navbar-home"]').click();
142+
cy.get('[data-cy="unread-badge-0"]').should('be.visible');
143+
});
144+
});
145+
146+
describe('clearing messages tab', () => {
147+
beforeEach(() => {
148+
cy.auth(user.id).then(() => cy.visit('/messages'));
149+
});
150+
151+
it('should clear the badge when landing directly on /messages', () => {
152+
cy.get('[data-cy="dm-list-item"]').should($p => {
153+
expect($p).to.have.length(1);
154+
});
155+
cy.get('[data-cy="unread-dm-list-item"]').should($p => {
156+
expect($p).to.have.length(1);
157+
});
158+
cy.get('[data-cy="unread-badge-0"]').should('be.visible');
159+
});
160+
});

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Spectrum",
3-
"version": "2.5.3",
3+
"version": "2.5.4",
44
"license": "BSD-3-Clause",
55
"devDependencies": {
66
"@babel/preset-flow": "^7.0.0",
@@ -145,12 +145,12 @@
145145
"query-string": "5.1.1",
146146
"raf": "^3.4.0",
147147
"raven": "^2.6.4",
148-
"react": "16.4.2",
148+
"react": "^16.6.3",
149149
"react-apollo": "^2.3.2",
150150
"react-app-rewire-styled-components": "^3.0.0",
151151
"react-app-rewired": "^1.6.2",
152152
"react-clipboard.js": "^2.0.1",
153-
"react-dom": "16.4.2",
153+
"react-dom": "^16.6.3",
154154
"react-flip-move": "^3.0.2",
155155
"react-helmet-async": "^0.1.0",
156156
"react-image": "^1.5.1",

0 commit comments

Comments
 (0)