diff --git a/src/components/messenger/chat/index.test.tsx b/src/components/messenger/chat/index.test.tsx index 6bcc211a7..fd9f103b1 100644 --- a/src/components/messenger/chat/index.test.tsx +++ b/src/components/messenger/chat/index.test.tsx @@ -193,7 +193,9 @@ describe(DirectMessageChat, () => { describe('mapState', () => { describe('canLeaveRoom', () => { it('is false when only when one other member', () => { - const state = new StoreBuilder().withActiveConversation(stubConversation({ otherMembers: [stubUser()] })); + const state = new StoreBuilder().withActiveConversation( + stubConversation({ otherMembers: [stubUser()], isSocialChannel: false }) + ); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canLeaveRoom: false })); }); @@ -201,7 +203,25 @@ describe(DirectMessageChat, () => { it('is false when user is admin', () => { const state = new StoreBuilder() .withActiveConversation( - stubConversation({ otherMembers: [stubUser(), stubUser()], adminMatrixIds: ['current-user-matrix-id'] }) + stubConversation({ + otherMembers: [stubUser(), stubUser()], + adminMatrixIds: ['current-user-matrix-id'], + isSocialChannel: false, + }) + ) + .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); + + expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canLeaveRoom: false })); + }); + + it('is false when user is admin and conversation is social channel', () => { + const state = new StoreBuilder() + .withActiveConversation( + stubConversation({ + otherMembers: [stubUser(), stubUser()], + adminMatrixIds: ['current-user-matrix-id'], + isSocialChannel: true, + }) ) .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); @@ -217,18 +237,38 @@ describe(DirectMessageChat, () => { expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canLeaveRoom: true })); }); + + it('is true when the conversation is a social channel and has multiple members', () => { + const state = new StoreBuilder() + .withActiveConversation(stubConversation({ otherMembers: [stubUser(), stubUser()], isSocialChannel: true })) + .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); + + expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canLeaveRoom: true })); + }); + + it('is false when the conversation is a social channel and has only one member', () => { + const state = new StoreBuilder() + .withActiveConversation(stubConversation({ otherMembers: [stubUser()], isSocialChannel: true })) + .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); + + expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canLeaveRoom: false })); + }); }); describe('canEdit', () => { it('is false when one on one conversation', () => { - const state = new StoreBuilder().withActiveConversation(stubConversation({ isOneOnOne: true })); + const state = new StoreBuilder().withActiveConversation( + stubConversation({ isOneOnOne: true, isSocialChannel: false }) + ); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canEdit: false })); }); it('is false when current user is not room admin', () => { const state = new StoreBuilder() - .withActiveConversation(stubConversation({ isOneOnOne: false, adminMatrixIds: ['other-user-matrix-id'] })) + .withActiveConversation( + stubConversation({ isOneOnOne: false, adminMatrixIds: ['other-user-matrix-id'], isSocialChannel: false }) + ) .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canEdit: false })); @@ -236,7 +276,9 @@ describe(DirectMessageChat, () => { it('is true when current user is room admin', () => { const state = new StoreBuilder() - .withActiveConversation(stubConversation({ isOneOnOne: false, adminMatrixIds: ['current-user-matrix-id'] })) + .withActiveConversation( + stubConversation({ isOneOnOne: false, adminMatrixIds: ['current-user-matrix-id'], isSocialChannel: false }) + ) .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canEdit: true })); @@ -244,23 +286,53 @@ describe(DirectMessageChat, () => { it('is true when current user is room moderator', () => { const state = new StoreBuilder() - .withActiveConversation(stubConversation({ isOneOnOne: false, moderatorIds: ['current-user-id'] })) + .withActiveConversation( + stubConversation({ isOneOnOne: false, moderatorIds: ['current-user-id'], isSocialChannel: false }) + ) .withCurrentUser(stubAuthenticatedUser({ id: 'current-user-id' })); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canEdit: true })); }); + + it('is true when the conversation is a social channel and user is an admin', () => { + const state = new StoreBuilder() + .withActiveConversation( + stubConversation({ + isOneOnOne: true, + adminMatrixIds: ['current-user-matrix-id'], + isSocialChannel: true, + }) + ) + .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); + + expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canEdit: true })); + }); + + it('is false when the conversation is a social channel and current user is not room admin', () => { + const state = new StoreBuilder() + .withActiveConversation( + stubConversation({ isOneOnOne: false, adminMatrixIds: ['other-user-matrix-id'], isSocialChannel: true }) + ) + .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); + + expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canEdit: false })); + }); }); describe('canAddMembers', () => { it('is false when one on one conversation', () => { - const state = new StoreBuilder().withActiveConversation(stubConversation({ isOneOnOne: true })); + const state = new StoreBuilder().withActiveConversation( + stubConversation({ isOneOnOne: true, isSocialChannel: false }) + ); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canAddMembers: false })); }); it('is false when current user is not room admin', () => { const state = new StoreBuilder() - .withActiveConversation(stubConversation({ isOneOnOne: false, adminMatrixIds: ['other-user-matrix-id'] })) + .withActiveConversation( + stubConversation({ isOneOnOne: false, adminMatrixIds: ['other-user-matrix-id'], isSocialChannel: false }) + ) .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canAddMembers: false })); @@ -268,22 +340,63 @@ describe(DirectMessageChat, () => { it('is true when current user is room admin', () => { const state = new StoreBuilder() - .withActiveConversation(stubConversation({ isOneOnOne: false, adminMatrixIds: ['current-user-matrix-id'] })) + .withActiveConversation( + stubConversation({ isOneOnOne: false, adminMatrixIds: ['current-user-matrix-id'], isSocialChannel: false }) + ) .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canAddMembers: true })); }); + + it('is true when the conversation is a social channel and user is an admin', () => { + const state = new StoreBuilder() + .withActiveConversation( + stubConversation({ + isOneOnOne: true, + adminMatrixIds: ['current-user-matrix-id'], + isSocialChannel: true, + }) + ) + .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); + + expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canAddMembers: true })); + }); + + it('is false when the conversation is a social channel and current user is not room admin', () => { + const state = new StoreBuilder() + .withActiveConversation( + stubConversation({ isOneOnOne: false, adminMatrixIds: ['other-user-matrix-id'], isSocialChannel: true }) + ) + .withCurrentUser(stubAuthenticatedUser({ matrixId: 'current-user-matrix-id' })); + + expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canAddMembers: false })); + }); }); describe('canViewDetails', () => { it('is false when one on one conversation', () => { - const state = new StoreBuilder().withActiveConversation(stubConversation({ isOneOnOne: true })); + const state = new StoreBuilder().withActiveConversation( + stubConversation({ isOneOnOne: true, isSocialChannel: false }) + ); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canViewDetails: false })); }); it('is true when not a one on one conversation', () => { - const state = new StoreBuilder().withActiveConversation(stubConversation({ isOneOnOne: false })); + const state = new StoreBuilder().withActiveConversation( + stubConversation({ isOneOnOne: false, isSocialChannel: false }) + ); + + expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canViewDetails: true })); + }); + + it('is true when the conversation is a social channel', () => { + const state = new StoreBuilder().withActiveConversation( + stubConversation({ + isOneOnOne: false, + isSocialChannel: true, + }) + ); expect(DirectMessageChat.mapState(state.build())).toEqual(expect.objectContaining({ canViewDetails: true })); }); diff --git a/src/components/messenger/chat/index.tsx b/src/components/messenger/chat/index.tsx index f40f7a279..c69fb5cbb 100644 --- a/src/components/messenger/chat/index.tsx +++ b/src/components/messenger/chat/index.tsx @@ -75,12 +75,16 @@ export class Container extends React.Component { const directMessage = denormalize(activeConversationId, state); const currentUser = currentUserSelector(state); + const hasMultipleMembers = (directMessage?.otherMembers || []).length > 1; + const isSocialChannel = directMessage?.isSocialChannel; const isCurrentUserRoomAdmin = directMessage?.adminMatrixIds?.includes(currentUser?.matrixId) ?? false; const isCurrentUserRoomModerator = directMessage?.moderatorIds?.includes(currentUser?.id) ?? false; - const canLeaveRoom = !isCurrentUserRoomAdmin && (directMessage?.otherMembers || []).length > 1; - const canEdit = (isCurrentUserRoomAdmin || isCurrentUserRoomModerator) && !directMessage?.isOneOnOne; - const canAddMembers = isCurrentUserRoomAdmin && !directMessage?.isOneOnOne; - const canViewDetails = !directMessage?.isOneOnOne; + + const canLeaveRoom = !isCurrentUserRoomAdmin && hasMultipleMembers; + const canEdit = + (isCurrentUserRoomAdmin || isCurrentUserRoomModerator) && (!directMessage?.isOneOnOne || isSocialChannel); + const canAddMembers = isCurrentUserRoomAdmin && (!directMessage?.isOneOnOne || isSocialChannel); + const canViewDetails = !directMessage?.isOneOnOne || isSocialChannel; const channel = rawChannelSelector(activeConversationId)(state); return {