Files
twenty/packages/twenty-server/test/integration/metadata/suites/connected-account/connected-account-resolver.integration-spec.ts
T
neo773 d3f0162cf5 Remove connected account feature flag (#19286)
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2026-04-06 08:13:41 +00:00

165 lines
5.2 KiB
TypeScript

import { gql } from 'graphql-tag';
import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util';
import { makeMetadataAPIRequestWithMemberRole } from 'test/integration/metadata/suites/utils/make-metadata-api-request-with-member-role.util';
import { CONNECTED_ACCOUNT_DATA_SEED_IDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/connected-account-data-seeds.constant';
describe('connectedAccountResolver (e2e)', () => {
describe('myConnectedAccounts', () => {
it('should return only the current user connected accounts', async () => {
const response = await makeMetadataAPIRequest({
query: gql`
query MyConnectedAccounts {
myConnectedAccounts {
id
handle
provider
}
}
`,
});
expect(response.status).toBe(200);
expect(response.body.errors).toBeUndefined();
const accounts = response.body.data.myConnectedAccounts;
const accountIds = accounts.map((account: { id: string }) => account.id);
expect(accountIds).toContain(CONNECTED_ACCOUNT_DATA_SEED_IDS.JANE);
expect(accountIds).not.toContain(CONNECTED_ACCOUNT_DATA_SEED_IDS.JONY);
});
it('should not return sensitive fields', async () => {
const response = await makeMetadataAPIRequest({
query: gql`
query MyConnectedAccounts {
myConnectedAccounts {
id
handle
provider
authFailedAt
scopes
handleAliases
lastSignedInAt
userWorkspaceId
createdAt
updatedAt
}
}
`,
});
expect(response.status).toBe(200);
expect(response.body.errors).toBeUndefined();
const account = response.body.data.myConnectedAccounts.find(
(connectedAccount: { id: string }) =>
connectedAccount.id === CONNECTED_ACCOUNT_DATA_SEED_IDS.JANE,
);
expect(account).toBeDefined();
expect(account.handle).toBe('jane.austen@apple.dev');
expect(account).not.toHaveProperty('accessToken');
expect(account).not.toHaveProperty('refreshToken');
expect(account).not.toHaveProperty('connectionParameters');
expect(account).not.toHaveProperty('oidcTokenClaims');
});
it('should reject requesting hidden fields via GraphQL', async () => {
const response = await makeMetadataAPIRequest({
query: gql`
query MyConnectedAccounts {
myConnectedAccounts {
id
accessToken
}
}
`,
});
expect(response.status).toBe(200);
expect(response.body.errors).toBeDefined();
expect(response.body.errors.length).toBeGreaterThan(0);
});
});
describe('connectedAccounts (admin listing)', () => {
it('should return all workspace accounts for admin', async () => {
const response = await makeMetadataAPIRequest({
query: gql`
query ConnectedAccounts {
connectedAccounts {
id
handle
provider
}
}
`,
});
expect(response.status).toBe(200);
expect(response.body.errors).toBeUndefined();
const accounts = response.body.data.connectedAccounts;
const accountIds = accounts.map((account: { id: string }) => account.id);
expect(accountIds).toContain(CONNECTED_ACCOUNT_DATA_SEED_IDS.JANE);
expect(accountIds).toContain(CONNECTED_ACCOUNT_DATA_SEED_IDS.JONY);
});
it('should also be accessible for member role (tool permission)', async () => {
const response = await makeMetadataAPIRequestWithMemberRole({
query: gql`
query ConnectedAccounts {
connectedAccounts {
id
handle
}
}
`,
});
expect(response.status).toBe(200);
expect(response.body.errors).toBeUndefined();
expect(response.body.data.connectedAccounts).toBeDefined();
});
});
describe('deleteConnectedAccount', () => {
it('should allow deleting own account', async () => {
const response = await makeMetadataAPIRequest({
query: gql`
mutation DeleteConnectedAccount($id: UUID!) {
deleteConnectedAccount(id: $id) {
id
}
}
`,
variables: { id: CONNECTED_ACCOUNT_DATA_SEED_IDS.JANE_DELETABLE },
});
expect(response.status).toBe(200);
expect(response.body.errors).toBeUndefined();
expect(response.body.data.deleteConnectedAccount.id).toBe(
CONNECTED_ACCOUNT_DATA_SEED_IDS.JANE_DELETABLE,
);
});
it('should deny deleting another user account', async () => {
const response = await makeMetadataAPIRequest({
query: gql`
mutation DeleteConnectedAccount($id: UUID!) {
deleteConnectedAccount(id: $id) {
id
}
}
`,
variables: { id: CONNECTED_ACCOUNT_DATA_SEED_IDS.JONY },
});
expect(response.status).toBe(200);
expect(response.body.errors?.[0]?.extensions?.code).toBe('FORBIDDEN');
});
});
});