336 lines
10 KiB
TypeScript
336 lines
10 KiB
TypeScript
/**
|
|
* Webhook E2E Tests
|
|
*
|
|
* Tests for webhook CRUD operations.
|
|
*/
|
|
|
|
/// <reference path="./globals.d.ts" />
|
|
|
|
import { waitForAppReady, TestData } from './fixtures';
|
|
|
|
describe('Webhook Operations', () => {
|
|
let testWebhookId: string | null = null;
|
|
let testWorkspaceId: string | null = null;
|
|
|
|
before(async () => {
|
|
await waitForAppReady();
|
|
// Get a workspace ID for webhook operations
|
|
const workspaces = await browser.execute(async () => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const response = await api?.listWorkspaces();
|
|
return response?.workspaces ?? [];
|
|
} catch {
|
|
return [];
|
|
}
|
|
});
|
|
// Only use workspace if it has a valid (non-null) ID
|
|
const nullUuid = '00000000-0000-0000-0000-000000000000';
|
|
if (workspaces.length > 0 && workspaces[0].id && workspaces[0].id !== nullUuid) {
|
|
testWorkspaceId = workspaces[0].id;
|
|
}
|
|
});
|
|
|
|
after(async () => {
|
|
if (testWebhookId) {
|
|
try {
|
|
await browser.execute(async (id) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
await api?.deleteWebhook(id);
|
|
}, testWebhookId);
|
|
} catch {
|
|
// Ignore cleanup errors
|
|
}
|
|
}
|
|
});
|
|
|
|
describe('registerWebhook', () => {
|
|
it('should register a new webhook', async () => {
|
|
if (!testWorkspaceId) {
|
|
// Skip test - no workspace available
|
|
return;
|
|
}
|
|
|
|
const testId = TestData.generateTestId();
|
|
|
|
const result = await browser.execute(
|
|
async (id, workspaceId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const webhook = await api?.registerWebhook({
|
|
workspace_id: workspaceId,
|
|
url: `https://example.com/webhook/${id}`,
|
|
events: ['meeting.completed'],
|
|
name: `Test Webhook ${id}`,
|
|
});
|
|
return { success: true, webhook };
|
|
} catch (e: unknown) {
|
|
const error = e as { message?: string; error?: string };
|
|
const errorMsg =
|
|
error?.message ||
|
|
error?.error ||
|
|
(typeof e === 'object' ? JSON.stringify(e) : String(e));
|
|
return { success: false, error: errorMsg };
|
|
}
|
|
},
|
|
testId,
|
|
testWorkspaceId
|
|
);
|
|
|
|
expect(result).toBeDefined();
|
|
if (result.success) {
|
|
expect(result.webhook).toHaveProperty('id');
|
|
expect(result.webhook).toHaveProperty('url');
|
|
expect(result.webhook).toHaveProperty('events');
|
|
testWebhookId = result.webhook?.id ?? null;
|
|
}
|
|
});
|
|
|
|
it('should register webhook with multiple events', async () => {
|
|
if (!testWorkspaceId) {
|
|
// Skip test - no workspace available
|
|
return;
|
|
}
|
|
|
|
const testId = TestData.generateTestId();
|
|
|
|
const result = await browser.execute(
|
|
async (id, workspaceId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const webhook = await api?.registerWebhook({
|
|
workspace_id: workspaceId,
|
|
url: `https://example.com/webhook/${id}`,
|
|
events: ['meeting.completed', 'summary.generated', 'recording.started'],
|
|
name: `Multi-Event Webhook ${id}`,
|
|
});
|
|
return { success: true, webhook };
|
|
} catch (e: unknown) {
|
|
const error = e as { message?: string; error?: string };
|
|
const errorMsg =
|
|
error?.message ||
|
|
error?.error ||
|
|
(typeof e === 'object' ? JSON.stringify(e) : String(e));
|
|
return { success: false, error: errorMsg };
|
|
}
|
|
},
|
|
testId,
|
|
testWorkspaceId
|
|
);
|
|
|
|
expect(result).toBeDefined();
|
|
if (result.success) {
|
|
expect(result.webhook?.events?.length).toBe(3);
|
|
// Cleanup
|
|
if (result.webhook?.id) {
|
|
await browser.execute(async (webhookId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
await api?.deleteWebhook(webhookId);
|
|
}, result.webhook.id);
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should register webhook with secret', async () => {
|
|
if (!testWorkspaceId) {
|
|
// Skip test - no workspace available
|
|
return;
|
|
}
|
|
|
|
const testId = TestData.generateTestId();
|
|
|
|
const result = await browser.execute(
|
|
async (id, workspaceId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const webhook = await api?.registerWebhook({
|
|
workspace_id: workspaceId,
|
|
url: `https://example.com/webhook/${id}`,
|
|
events: ['meeting.completed'],
|
|
name: `Secret Webhook ${id}`,
|
|
secret: 'my-webhook-secret',
|
|
});
|
|
return { success: true, webhook };
|
|
} catch (e: unknown) {
|
|
const error = e as { message?: string; error?: string };
|
|
const errorMsg =
|
|
error?.message ||
|
|
error?.error ||
|
|
(typeof e === 'object' ? JSON.stringify(e) : String(e));
|
|
return { success: false, error: errorMsg };
|
|
}
|
|
},
|
|
testId,
|
|
testWorkspaceId
|
|
);
|
|
|
|
expect(result).toBeDefined();
|
|
if (result.success && result.webhook?.id) {
|
|
// Cleanup
|
|
await browser.execute(async (webhookId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
await api?.deleteWebhook(webhookId);
|
|
}, result.webhook.id);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('listWebhooks', () => {
|
|
it('should list all webhooks', async () => {
|
|
const result = await browser.execute(async () => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const response = await api?.listWebhooks();
|
|
return { success: true, ...response };
|
|
} catch (e) {
|
|
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
}
|
|
});
|
|
|
|
expect(result).toBeDefined();
|
|
if (result.success) {
|
|
expect(result).toHaveProperty('webhooks');
|
|
expect(Array.isArray(result.webhooks)).toBe(true);
|
|
}
|
|
});
|
|
|
|
it('should list only enabled webhooks', async () => {
|
|
const result = await browser.execute(async () => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const response = await api?.listWebhooks(true);
|
|
return { success: true, ...response };
|
|
} catch (e) {
|
|
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
}
|
|
});
|
|
|
|
expect(result).toBeDefined();
|
|
if (result.success && result.webhooks) {
|
|
for (const webhook of result.webhooks) {
|
|
expect(webhook.enabled).toBe(true);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('updateWebhook', () => {
|
|
it('should update webhook name', async () => {
|
|
if (!testWebhookId) {
|
|
// Skip test - no test webhook created
|
|
return;
|
|
}
|
|
|
|
const result = await browser.execute(async (webhookId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const updated = await api?.updateWebhook({
|
|
webhook_id: webhookId,
|
|
name: 'Updated Webhook Name',
|
|
});
|
|
return { success: true, updated };
|
|
} catch (e) {
|
|
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
}
|
|
}, testWebhookId);
|
|
|
|
expect(result).toBeDefined();
|
|
if (result.success) {
|
|
expect(result.updated?.name).toBe('Updated Webhook Name');
|
|
}
|
|
});
|
|
|
|
it('should disable webhook', async () => {
|
|
if (!testWebhookId) {
|
|
// Skip test - no test webhook created
|
|
return;
|
|
}
|
|
|
|
const result = await browser.execute(async (webhookId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const updated = await api?.updateWebhook({
|
|
webhook_id: webhookId,
|
|
enabled: false,
|
|
});
|
|
return { success: true, updated };
|
|
} catch (e) {
|
|
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
}
|
|
}, testWebhookId);
|
|
|
|
expect(result).toBeDefined();
|
|
if (result.success) {
|
|
expect(result.updated?.enabled).toBe(false);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('getWebhookDeliveries', () => {
|
|
it('should get delivery history', async () => {
|
|
if (!testWebhookId) {
|
|
// Skip test - no test webhook created
|
|
return;
|
|
}
|
|
|
|
const result = await browser.execute(async (webhookId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const response = await api?.getWebhookDeliveries(webhookId, 10);
|
|
return { success: true, ...response };
|
|
} catch (e) {
|
|
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
}
|
|
}, testWebhookId);
|
|
|
|
expect(result).toBeDefined();
|
|
if (result.success) {
|
|
expect(result).toHaveProperty('deliveries');
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('deleteWebhook', () => {
|
|
it('should delete a webhook', async () => {
|
|
if (!testWorkspaceId) {
|
|
// Skip test - no workspace available
|
|
return;
|
|
}
|
|
|
|
// Create a webhook to delete
|
|
const testId = TestData.generateTestId();
|
|
const createResult = await browser.execute(
|
|
async (id, workspaceId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
return await api?.registerWebhook({
|
|
workspace_id: workspaceId,
|
|
url: `https://example.com/delete/${id}`,
|
|
events: ['meeting.completed'],
|
|
name: `Delete Test ${id}`,
|
|
});
|
|
} catch {
|
|
return null;
|
|
}
|
|
},
|
|
testId,
|
|
testWorkspaceId
|
|
);
|
|
|
|
if (createResult?.id) {
|
|
const deleteResult = await browser.execute(async (webhookId) => {
|
|
const api = window.__NOTEFLOW_API__;
|
|
try {
|
|
const response = await api?.deleteWebhook(webhookId);
|
|
return { success: true, ...response };
|
|
} catch (e) {
|
|
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
}
|
|
}, createResult.id);
|
|
|
|
expect(deleteResult.success).toBe(true);
|
|
}
|
|
});
|
|
});
|
|
});
|