Skip to content

Commit ae6b57a

Browse files
test: add saml login tests for user without name and user with channels (#36383)
1 parent 00b6fd1 commit ae6b57a

File tree

3 files changed

+132
-6
lines changed

3 files changed

+132
-6
lines changed

apps/meteor/tests/e2e/containers/saml/config/simplesamlphp/authsources.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,27 @@
3737
'email' => 'samluser4@example.com',
3838
'role' => 'saml-role',
3939
),
40+
'samluser5:password' => array(
41+
'uid' => array('5'),
42+
'username' => 'samluser5',
43+
'eduPersonAffiliation' => array('group5'),
44+
'email' => 'samluser5@example.com',
45+
),
46+
'samluser6:password' => array(
47+
'uid' => array('6'),
48+
'username' => 'samluser6',
49+
'displayName' => 'Saml User 6 Display Name',
50+
'eduPersonAffiliation' => array('group6'),
51+
'email' => 'samluser6@example.com',
52+
),
53+
'samluser7:password' => array(
54+
'uid' => array('7'),
55+
'username' => 'samluser7',
56+
'cn' => 'Saml User 7',
57+
'eduPersonAffiliation' => array('group7'),
58+
'email' => 'samluser7@example.com',
59+
'channels' => array('saml-channel-1', 'saml-channel-2'),
60+
),
4061
'samlusernoname:password' => array(
4162
'uid' => array('5'),
4263
'cn' => 'Saml User No Username',

apps/meteor/tests/e2e/fixtures/userStates.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ export const Users = {
125125
samluser1: generateContext('samluser1'),
126126
samluser2: generateContext('samluser2'),
127127
samluser4: generateContext('samluser4'),
128+
samluser5: generateContext('samluser5'),
129+
samluser6: generateContext('samluser6'),
130+
samluser7: generateContext('samluser7'),
128131
samlusernoname: generateContext('custom_saml_username'),
129132
samlusernoname2: generateContext('custom_saml_username2'),
130133
userForSamlMerge: generateContext('user_for_saml_merge'),

apps/meteor/tests/e2e/saml.spec.ts

Lines changed: 108 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@ const resetTestData = async ({ api, cleanupOnly = false }: { api?: any; cleanupO
3232
Users.samluser1,
3333
Users.samluser2,
3434
Users.samluser4,
35+
Users.samluser5,
36+
Users.samluser6,
37+
Users.samluser7,
3538
Users.samlusernoname,
3639
Users.samlusernoname2,
3740
].map(({ data: { username } }) => username),
3841
'custom_saml_username',
3942
'custom_saml_username2',
4043
];
44+
4145
await connection
4246
.db()
4347
.collection('users')
@@ -94,6 +98,8 @@ test.describe('SAML', () => {
9498
let targetInviteGroupId: string;
9599
let targetInviteGroupName: string;
96100
let inviteId: string;
101+
let targetChannel: string;
102+
let autoCreatedChannel: string;
97103

98104
const containerPath = path.join(__dirname, 'containers', 'saml');
99105

@@ -118,11 +124,18 @@ test.describe('SAML', () => {
118124
});
119125

120126
test.beforeAll(async ({ api }) => {
121-
const groupResponse = await api.post('/groups.create', { name: faker.string.uuid() });
127+
const [groupResponse, channelResponse] = await Promise.all([
128+
api.post('/groups.create', { name: faker.string.uuid() }),
129+
api.post('/channels.create', { name: 'saml-channel-1' }),
130+
]);
131+
122132
expect(groupResponse.status()).toBe(200);
133+
expect(channelResponse.status()).toBe(200);
134+
123135
const { group } = await groupResponse.json();
124136
targetInviteGroupId = group._id;
125137
targetInviteGroupName = group.name;
138+
targetChannel = 'saml-channel-1';
126139

127140
const inviteResponse = await api.post('/findOrCreateInvite', { rid: targetInviteGroupId, days: 1, maxUses: 0 });
128141
expect(inviteResponse.status()).toBe(200);
@@ -154,7 +167,11 @@ test.describe('SAML', () => {
154167
});
155168

156169
test.afterAll(async ({ api }) => {
157-
expect((await api.post('/groups.delete', { roomId: targetInviteGroupId })).status()).toBe(200);
170+
await Promise.all([
171+
api.post('/groups.delete', { roomId: targetInviteGroupId }).then((response) => expect(response.status()).toBe(200)),
172+
api.post('/channels.delete', { roomName: targetChannel }).then((response) => expect(response.status()).toBe(200)),
173+
api.post('/channels.delete', { roomName: autoCreatedChannel }),
174+
]);
158175
});
159176

160177
test.beforeEach(async ({ page }) => {
@@ -573,12 +590,97 @@ test.describe('SAML', () => {
573590
// Test different variations of the Immutable Property setting
574591
});
575592

576-
test.fixme('Login - User without name', async () => {
577-
// Test login with a SAML user with no name
593+
test('Login - User without name', async ({ page, api }) => {
594+
await test.step('expect user name to fallback to username when displayName is not provided', async () => {
595+
await doLoginStep(page, 'samluser5');
596+
597+
const user = await getUserInfo(api, 'samluser5');
598+
599+
expect(user).toBeDefined();
600+
expect(user?.username).toBe('samluser5');
601+
expect(user?.emails).toBeDefined();
602+
expect(user?.emails?.[0].address).toBe('samluser5@example.com');
603+
// When displayName is not provided, it should fall back to username
604+
expect(user?.name).toBe('samluser5');
605+
await doLogoutStep(page);
606+
});
607+
608+
await test.step('expect user name to fallback to displayName when provided', async () => {
609+
await doLoginStep(page, 'samluser6');
610+
611+
const user = await getUserInfo(api, 'samluser6');
612+
613+
expect(user).toBeDefined();
614+
expect(user?.username).toBe('samluser6');
615+
expect(user?.emails).toBeDefined();
616+
expect(user?.emails?.[0].address).toBe('samluser6@example.com');
617+
// When displayName is provided, it should fall back to displayName
618+
expect(user?.name).toBe('Saml User 6 Display Name');
619+
});
578620
});
579621

580-
test.fixme('Login - User with channels attribute', async () => {
581-
// Test login with a SAML user with a "channels" attribute
622+
test('Login - User with channels attribute', async ({ page, api }) => {
623+
autoCreatedChannel = 'saml-channel-2';
624+
625+
await test.step('Configure SAML to enable channels attribute updates', async () => {
626+
expect((await setSettingValueById(api, 'SAML_Custom_Default_channels_update', true)).status()).toBe(200);
627+
});
628+
629+
await doLoginStep(page, 'samluser7');
630+
631+
await test.step('expect user data to have been mapped correctly', async () => {
632+
const user = await getUserInfo(api, 'samluser7');
633+
634+
expect(user).toBeDefined();
635+
expect(user?.username).toBe('samluser7');
636+
expect(user?.name).toBe('Saml User 7');
637+
expect(user?.emails).toBeDefined();
638+
expect(user?.emails?.[0].address).toBe('samluser7@example.com');
639+
});
640+
641+
await test.step('expect auto-created channel to be created automatically', async () => {
642+
const channelInfoResponse = await api.get(`/channels.info?roomName=${autoCreatedChannel}`);
643+
expect(channelInfoResponse.status()).toBe(200);
644+
const { channel } = await channelInfoResponse.json();
645+
expect(channel).toBeDefined();
646+
expect(channel.name).toBe(autoCreatedChannel);
647+
});
648+
649+
await test.step('expect user to be member of existing channel', async () => {
650+
const existingChannelMembersResponse = await api.get(`/channels.members?roomName=${targetChannel}`);
651+
expect(existingChannelMembersResponse.status()).toBe(200);
652+
const { members: existingMembers } = await existingChannelMembersResponse.json();
653+
expect(existingMembers).toBeDefined();
654+
expect(existingMembers.some((member: { username: string }) => member.username === 'samluser7')).toBe(true);
655+
});
656+
657+
await test.step('expect user to be member of auto-created channel', async () => {
658+
const autoCreatedChannelMembersResponse = await api.get(`/channels.members?roomName=${autoCreatedChannel}`);
659+
expect(autoCreatedChannelMembersResponse.status()).toBe(200);
660+
const { members: autoCreatedMembers } = await autoCreatedChannelMembersResponse.json();
661+
expect(autoCreatedMembers).toBeDefined();
662+
expect(autoCreatedMembers.some((member: { username: string }) => member.username === 'samluser7')).toBe(true);
663+
});
664+
665+
await doLogoutStep(page);
666+
667+
await doLoginStep(page, 'samluser1');
668+
669+
await test.step('expect user without channels attribute to not be added to existing channel', async () => {
670+
const existingChannelMembersResponse = await api.get(`/channels.members?roomName=${targetChannel}`);
671+
expect(existingChannelMembersResponse.status()).toBe(200);
672+
const { members: existingMembers } = await existingChannelMembersResponse.json();
673+
expect(existingMembers).toBeDefined();
674+
expect(existingMembers.some((member: { username: string }) => member.username === 'samluser1')).toBe(false);
675+
});
676+
677+
await test.step('expect user without channels attribute to not be added to auto-created channel', async () => {
678+
const autoCreatedChannelMembersResponse = await api.get(`/channels.members?roomName=${autoCreatedChannel}`);
679+
expect(autoCreatedChannelMembersResponse.status()).toBe(200);
680+
const { members: autoCreatedMembers } = await autoCreatedChannelMembersResponse.json();
681+
expect(autoCreatedMembers).toBeDefined();
682+
expect(autoCreatedMembers.some((member: { username: string }) => member.username === 'samluser1')).toBe(false);
683+
});
582684
});
583685

584686
test.fixme('Data Sync - Custom Field Map', async () => {

0 commit comments

Comments
 (0)