Skip to content

Commit

Permalink
Add e2e for marking unread messages
Browse files Browse the repository at this point in the history
  • Loading branch information
rottabonus committed May 11, 2024
1 parent b3d0264 commit e7115db
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 20 deletions.
96 changes: 89 additions & 7 deletions e2e/chatTest.spec.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import { by, element, device, expect } from 'detox';
import { describe, it, beforeEach, beforeAll } from '@jest/globals';
import { describe, it, beforeEach, expect as jestExpect } from '@jest/globals';
import accountFixtures from './fixtures/accounts.json';

import {
APISignUpMentee,
APISignUpMentor,
APIGetSendInfo,
APIDeleteAccounts,
APISendMessage,
waitAndTypeText,
signIn,
forceLogout,
detoxElementCount,
} from './helpers';

describe('Chat', () => {
beforeAll(async () => {
await device.launchApp();
jest.setTimeout(200000);
});
beforeEach(async () => {
await APIDeleteAccounts();
await device.reloadReactNative();
});
afterEach(async () => {
await forceLogout();
});

it('with new mentor', async () => {
const mentee = accountFixtures.mentees[0];
Expand All @@ -32,8 +34,8 @@ describe('Chat', () => {

await signIn(mentee);

await element(by.text('Show mentor')).tap();
await element(by.text('Chat')).tap();
await element(by.id('components.mentorCard.readMore')).tap();
await element(by.id('main.mentorCardExpanded.button')).tap();

await waitAndTypeText('main.chat.input.input', message_from_mentee, true);
await element(by.id('main.chat.input.button')).tap();
Expand All @@ -59,4 +61,84 @@ describe('Chat', () => {
await expect(element(by.text(message_from_mentee))).toBeVisible();
await expect(element(by.text(message_from_mentor))).toBeVisible();
});

const sendMultiple = async (
from: string,
to: string,
headers: { Authorization: string },
content: string,
amount: number,
) => {
for (let i = 0; i < amount; i++) {
await APISendMessage({
sender_id: from,
recipient_id: to,
content: `${content} ${i}`,
headers,
});
}
};

it('marks message unseen', async () => {
const mentee = accountFixtures.mentees[0];
await APISignUpMentee(mentee);
const mentee2 = accountFixtures.mentees[1];
await APISignUpMentee(mentee2);
const mentor = accountFixtures.mentors[0];
await APISignUpMentor(mentor);

const {
sender_id: menteeId,
recipient_id: mentorId,
senderHeaders: menteeHeaders,
} = await APIGetSendInfo(mentee, mentor);
await sendMultiple(menteeId, mentorId, menteeHeaders, 'Hello', 5);

const { sender_id: mentee2Id, senderHeaders: mentee2Headers } =
await APIGetSendInfo(mentee2, mentor);
await sendMultiple(mentee2Id, mentorId, mentee2Headers, 'Hello', 10);

await signIn(mentor);
await element(by.id('tabs.chats')).tap();

const unseenDotsAmountBefore = await detoxElementCount(
by.id('main.buddyList.button.unseenDot'),
);
jestExpect(unseenDotsAmountBefore).toBe(2);

await element(by.text(mentee.displayName)).tap();
await expect(element(by.text('Hello 0'))).toBeVisible();
await expect(element(by.text('Hello 4'))).toBeVisible();

await element(by.id('chat.back.button')).tap();

const unseenDotsAmountAfter = await detoxElementCount(
by.id('main.buddyList.button.unseenDot'),
);
jestExpect(unseenDotsAmountAfter).toBe(1);
});

it('marks message unseen only if fully visible', async () => {
const mentee = accountFixtures.mentees[0];
await APISignUpMentee(mentee);
const mentor = accountFixtures.mentors[0];
await APISignUpMentor(mentor);

const {
sender_id: menteeId,
recipient_id: mentorId,
senderHeaders: menteeHeaders,
} = await APIGetSendInfo(mentee, mentor);
await sendMultiple(menteeId, mentorId, menteeHeaders, 'Hello', 10);

await signIn(mentor);
await element(by.id('tabs.chats')).tap();
await element(by.text(mentee.displayName)).tap();

await expect(element(by.text('Hello 0'))).not.toBeVisible();
await expect(element(by.text('Hello 9'))).toBeVisible();

await element(by.id('chat.back.button')).tap();
await expect(element(by.id('main.tabs.unseenDot'))).toBeVisible();
});
});
9 changes: 8 additions & 1 deletion e2e/fixtures/accounts.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@
},
{
"loginName": "mentee1",
"displayName": "mentee1_nick",
"displayName": "mentee_mummo",
"password": "Menteementee!",
"email": "[email protected]",
"role": "mentee"
},
{
"loginName": "mentee2",
"displayName": "mentee_seppo",
"password": "Menteementee!",
"email": "[email protected]",
"role": "mentee"
}
],
"mentors": [
Expand Down
15 changes: 15 additions & 0 deletions e2e/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { by, element, waitFor, device } from 'detox';
import { NativeMatcher } from 'detox/detox';
import { generateToken } from 'node-2fa';

const API_URL = process.env.YLITSE_API_URL || 'http://127.0.0.1:8080';
Expand Down Expand Up @@ -521,3 +522,17 @@ export async function APIUpdateMentor(mentorName: string, mentor: any) {
body: JSON.stringify(updatedMentor),
});
}

export async function detoxElementCount(matcher: NativeMatcher) {
try {
const attributes = await element(matcher)?.getAttributes();

if ('elements' in attributes) {
return attributes.elements.length;
} else {
return 1;
}
} catch (e) {
return 0;
}
}
2 changes: 0 additions & 2 deletions src/Screens/Main/Chat/MessageList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ export const MessageList = ({
)
.map<messageApi.Message>(({ item }) => item.value);

console.log('changed', unSeenMessagesOnScreen);

dispatch(markSeen({ messages: unSeenMessagesOnScreen }));
};

Expand Down
1 change: 1 addition & 0 deletions src/Screens/Main/MentorCardExpanded.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const MentorCardExpanded = ({ navigation, route }: Props) => {
style={styles.button}
onPress={shouldNavigateBack ? goBack : navigateToChat}
messageId="main.mentorCardExpanded.button"
testID="main.mentorCardExpanded.button"
disabled={isChatDisabled || isMe}
/>
</SafeAreaView>
Expand Down
1 change: 1 addition & 0 deletions src/Screens/components/MentorCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const MentorCard: React.FC<Props> = ({ onPress, style, mentor }) => {
<Button
style={styles.button}
messageId="components.mentorCard.readMore"
testID="components.mentorCard.readMore"
onPress={() => onPress(mentor)}
/>
</RN.View>
Expand Down
4 changes: 0 additions & 4 deletions src/api/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ export const getParamsForUnreadMessages = (
messages: MessageMapping,
params: PollingParams,
): Array<PollingParams> => {
console.log('getParamsForUnreadMessages');
switch (params.type) {
case 'OlderThan': {
return getOlderThanParamsIfHasUnread(messages)(params.buddyId);
Expand All @@ -228,7 +227,6 @@ export const getParamsForUnreadMessages = (
export const getOlderThanParamsIfHasUnread =
(messages: MessageMapping) =>
(buddyId: string): Array<PollingParams> => {
console.log('getOlderThanParamsIfHasUnread for buddyId:', buddyId);
const buddyMessages = messages[buddyId] ?? {};

const sorted = Object.keys(buddyMessages).map(
Expand All @@ -237,8 +235,6 @@ export const getOlderThanParamsIfHasUnread =

const hasUnread = sorted.some(message => !message.isSeen);

console.log('hasUnread', hasUnread);

return hasUnread
? [{ type: 'OlderThan', buddyId, messageId: sorted[0].messageId }]
: [];
Expand Down
2 changes: 0 additions & 2 deletions src/state/reducers/markSeen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ export const reducer: automaton.Reducer<State, actions.Action> = (

const [first, ...messages] = action.payload.messages;

console.log('markSeen action for message', first.content);

const nextState =
first.messageId in state || first.isSeen || first.type === 'Sent'
? state
Expand Down
4 changes: 0 additions & 4 deletions src/state/reducers/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,12 @@ export const reducer: automaton.Reducer<State, actions.Action> = (
// - mentor opens chat
// case 2: marking unread message
// case 3: marking unread only for messages that are seen 100%
console.log('got messages', newMessages);

const newOlderThanParams = messageApi.getParamsForUnreadMessages(
newMessages,
state.currentParams,
);

console.log('polled with', state.currentParams);
console.log('new older than params', newOlderThanParams);

const [nextCurrent, nextQueue] = messageApi.getNextParams(
action.payload,
state.pollingQueue,
Expand Down

0 comments on commit e7115db

Please sign in to comment.