Dashboard-Automatizase/lib/__tests__/n8n-api.test.ts
Luis Erlacher 0152a2fda0 feat: add n8n API testing script for Google OAuth2 schema and existing credentials
- Implemented a bash script to test n8n API and retrieve credential schemas.
- Added types for API responses, Google Calendar, and WhatsApp instances.
- Configured Vitest for testing with React and added setup for testing-library.
2025-10-10 14:29:02 -03:00

232 lines
6.1 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
// Mock environment variables BEFORE importing module
process.env.N8N_API_BASE_URL = "https://n8n.test/api/v1";
process.env.N8N_API_KEY = "test-api-key";
process.env.N8N_GOOGLE_CREDENTIAL_ID = "cred-123";
import {
createGoogleCredential,
updateCredentialTokens,
upsertGoogleCredential,
} from "../n8n-api";
// Mock global fetch
global.fetch = vi.fn();
describe("n8n-api", () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe("upsertGoogleCredential", () => {
it("deve atualizar credencial existente via PUT", async () => {
const mockResponse = {
id: "cred-123",
name: "refugio",
type: "googleOAuth2Api",
};
(global.fetch as any).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse,
});
const result = await upsertGoogleCredential(
"refugio",
"client-id",
"client-secret",
"https://www.googleapis.com/auth/calendar.events",
"access-token",
"refresh-token",
3599,
);
expect(result.id).toBe("cred-123");
expect(global.fetch).toHaveBeenCalledWith(
expect.stringContaining("/credentials/cred-123"),
expect.objectContaining({
method: "PUT",
headers: expect.objectContaining({
"X-N8N-API-KEY": expect.any(String),
"Content-Type": "application/json",
}),
}),
);
});
it("deve criar nova credencial via POST se PUT falhar", async () => {
const mockResponse = {
id: "new-cred-456",
name: "refugio",
type: "googleOAuth2Api",
};
// PUT falha
(global.fetch as any).mockResolvedValueOnce({
ok: false,
statusText: "Not Found",
});
// POST sucede
(global.fetch as any).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse,
});
const result = await upsertGoogleCredential(
"refugio",
"client-id",
"client-secret",
"https://www.googleapis.com/auth/calendar.events",
"access-token",
"refresh-token",
3599,
);
expect(result.id).toBe("new-cred-456");
expect(global.fetch).toHaveBeenCalledTimes(2);
});
});
describe("createGoogleCredential", () => {
it("deve criar credencial com dados corretos", async () => {
const mockResponse = {
id: "new-cred-123",
name: "refugio",
type: "googleOAuth2Api",
};
(global.fetch as any).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse,
});
const result = await createGoogleCredential(
"refugio",
"client-id",
"client-secret",
"https://www.googleapis.com/auth/calendar.events",
);
expect(result.id).toBe("new-cred-123");
expect(global.fetch).toHaveBeenCalledWith(
expect.stringContaining("/credentials"),
expect.objectContaining({
method: "POST",
headers: expect.objectContaining({
"X-N8N-API-KEY": expect.any(String),
"Content-Type": "application/json",
}),
body: expect.stringContaining('"name":"refugio"'),
}),
);
});
});
describe("updateCredentialTokens", () => {
it("deve atualizar tokens com sucesso", async () => {
const mockResponse = {
id: "cred-123",
name: "refugio",
};
(global.fetch as any).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse,
});
const result = await updateCredentialTokens(
"cred-123",
"access-token",
"refresh-token",
3599,
);
expect(result.id).toBe("cred-123");
expect(global.fetch).toHaveBeenCalledWith(
expect.stringContaining("/credentials/cred-123"),
expect.objectContaining({
method: "PUT",
body: expect.stringContaining('"access_token":"access-token"'),
}),
);
});
it("deve lançar erro quando credencial não existe (404)", async () => {
const mockError = { message: "Credential not found" };
(global.fetch as any).mockResolvedValueOnce({
ok: false,
json: async () => mockError,
});
await expect(
updateCredentialTokens("invalid-id", "token", "refresh", 3599),
).rejects.toThrow("Failed to update credential");
});
});
describe("createGoogleCredential - error scenarios", () => {
it("deve lançar erro quando schema está inválido (400)", async () => {
const mockError = {
message: "Validation error",
errors: ["Missing required field: clientId"],
};
(global.fetch as any).mockResolvedValueOnce({
ok: false,
json: async () => mockError,
});
await expect(
createGoogleCredential("test", "", "", "scopes"),
).rejects.toThrow("Failed to create credential");
});
it("deve lançar erro quando API key é inválida (401)", async () => {
const mockError = { message: "Unauthorized" };
(global.fetch as any).mockResolvedValueOnce({
ok: false,
status: 401,
json: async () => mockError,
});
await expect(
createGoogleCredential("test", "id", "secret", "scopes"),
).rejects.toThrow("Failed to create credential");
});
});
describe("upsertGoogleCredential - error scenarios", () => {
it("deve lançar erro quando POST falha após PUT falhar", async () => {
const mockError = { message: "Internal server error" };
// PUT falha
(global.fetch as any).mockResolvedValueOnce({
ok: false,
statusText: "Not Found",
});
// POST também falha
(global.fetch as any).mockResolvedValueOnce({
ok: false,
json: async () => mockError,
});
await expect(
upsertGoogleCredential(
"test",
"id",
"secret",
"scopes",
"token",
"refresh",
3599,
),
).rejects.toThrow("Failed to create credential");
});
});
});