- 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.
232 lines
6.1 KiB
TypeScript
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");
|
|
});
|
|
});
|
|
});
|