Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
aad915d
fix: read receipts not turning blue when all active users have read
abhinavkrin Feb 24, 2026
f24d4ea
added changeset
abhinavkrin Feb 24, 2026
f6f0360
unarchive subscription of only active users
abhinavkrin Mar 2, 2026
6b40a46
minor change
abhinavkrin Mar 2, 2026
2c503f1
Merge branch 'develop' into fix/read-receipts-ignore-deactivated-users
abhinavkrin Mar 6, 2026
6d56a2b
Merge branch 'develop' into fix/read-receipts-ignore-deactivated-users
abhinavkrin Mar 7, 2026
f530108
Merge branch 'develop' into fix/read-receipts-ignore-deactivated-users
abhinavkrin Mar 9, 2026
d081e06
test fix
abhinavkrin Mar 9, 2026
3cf6407
Merge branch 'develop' into fix/read-receipts-ignore-deactivated-users
abhinavkrin Mar 10, 2026
5d4e979
requested changes
abhinavkrin Mar 10, 2026
d1ce974
requested changes
abhinavkrin Mar 11, 2026
39dfaff
minor improvement
abhinavkrin Mar 11, 2026
a8ae48d
requested changes
abhinavkrin Mar 11, 2026
2a3559f
requested changes
abhinavkrin Mar 13, 2026
0c6af04
requested changes
abhinavkrin Mar 13, 2026
7deda6b
refactor: apply PR review feedback
abhinavkrin Mar 18, 2026
f0aeb1f
style: run prettier to fix line length in tests
abhinavkrin Mar 18, 2026
8422dd9
Apply suggestion from @abhinavkrin
abhinavkrin Mar 19, 2026
05c8922
improved tests
abhinavkrin Apr 2, 2026
b8b2fc7
switched from aggregation to normal queries
abhinavkrin Apr 15, 2026
3f7a15c
update tests
abhinavkrin Apr 15, 2026
10ff7eb
minor changes
abhinavkrin Apr 15, 2026
d39e70a
fix: preserve dm archive behavior for other users on deactivation
abhinavkrin Apr 16, 2026
d8cd6f0
remove serActiveStatus.spec.ts
abhinavkrin Apr 16, 2026
5f83bc4
move files around
sampaiodiego Apr 16, 2026
cefe518
Merge branch 'develop' into fix/read-receipts-ignore-deactivated-users
abhinavkrin Apr 17, 2026
8dce836
lint
abhinavkrin Apr 17, 2026
bb860a7
Merge branch 'develop' into fix/read-receipts-ignore-deactivated-users
abhinavkrin Apr 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test fix
Signed-off-by: Abhinav Kumar <abhinav@avitechlab.com>
  • Loading branch information
abhinavkrin committed Mar 9, 2026
commit d081e06057f776f1a0a81556547d87c5db37ca85
29 changes: 18 additions & 11 deletions apps/meteor/tests/e2e/read-receipts-deactivated-users.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import type { Page } from '@playwright/test';

import { IS_EE } from './config/constants';
import { createAuxContext } from './fixtures/createAuxContext';
import type { IUserState } from './fixtures/userStates';
import { Users } from './fixtures/userStates';
import { HomeChannel } from './page-objects';
import { createTargetChannel, deleteChannel, setSettingValueById } from './utils';
import { expect, test } from './utils/test';
import type { ITestUser } from './utils/user-helpers';
import { createTestUser, loginTestUser } from './utils/user-helpers';

test.use({ storageState: Users.admin.state });

