diff --git a/packages/account-client/src/client.ts b/packages/account-client/src/client.ts index dcc2c958e0..6cbaf21e55 100644 --- a/packages/account-client/src/client.ts +++ b/packages/account-client/src/client.ts @@ -146,21 +146,12 @@ export interface AccountClient { updateIntegration: (integration: Integration) => Promise deleteIntegration: (integrationKey: IntegrationKey) => Promise getIntegration: (integrationKey: IntegrationKey) => Promise - listIntegrations: (filter: { - socialId?: PersonId - kind?: string - workspaceUuid?: WorkspaceUuid | null - }) => Promise + listIntegrations: (filter: Partial) => Promise addIntegrationSecret: (integrationSecret: IntegrationSecret) => Promise updateIntegrationSecret: (integrationSecret: IntegrationSecret) => Promise deleteIntegrationSecret: (integrationSecretKey: IntegrationSecretKey) => Promise getIntegrationSecret: (integrationSecretKey: IntegrationSecretKey) => Promise - listIntegrationsSecrets: (filter: { - socialId?: PersonId - kind?: string - workspaceUuid?: WorkspaceUuid | null - key?: string - }) => Promise + listIntegrationsSecrets: (filter: Partial) => Promise getAccountInfo: (uuid: PersonUuid) => Promise setCookie: () => Promise @@ -786,11 +777,7 @@ class AccountClientImpl implements AccountClient { return await this.rpc(request) } - async listIntegrations (filter: { - socialId?: PersonId - kind?: string - workspaceUuid?: WorkspaceUuid | null - }): Promise { + async listIntegrations (filter: Partial): Promise { const request = { method: 'listIntegrations' as const, params: filter @@ -835,12 +822,7 @@ class AccountClientImpl implements AccountClient { return await this.rpc(request) } - async listIntegrationsSecrets (filter: { - socialId?: PersonId - kind?: string - workspaceUuid?: WorkspaceUuid | null - key?: string - }): Promise { + async listIntegrationsSecrets (filter: Partial): Promise { const request = { method: 'listIntegrationsSecrets' as const, params: filter diff --git a/packages/account-client/src/types.ts b/packages/account-client/src/types.ts index 2bf6795eea..e1f67c63e9 100644 --- a/packages/account-client/src/types.ts +++ b/packages/account-client/src/types.ts @@ -59,7 +59,7 @@ export interface MailboxInfo { export interface Integration { socialId: PersonId kind: string // Integration kind. E.g. 'github', 'mail', 'telegram-bot', 'telegram' etc. - workspaceUuid?: WorkspaceUuid + workspaceUuid: WorkspaceUuid | null data?: Record } @@ -68,7 +68,7 @@ export type IntegrationKey = Omit export interface IntegrationSecret { socialId: PersonId kind: string // Integration kind. E.g. 'github', 'mail', 'telegram-bot', 'telegram' etc. - workspaceUuid?: WorkspaceUuid + workspaceUuid: WorkspaceUuid | null key: string // Key for the secret in the integration. Different secrets for the same integration must have different keys. Can be any string. E.g. '', 'user_app_1' etc. secret: string } diff --git a/server/account/src/__tests__/serviceOperations.test.ts b/server/account/src/__tests__/serviceOperations.test.ts index 4fdf1869f8..d8d9827a32 100644 --- a/server/account/src/__tests__/serviceOperations.test.ts +++ b/server/account/src/__tests__/serviceOperations.test.ts @@ -889,15 +889,14 @@ describe('integration methods', () => { expect(mockDb.integrationSecret.findOne).toHaveBeenCalledWith(mockSecretKey) }) - test('should throw error when secret not found', async () => { + test('should return null when integration secret not found', async () => { ;(decodeTokenVerbose as jest.Mock).mockReturnValue({ extra: { service: 'github' } }) ;(mockDb.integrationSecret.findOne as jest.Mock).mockResolvedValue(null) - await expect(getIntegrationSecret(mockCtx, mockDb, mockBranding, mockToken, mockSecretKey)).rejects.toThrow( - new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationSecretNotFound, {})) - ) + const result = await getIntegrationSecret(mockCtx, mockDb, mockBranding, mockToken, mockSecretKey) + expect(result).toBeNull() }) test('should throw error for unauthorized service', async () => { diff --git a/server/account/src/collections/mongo.ts b/server/account/src/collections/mongo.ts index 9fc307f89b..40d77fda17 100644 --- a/server/account/src/collections/mongo.ts +++ b/server/account/src/collections/mongo.ts @@ -62,6 +62,15 @@ interface MongoIndex { options: CreateIndexesOptions & { name: string } } +function getFilteredQuery (query: Query): Query { + return Object.entries(query).reduce>((acc, [key, value]) => { + if (value !== undefined) { + acc[key as keyof Query] = value + } + return acc + }, {}) +} + export class MongoDbCollection, K extends keyof T | undefined = undefined> implements DbCollection { constructor ( @@ -123,11 +132,11 @@ implements DbCollection { } async find (query: Query, sort?: Sort, limit?: number): Promise { - return await this.findCursor(query, sort, limit).toArray() + return await this.findCursor(getFilteredQuery(query), sort, limit).toArray() } findCursor (query: Query, sort?: Sort, limit?: number): FindCursor { - const cursor = this.collection.find(query as Filter) + const cursor = this.collection.find(getFilteredQuery(query) as Filter) if (sort !== undefined) { cursor.sort(sort as RawSort) @@ -147,7 +156,7 @@ implements DbCollection { } async findOne (query: Query): Promise { - const doc = await this.collection.findOne(query as Filter) + const doc = await this.collection.findOne(getFilteredQuery(query) as Filter) if (doc === null) { return null } @@ -190,11 +199,11 @@ implements DbCollection { } } - await this.collection.updateOne(query as Filter, resOps) + await this.collection.updateOne(getFilteredQuery(query) as Filter, resOps) } async deleteMany (query: Query): Promise { - await this.collection.deleteMany(query as Filter) + await this.collection.deleteMany(getFilteredQuery(query) as Filter) } } @@ -218,7 +227,7 @@ export class AccountMongoDbCollection extends MongoDbCollection } async findOne (query: Query): Promise { - const res = await this.collection.findOne(query as Filter) + const res = await this.collection.findOne(getFilteredQuery(query) as Filter) return res !== null ? this.convertToObj(res) : null } @@ -247,7 +256,7 @@ export class WorkspaceStatusMongoDbCollection implements DbCollection): Query { const res: Query = {} - for (const key of Object.keys(query)) { + for (const key of Object.keys(getFilteredQuery(query))) { const qVal = (query as any)[key] if (key === 'workspaceUuid') { res.uuid = qVal diff --git a/server/account/src/collections/postgres.ts b/server/account/src/collections/postgres.ts index 0d02088e81..a61fca8862 100644 --- a/server/account/src/collections/postgres.ts +++ b/server/account/src/collections/postgres.ts @@ -180,8 +180,8 @@ implements DbCollection { break } default: { - currIdx++ if (qKey !== null) { + currIdx++ whereChunks.push(`"${snakeKey}" = ${formatVar(currIdx, castType)}`) values.push(qKey) } else { @@ -955,10 +955,7 @@ export class PostgresAccountDB implements AccountDB { _def_ws_uuid UUID NOT NULL GENERATED ALWAYS AS (COALESCE(workspace_uuid, '00000000-0000-0000-0000-000000000000')) STORED NOT VISIBLE, key STRING, secret STRING NOT NULL, - CONSTRAINT integration_secrets_pk PRIMARY KEY (social_id, kind, _def_ws_uuid, key), - CONSTRAINT integration_secrets_integrations_fk FOREIGN KEY (social_id, kind, _def_ws_uuid) - REFERENCES ${this.ns}.integrations(social_id, kind, _def_ws_uuid) - ON DELETE CASCADE + CONSTRAINT integration_secrets_pk PRIMARY KEY (social_id, kind, _def_ws_uuid, key) ); ` ] diff --git a/server/account/src/serviceOperations.ts b/server/account/src/serviceOperations.ts index c86321cd71..4fa9b38eeb 100644 --- a/server/account/src/serviceOperations.ts +++ b/server/account/src/serviceOperations.ts @@ -518,7 +518,7 @@ export async function createIntegration ( verifyAllowedServices(integrationServices, extra) const { socialId, kind, workspaceUuid, data } = params - if (kind == null || socialId == null) { + if (kind == null || socialId == null || workspaceUuid === undefined) { throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) } @@ -553,6 +553,10 @@ export async function updateIntegration ( verifyAllowedServices(integrationServices, extra) const { socialId, kind, workspaceUuid, data } = params + if (kind == null || socialId == null || workspaceUuid === undefined) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) + } + const existing = await db.integration.findOne({ socialId, kind, workspaceUuid }) if (existing == null) { throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationNotFound, {})) @@ -572,11 +576,16 @@ export async function deleteIntegration ( verifyAllowedServices(integrationServices, extra) const { socialId, kind, workspaceUuid } = params + if (kind == null || socialId == null || workspaceUuid === undefined) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) + } + const existing = await db.integration.findOne({ socialId, kind, workspaceUuid }) if (existing == null) { throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationNotFound, {})) } + await db.integrationSecret.deleteMany({ socialId, kind, workspaceUuid }) await db.integration.deleteMany({ socialId, kind, workspaceUuid }) } @@ -585,11 +594,7 @@ export async function listIntegrations ( db: AccountDB, branding: Branding | null, token: string, - params: { - socialId?: PersonId - kind?: string - workspaceUuid?: WorkspaceUuid | null - } + params: Partial ): Promise { const { account, extra } = decodeTokenVerbose(ctx, token) const isAllowedService = verifyAllowedServices(integrationServices, extra, false) @@ -636,6 +641,10 @@ export async function getIntegration ( const isAllowedService = verifyAllowedServices(integrationServices, extra, false) const { socialId, kind, workspaceUuid } = params + if (kind == null || socialId == null || workspaceUuid === undefined) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) + } + if (!isAllowedService) { const existingSocialId = await db.socialId.findOne({ _id: socialId, personUuid: account, verifiedOn: { $gt: 0 } }) @@ -658,7 +667,7 @@ export async function addIntegrationSecret ( verifyAllowedServices(integrationServices, extra) const { socialId, kind, workspaceUuid, key, secret } = params - if (kind == null || socialId == null || key == null) { + if (kind == null || socialId == null || workspaceUuid === undefined || key == null) { throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) } @@ -690,6 +699,10 @@ export async function updateIntegrationSecret ( const { socialId, kind, workspaceUuid, key, secret } = params const secretKey: IntegrationSecretKey = { socialId, kind, workspaceUuid, key } + if (kind == null || socialId == null || workspaceUuid === undefined || key == null) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) + } + const existingSecret = await db.integrationSecret.findOne(secretKey) if (existingSecret == null) { throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationSecretNotFound, {})) @@ -710,6 +723,10 @@ export async function deleteIntegrationSecret ( const { socialId, kind, workspaceUuid, key } = params const secretKey: IntegrationSecretKey = { socialId, kind, workspaceUuid, key } + if (kind == null || socialId == null || workspaceUuid === undefined || key == null) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) + } + const existingSecret = await db.integrationSecret.findOne(secretKey) if (existingSecret == null) { throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationSecretNotFound, {})) @@ -729,11 +746,12 @@ export async function getIntegrationSecret ( verifyAllowedServices(integrationServices, extra) const { socialId, kind, workspaceUuid, key } = params - const existing = await db.integrationSecret.findOne({ socialId, kind, workspaceUuid, key }) - if (existing == null) { - throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationSecretNotFound, {})) + if (kind == null || socialId == null || workspaceUuid === undefined || key == null) { + throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {})) } + const existing = await db.integrationSecret.findOne({ socialId, kind, workspaceUuid, key }) + return existing } @@ -742,12 +760,7 @@ export async function listIntegrationsSecrets ( db: AccountDB, branding: Branding | null, token: string, - params: { - socialId?: PersonId - kind?: string - workspaceUuid?: WorkspaceUuid | null - key?: string - } + params: Partial ): Promise { const { extra } = decodeTokenVerbose(ctx, token) verifyAllowedServices(integrationServices, extra) diff --git a/server/account/src/types.ts b/server/account/src/types.ts index 55dc12767d..252588eb5e 100644 --- a/server/account/src/types.ts +++ b/server/account/src/types.ts @@ -142,7 +142,7 @@ export interface MailboxInfo { export interface Integration { socialId: PersonId kind: string // Integration kind. E.g. 'github', 'mail', 'telegram-bot', 'telegram' etc. - workspaceUuid?: WorkspaceUuid + workspaceUuid: WorkspaceUuid | null data?: Record } @@ -151,7 +151,7 @@ export type IntegrationKey = Omit export interface IntegrationSecret { socialId: PersonId kind: string // Integration kind. E.g. 'github', 'mail', 'telegram-bot', 'telegram' etc. - workspaceUuid?: WorkspaceUuid + workspaceUuid: WorkspaceUuid | null key: string // Key for the secret in the integration. Different secrets for the same integration must have different keys. Can be any string. E.g. '', 'user_app_1' etc. secret: string } diff --git a/tests/docker-compose.yaml b/tests/docker-compose.yaml index 6682ffdc06..3b42697a62 100644 --- a/tests/docker-compose.yaml +++ b/tests/docker-compose.yaml @@ -28,7 +28,7 @@ services: - 27018:27018 restart: unless-stopped cockroach: - image: cockroachdb/cockroach:latest-v24.2 + image: cockroachdb/cockroach:v24.1.2 ports: - '26258:26257' - '18089:8080' diff --git a/tests/sanity/.env b/tests/sanity/.env index 18f6d8dc40..d52241fd45 100644 --- a/tests/sanity/.env +++ b/tests/sanity/.env @@ -3,6 +3,7 @@ PLATFORM_TRANSACTOR='ws://localhost:3334' STAGING_URL='https://front.hc.engineering' PLATFORM_USER='user1' PLATFORM_USER_SECOND='user2' +PLATFORM_ADMIN='admin' PLATFORM_WS='sanity-ws' PLATFORM_TOKEN='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InVzZXIxIiwid29ya3NwYWNlIjoic2FuaXR5LXdzIn0.hfUCqePHO-WNps2by4B-CYGKIpDpLG0WVCUUtU-SVI4' LOCAL_URL='http://localhost:3003/' diff --git a/tests/sanity/package.json b/tests/sanity/package.json index 725fb25cc4..7f8b0f2261 100644 --- a/tests/sanity/package.json +++ b/tests/sanity/package.json @@ -51,6 +51,7 @@ "cross-env": "~7.0.3", "@hcengineering/core": "^0.6.32", "@hcengineering/client-resources": "^0.6.27", - "@hcengineering/account": "^0.6.0" + "@hcengineering/account": "^0.6.0", + "@hcengineering/account-client": "^0.6.0" } } diff --git a/tests/sanity/tests/API/AccountClient.ts b/tests/sanity/tests/API/AccountClient.ts new file mode 100644 index 0000000000..229096fe16 --- /dev/null +++ b/tests/sanity/tests/API/AccountClient.ts @@ -0,0 +1,20 @@ +import { getClient as getClientRaw, type AccountClient } from '@hcengineering/account-client' +import { LocalUrl, PlatformAdmin } from '../utils' + +let adminAccountClient: AccountClient + +export async function getAdminAccountClient (): Promise { + if (adminAccountClient != null) { + return adminAccountClient + } + + const unauthClient = getClientRaw(LocalUrl) + const loginInfo = await unauthClient.login(PlatformAdmin, '1234') + + if (loginInfo == null) { + throw new Error('Failed to login as admin') + } + + adminAccountClient = getClientRaw(LocalUrl, loginInfo.token) + return adminAccountClient +} diff --git a/tests/sanity/tests/integrations.spec.ts b/tests/sanity/tests/integrations.spec.ts new file mode 100644 index 0000000000..faefca5fd8 --- /dev/null +++ b/tests/sanity/tests/integrations.spec.ts @@ -0,0 +1,252 @@ +import { expect, test } from '@playwright/test' +import { faker } from '@faker-js/faker' +import { Integration, IntegrationSecret } from '@hcengineering/account' +import { buildSocialIdString, SocialIdType } from '@hcengineering/core' + +import { PlatformUser } from './utils' +import { getAdminAccountClient } from './API/AccountClient' + +test.describe('integrations in accounts tests', () => { + test('manage integrations', async () => { + const accountClient = await getAdminAccountClient() + + const personUuid = await accountClient.findPersonBySocialKey( + buildSocialIdString({ type: SocialIdType.EMAIL, value: PlatformUser }) + ) + if (personUuid == null) { + throw new Error('Failed to find person for PlatformUser: ' + PlatformUser) + } + + const personId1 = await accountClient.addSocialIdToPerson(personUuid, SocialIdType.EMAIL, faker.word.words(1), true) + const personId2 = await accountClient.addSocialIdToPerson( + personUuid, + SocialIdType.GITHUB, + faker.word.words(1), + true + ) + const personId3 = await accountClient.addSocialIdToPerson( + personUuid, + SocialIdType.GOOGLE, + faker.word.words(1), + true + ) + const workspaces = await accountClient.listWorkspaces() + if (workspaces.length === 0) { + throw new Error('No workspaces found') + } + const workspaceUuid = workspaces[0].uuid + + // Test data setup + const integration1: Integration = { + socialId: personId1, + kind: 'github', + workspaceUuid: null, // Global integration + data: { + repo: 'repo1', + owner: 'owner1', + branch: 'main' + } + } + + const integration2: Integration = { + socialId: personId2, + kind: 'telegram-bot', + workspaceUuid, + data: { + chatId: '123', + username: 'bot1', + webhookUrl: 'https://example.com/webhook' + } + } + + const integration3: Integration = { + socialId: personId3, + kind: 'mailbox', + workspaceUuid, + data: { + email: 'test@example.com', + name: 'Test Mailbox', + settings: { folder: 'INBOX' } + } + } + + // Create and verify integrations one by one + await accountClient.createIntegration(integration1) + const checkIntegration1 = await accountClient.getIntegration({ + socialId: integration1.socialId, + kind: integration1.kind, + workspaceUuid: integration1.workspaceUuid + }) + expect(checkIntegration1).toEqual(integration1) + + await accountClient.createIntegration(integration2) + let checkIntegration2 = await accountClient.getIntegration({ + socialId: integration2.socialId, + kind: integration2.kind, + workspaceUuid: integration2.workspaceUuid + }) + expect(checkIntegration2).toEqual(integration2) + + await accountClient.createIntegration(integration3) + const checkIntegration3 = await accountClient.getIntegration({ + socialId: integration3.socialId, + kind: integration3.kind, + workspaceUuid: integration3.workspaceUuid + }) + expect(checkIntegration3).toEqual(integration3) + + // Create secrets + const secret1: IntegrationSecret = { + socialId: personId1, + kind: 'github', + workspaceUuid: null, + key: 'token', + secret: 'github_pat_token_123' + } + + const secret2: IntegrationSecret = { + socialId: personId2, + kind: 'telegram-bot', + workspaceUuid, + key: 'bot_token', + secret: 'telegram_bot_token_123' + } + + const secret3: IntegrationSecret = { + socialId: personId2, + kind: 'telegram-bot', + workspaceUuid, + key: 'api_key', + secret: 'telegram_api_key_123' + } + + // Add and verify secrets one by one + await accountClient.addIntegrationSecret(secret1) + const checkSecret1 = await accountClient.getIntegrationSecret({ + socialId: secret1.socialId, + kind: secret1.kind, + workspaceUuid: secret1.workspaceUuid, + key: secret1.key + }) + expect(checkSecret1).toEqual(secret1) + + await accountClient.addIntegrationSecret(secret2) + let checkSecret2 = await accountClient.getIntegrationSecret({ + socialId: secret2.socialId, + kind: secret2.kind, + workspaceUuid: secret2.workspaceUuid, + key: secret2.key + }) + expect(checkSecret2).toEqual(secret2) + + await accountClient.addIntegrationSecret(secret3) + const checkSecret3 = await accountClient.getIntegrationSecret({ + socialId: secret3.socialId, + kind: secret3.kind, + workspaceUuid: secret3.workspaceUuid, + key: secret3.key + }) + expect(checkSecret3).toEqual(secret3) + + // Test listing with various filters + const allIntegrations = await accountClient.listIntegrations({}) + expect(allIntegrations).toHaveLength(3) + expect(allIntegrations).toEqual(expect.arrayContaining([integration1, integration2, integration3])) + + const workspaceIntegrations = await accountClient.listIntegrations({ workspaceUuid }) + expect(workspaceIntegrations).toHaveLength(2) + expect(workspaceIntegrations).toEqual(expect.arrayContaining([integration2, integration3])) + + const githubIntegrations = await accountClient.listIntegrations({ kind: 'github' }) + expect(githubIntegrations).toHaveLength(1) + expect(githubIntegrations[0]).toEqual(integration1) + + const telegramIntegrations = await accountClient.listIntegrations({ kind: 'telegram-bot' }) + expect(telegramIntegrations).toHaveLength(1) + expect(telegramIntegrations[0]).toEqual(integration2) + + // Test listing secrets with filters + const allSecrets = await accountClient.listIntegrationsSecrets({}) + expect(allSecrets).toHaveLength(3) + expect(allSecrets).toEqual(expect.arrayContaining([secret1, secret2, secret3])) + + const workspaceSecrets = await accountClient.listIntegrationsSecrets({ + workspaceUuid + }) + expect(workspaceSecrets).toHaveLength(2) + expect(workspaceSecrets).toEqual(expect.arrayContaining([secret2, secret3])) + + const telegramSecrets = await accountClient.listIntegrationsSecrets({ kind: 'telegram-bot' }) + expect(telegramSecrets).toHaveLength(2) + expect(telegramSecrets).toEqual(expect.arrayContaining([secret2, secret3])) + + // Test updates + const updatedIntegration2: Integration = { + ...integration2, + data: { + chatId: '456', + username: 'bot1_updated', + webhookUrl: 'https://example.com/webhook2' + } + } + await accountClient.updateIntegration(updatedIntegration2) + checkIntegration2 = await accountClient.getIntegration({ + socialId: integration2.socialId, + kind: integration2.kind, + workspaceUuid: integration2.workspaceUuid + }) + expect(checkIntegration2).toEqual(updatedIntegration2) + + const updatedSecret2: IntegrationSecret = { + ...secret2, + secret: 'telegram_bot_token_456' + } + await accountClient.updateIntegrationSecret(updatedSecret2) + checkSecret2 = await accountClient.getIntegrationSecret({ + socialId: secret2.socialId, + kind: secret2.kind, + workspaceUuid: secret2.workspaceUuid, + key: secret2.key + }) + expect(checkSecret2).toEqual(updatedSecret2) + + // Test deletions + await accountClient.deleteIntegration({ + socialId: integration1.socialId, + kind: integration1.kind, + workspaceUuid: integration1.workspaceUuid + }) + + await accountClient.deleteIntegrationSecret({ + socialId: secret2.socialId, + kind: secret2.kind, + workspaceUuid: secret2.workspaceUuid, + key: secret2.key + }) + + // Verify deletions + const remainingIntegrations = await accountClient.listIntegrations({}) + expect(remainingIntegrations).toHaveLength(2) + expect(remainingIntegrations).toEqual(expect.arrayContaining([updatedIntegration2, integration3])) + + const remainingSecrets = await accountClient.listIntegrationsSecrets({}) + expect(remainingSecrets).toHaveLength(1) + expect(remainingSecrets).toEqual(expect.arrayContaining([secret3])) + + // Verify deleted items don't exist + const deletedIntegration = await accountClient.getIntegration({ + socialId: integration1.socialId, + kind: integration1.kind, + workspaceUuid: integration1.workspaceUuid + }) + expect(deletedIntegration).toBeNull() + + const deletedSecret = await accountClient.getIntegrationSecret({ + socialId: secret2.socialId, + kind: secret2.kind, + workspaceUuid: secret2.workspaceUuid, + key: secret2.key + }) + expect(deletedSecret).toBeNull() + }) +}) diff --git a/tests/sanity/tests/utils.ts b/tests/sanity/tests/utils.ts index 9bb854d000..2629decdd6 100644 --- a/tests/sanity/tests/utils.ts +++ b/tests/sanity/tests/utils.ts @@ -14,6 +14,7 @@ export const PlatformURI = process.env.PLATFORM_URI as string export const PlatformTransactor = process.env.PLATFORM_TRANSACTOR as string export const PlatformUser = process.env.PLATFORM_USER as string export const PlatformUserSecond = process.env.PLATFORM_USER_SECOND as string +export const PlatformAdmin = process.env.PLATFORM_ADMIN as string export const PlatformWs = process.env.PLATFORM_WS as string export const PlatformSetting = process.env.SETTING as string export const PlatformSettingSecond = process.env.SETTING_SECOND as string diff --git a/ws-tests/docker-compose.yaml b/ws-tests/docker-compose.yaml index 32179b1948..ccb8ead964 100644 --- a/ws-tests/docker-compose.yaml +++ b/ws-tests/docker-compose.yaml @@ -32,7 +32,7 @@ services: - 27018:27018 restart: unless-stopped cockroach: - image: cockroachdb/cockroach:latest-v24.2 + image: cockroachdb/cockroach:v24.1.2 extra_hosts: - 'huly.local:host-gateway' ports: