Skip to content

Commit

Permalink
Add e2e for loading more if unread
Browse files Browse the repository at this point in the history
- if A sends B 20 messages, then when B opens app, B wants to load all
  unread messages
  • Loading branch information
rottabonus committed May 19, 2024
1 parent b506a83 commit 2d1fca6
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 30 deletions.
31 changes: 28 additions & 3 deletions e2e/chatTest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {
waitAndTypeText,
signIn,
forceLogout,
detoxElementCount,
countElements,
sleep,
scrollUpAndFindText,
} from './helpers';

describe('Chat', () => {
Expand Down Expand Up @@ -101,7 +103,7 @@ describe('Chat', () => {
await signIn(mentor);
await element(by.id('tabs.chats')).tap();

const unseenDotsAmountBefore = await detoxElementCount(
const unseenDotsAmountBefore = await countElements(
by.id('main.buddyList.button.unseenDot'),
);
jestExpect(unseenDotsAmountBefore).toBe(2);
Expand All @@ -112,7 +114,7 @@ describe('Chat', () => {

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

const unseenDotsAmountAfter = await detoxElementCount(
const unseenDotsAmountAfter = await countElements(
by.id('main.buddyList.button.unseenDot'),
);
jestExpect(unseenDotsAmountAfter).toBe(1);
Expand Down Expand Up @@ -141,4 +143,27 @@ describe('Chat', () => {
await element(by.id('chat.back.button')).tap();
await expect(element(by.id('main.tabs.unseenDot'))).toBeVisible();
});

it('loads more messages if all newest unread', 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', 20);

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

// wait for 2 message-polls, so all messages are fetched
await sleep(10);
await element(by.text(mentee.displayName)).tap();
await expect(element(by.text('Hello 19'))).toBeVisible();
await scrollUpAndFindText('Hello 0', 'main.buddy.messageList');
});
});
20 changes: 19 additions & 1 deletion e2e/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ export async function scrollUpTo(elementId: string, viewId: string) {
.scroll(100, 'up', 0.1, 0.2);
}

/**
* Scrolls view up until element with text is found
*/
export async function scrollUpAndFindText(text: string, viewId: string) {
await waitFor(element(by.text(text)))
.toBeVisible()
.whileElement(by.id(viewId))
// Needs to scroll from x=0.1, y=0.2
// because of the big sticky toolbar
.scroll(100, 'up', 0.1, 0.2);
}

/**
* Waits until input is visible and then types given text
*/
Expand Down Expand Up @@ -523,7 +535,7 @@ export async function APIUpdateMentor(mentorName: string, mentor: any) {
});
}

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

Expand All @@ -536,3 +548,9 @@ export async function detoxElementCount(matcher: NativeMatcher) {
return 0;
}
}

export async function sleep(seconds: number) {
return new Promise(resolve => {
setTimeout(resolve, seconds * 1000);
});
}
9 changes: 4 additions & 5 deletions src/Screens/Main/Chat/MessageList/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ const Message = ({ value: message }: MessageProps) => {
const bubbleStyle =
type === 'Received' ? styles.leftBubble : styles.rightBubble;

const isSeenTemp =
type === 'Received' && !message.isSeen
? { borderWidth: 2, borderColor: 'red' }
: { borderWidth: 2, borderColor: 'green' };
// TODO: Visual aid, remove this after review
const isSeenBorder = type === 'Received' &&
!message.isSeen && { borderWidth: 2, borderColor: colors.orangeLight };

const addZero = (n: number) => (n < 10 ? `0${n}` : `${n}`);
const date = new Date(sentTime);
Expand All @@ -32,7 +31,7 @@ const Message = ({ value: message }: MessageProps) => {
const timeText = `${hours}:${minutes}`;

return (
<RN.View style={[bubbleStyle, isSeenTemp, styles.bubble]}>
<RN.View style={[bubbleStyle, isSeenBorder, styles.bubble]}>
<RN.View>
<RN.Text style={styles.text}>{content}</RN.Text>
</RN.View>
Expand Down
6 changes: 4 additions & 2 deletions src/Screens/Main/Chat/MessageList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ export const MessageList = ({
const dispatch = useDispatch();

const getPreviousMessagesIfNotLoading = () => {
if (isLoading) {
console.log('messageList.length', messageList.length);
if (isLoading || messageList.length < messageApi.MAX_MESSAGES_AT_ONCE) {

Check failure on line 98 in src/Screens/Main/Chat/MessageList/index.tsx

View workflow job for this annotation

GitHub Actions / Lint

Expected blank line before this statement
return;
}

Expand All @@ -107,7 +108,7 @@ export const MessageList = ({
};

const handleViewableChanged = ({ changed }: ViewArgs) => {
// TODO: Helper here, decode the changed maybe
// TODO: Decode 'changed' maybe
const unSeenMessagesOnScreen = changed
.filter(item => item.isViewable)
.filter(
Expand All @@ -130,6 +131,7 @@ export const MessageList = ({

return (
<RN.FlatList
testID="main.buddy.messageList"
contentContainerStyle={styles.scrollContent}
data={messages}
renderItem={({ item }) => <MemoizedRenderItem item={item} />}
Expand Down
12 changes: 6 additions & 6 deletions src/api/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { isLeft } from 'fp-ts/lib/Either';

type ApiMessage = t.TypeOf<typeof messageType>;

export const MAX_MESSAGES_AT_ONCE = 10;

const messageType = t.interface({
content: t.string,
recipient_id: t.string,
Expand Down Expand Up @@ -94,23 +96,21 @@ const reduceToMsgRecord = (acc: MessageMapping, message: Message) => ({
});

const createFetchParams = (pollingParams: PollingParams) => {
const maxMessagesAtOnce = 10;

if (pollingParams.type === 'New' && pollingParams.previousMsgId.length > 0) {
return `from_message_id=${pollingParams.previousMsgId}&desc=false&max=${maxMessagesAtOnce}`;
return `from_message_id=${pollingParams.previousMsgId}&desc=false&max=${MAX_MESSAGES_AT_ONCE}`;
}

if (pollingParams.type === 'InitialMessages') {
const userIds = pollingParams.buddyIds.join(',');

return `contact_user_ids=${userIds}&max=${maxMessagesAtOnce}&desc=true`;
return `contact_user_ids=${userIds}&max=${MAX_MESSAGES_AT_ONCE}&desc=true`;
}

if (pollingParams.type === 'OlderThan') {
return `contact_user_ids=${pollingParams.buddyId}&from_message_id=${pollingParams.messageId}&max=${maxMessagesAtOnce}&desc=true`;
return `contact_user_ids=${pollingParams.buddyId}&from_message_id=${pollingParams.messageId}&max=${MAX_MESSAGES_AT_ONCE}&desc=true`;
}

return `max=${maxMessagesAtOnce}&desc=true`;
return `max=${MAX_MESSAGES_AT_ONCE}&desc=true`;
};

export type MessageResponse = {
Expand Down
4 changes: 0 additions & 4 deletions src/state/reducers/markSeen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ export const reducer: automaton.Reducer<State, actions.Action> = (
type: 'messages/markSeen',
payload: { messages },
})),
// {
// type: 'messages/markSeen',
// payload: { messages },
// },
);
}

Expand Down
9 changes: 0 additions & 9 deletions src/state/reducers/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,6 @@ export const reducer: automaton.Reducer<State, actions.Action> = (

const previousMsgId = messageApi.extractMostRecentId(nextMessages);

// TODO: add some e2e-test
// case 1: oldermessage-fetching (for example initial)
// - mentee sends 20 messages to mentor
// - mentor login
// - mentor waits 5 seconds (the poll interval)
// - mentor scrolls up to the converstaion ( all messages have been loaded )
// - mentor opens chat
// TODO: remove borders of message-bubbles

const newOlderThanParams = messageApi.getParamsForUnreadMessages(
newMessages,
state.currentParams,
Expand Down

0 comments on commit 2d1fca6

Please sign in to comment.