Expand All @@ -14,11 +17,20 @@ test.describe.serial('read-receipts-deactivated-users', () => {
let targetChannel: string;
let user1Context: { page: Page; poHomeChannel: HomeChannel } | undefined;
let user2Context: { page: Page; poHomeChannel: HomeChannel } | undefined;
let testUser1: ITestUser;
let testUser2: ITestUser;
let testUser1State: IUserState;
let testUser2State: IUserState;

test.skip(!IS_EE, 'Enterprise Only');

test.beforeAll(async ({ api }) => {
targetChannel = await createTargetChannel(api, { members: ['user1', 'user2'] });
testUser1 = await createTestUser(api);
testUser2 = await createTestUser(api);
Comment thread
abhinavkrin marked this conversation as resolved.
Outdated

[testUser1State, testUser2State] = await Promise.all([loginTestUser(api, testUser1), loginTestUser(api, testUser2)]);

targetChannel = await createTargetChannel(api, { members: [testUser1.data.username, testUser2.data.username] });
await setSettingValueById(api, 'Message_Read_Receipt_Enabled', true);
await setSettingValueById(api, 'Message_Read_Receipt_Store_Users', true);
});
Expand All @@ -27,10 +39,8 @@ test.describe.serial('read-receipts-deactivated-users', () => {
await setSettingValueById(api, 'Message_Read_Receipt_Enabled', false);
await setSettingValueById(api, 'Message_Read_Receipt_Store_Users', false);

await api.post('/users.setActiveStatus', { userId: Users.user1.data._id, activeStatus: true });
await api.post('/users.setActiveStatus', { userId: Users.user2.data._id, activeStatus: true });

await deleteChannel(api, targetChannel);
await Promise.all([testUser1?.delete(), testUser2?.delete()]);
});

test.beforeEach(async ({ page }) => {
Expand All @@ -50,11 +60,11 @@ test.describe.serial('read-receipts-deactivated-users', () => {
});

test('should correctly handle read receipts as users are deactivated', async ({ browser, api, page }) => {
const { page: page1 } = await createAuxContext(browser, Users.user1);
const { page: page1 } = await createAuxContext(browser, testUser1State);
const user1Ctx = { page: page1, poHomeChannel: new HomeChannel(page1) };
user1Context = user1Ctx;

const { page: page2 } = await createAuxContext(browser, Users.user2);
const { page: page2 } = await createAuxContext(browser, testUser2State);
const user2Ctx = { page: page2, poHomeChannel: new HomeChannel(page2) };
user2Context = user2Ctx;

Expand All @@ -77,7 +87,7 @@ test.describe.serial('read-receipts-deactivated-users', () => {
});

await test.step('when some users are deactivated', async () => {
await api.post('/users.setActiveStatus', { userId: Users.user1.data._id, activeStatus: false });
await api.post('/users.setActiveStatus', { userId: testUser1.data._id, activeStatus: false });

await poHomeChannel.content.sendMessage('Message 2: User1 deactivated, two active users');

Expand All @@ -92,7 +102,7 @@ test.describe.serial('read-receipts-deactivated-users', () => {
});

await test.step('when only one user remains active (user alone in room)', async () => {
await api.post('/users.setActiveStatus', { userId: Users.user2.data._id, activeStatus: false });
await api.post('/users.setActiveStatus', { userId: testUser2.data._id, activeStatus: false });

await poHomeChannel.content.sendMessage('Message 3: Only admin active');

Expand All @@ -103,8 +113,5 @@ test.describe.serial('read-receipts-deactivated-users', () => {
await expect(page.getByRole('dialog').getByRole('listitem')).toHaveCount(1);
await page.getByRole('button', { name: 'Close' }).click();
});

await api.post('/users.setActiveStatus', { userId: Users.user1.data._id, activeStatus: true });
await api.post('/users.setActiveStatus', { userId: Users.user2.data._id, activeStatus: true });
});
});
2 changes: 1 addition & 1 deletion apps/meteor/tests/e2e/read-receipts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ test.describe.serial('read-receipts', () => {
await poHomeChannel.navbar.openChat(targetChannel);
await poHomeChannel.content.sendMessage('hello world');
await poHomeChannel.content.openLastMessageMenu();
expect(page.locator('role=menuitem[name="Read receipts"]')).not.toBeVisible;
await expect(page.locator('role=menuitem[name="Read receipts"]')).not.toBeVisible();
});
});

Expand Down
60 changes: 59 additions & 1 deletion apps/meteor/tests/e2e/utils/user-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import type { APIResponse } from '@playwright/test';
import type { IUser } from '@rocket.chat/core-typings';

import type { BaseTest } from './test';
import { DEFAULT_USER_CREDENTIALS } from '../config/constants';
import { BASE_URL, DEFAULT_USER_CREDENTIALS } from '../config/constants';
import type { IUserState } from '../fixtures/userStates';

export interface ICreateUserOptions {
username?: string;
Expand Down Expand Up @@ -62,6 +63,63 @@ export async function createTestUser(api: BaseTest['api'], options: ICreateUserO
};
}

/**
* Logs in a test user via the REST API and returns an IUserState
* suitable for use with createAuxContext.
*
* Use this instead of the pre-baked Users.userN fixtures whenever the test
* will deactivate (or otherwise invalidate the session of) the user, so that
* shared fixture tokens are never corrupted.
*/
export async function loginTestUser(api: BaseTest['api'], user: ITestUser): Promise<IUserState> {
const response = await api.post('/login', {
username: user.data.username,
password: DEFAULT_USER_CREDENTIALS.password,
Comment thread
abhinavkrin marked this conversation as resolved.
});
const {
data: { userId, authToken },
} = await response.json();

const expires = new Date();
expires.setFullYear(expires.getFullYear() + 1);

return {
data: {
_id: userId,
username: user.data.username,
loginToken: authToken,
loginExpire: expires,
hashedToken: '',
},
state: {
cookies: [
{ sameSite: 'Lax', name: 'rc_uid', value: userId, domain: 'localhost', path: '/', expires: -1, httpOnly: false, secure: false },
{
sameSite: 'Lax',
name: 'rc_token',
value: authToken,
domain: 'localhost',
path: '/',
expires: -1,
httpOnly: false,
secure: false,
},
],
origins: [
{
origin: BASE_URL,
localStorage: [
{ name: 'userLanguage', value: 'en-US' },
{ name: 'Meteor.loginToken', value: authToken },
{ name: 'Meteor.loginTokenExpires', value: expires.toISOString() },
{ name: 'Meteor.userId', value: userId },
],
},
],
},
};
}

/**
* Creates multiple test users at once
*/
Expand Down
Loading