Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  pdf-native-providers.test.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import { afterEach, describe, expect, it, vi } from "vitest";
import * as pdfNativeProviders from "./pdf-native-providers.js";

vi.mock("../../plugins/provider-runtime.js", () => ({
  normalizeProviderTransportWithPlugin: (params: { context?: { baseUrl?: string } }) =>
    params.context?.baseUrl ? { baseUrl: params.context.baseUrl } : undefined,
}));

const TEST_PDF_INPUT = { base64: "dGVzdA==", filename: "doc.pdf" } as const;

function makeAnthropicAnalyzeParams(
  overrides: Partial<{
    apiKey: string;
    modelId: string;
    prompt: string;
    pdfs: Array<{ base64: string; filename: string }>;
    maxTokens: number;
    baseUrl: string;
  }> = {},
) {
  return {
    apiKey: "test-key",
    modelId: "claude-opus-4-6",
    prompt: "test",
    pdfs: [TEST_PDF_INPUT],
    ...overrides,
  };
}

function makeGeminiAnalyzeParams(
  overrides: Partial<{
    apiKey: string;
    modelId: string;
    prompt: string;
    pdfs: Array<{ base64: string; filename: string }>;
    baseUrl: string;
  }> = {},
) {
  return {
    apiKey: "test-key",
    modelId: "gemini-2.5-pro",
    prompt: "test",
    pdfs: [TEST_PDF_INPUT],
    ...overrides,
  };
}

describe("native PDF provider API calls", () => {
  const priorFetch = global.fetch;

  const mockFetchResponse = (response: unknown) => {
    const fetchMock = vi.fn().mockResolvedValue(response);
    global.fetch = Object.assign(fetchMock, { preconnect: vi.fn() }) as typeof global.fetch;
    return fetchMock;
  };

  afterEach(() => {
    global.fetch = priorFetch;
  });

  it("anthropicAnalyzePdf sends correct request shape", async () => {
    const fetchMock = mockFetchResponse({
      ok: true,
      json: async () => ({
        content: [{ type: "text", text: "Analysis of PDF" }],
      }),
    });

    const result = await pdfNativeProviders.anthropicAnalyzePdf(
      makeAnthropicAnalyzeParams({
        modelId: "claude-opus-4-6",
        prompt: "Summarize this document",
        maxTokens: 4096,
      }),
    );

    expect(result).toBe("Analysis of PDF");
    expect(fetchMock).toHaveBeenCalledTimes(1);
    const [url, opts] = fetchMock.mock.calls[0];
    expect(url).toContain("/v1/messages");
    const body = JSON.parse(opts.body);
    expect(body.model).toBe("claude-opus-4-6");
    expect(body.messages[0].content).toHaveLength(2);
    expect(body.messages[0].content[0].type).toBe("document");
    expect(body.messages[0].content[0].source.media_type).toBe("application/pdf");
    expect(body.messages[0].content[1].type).toBe("text");
  });

  it("anthropicAnalyzePdf throws on API error", async () => {
    mockFetchResponse({
      ok: false,
      status: 400,
      statusText: "Bad Request",
      text: async () => "invalid request",
    });

    await expect(
      pdfNativeProviders.anthropicAnalyzePdf(makeAnthropicAnalyzeParams()),
    ).rejects.toThrow("Anthropic PDF request failed");
  });

  it("anthropicAnalyzePdf throws when response has no text", async () => {
    mockFetchResponse({
      ok: true,
      json: async () => ({
        content: [{ type: "text", text: "   " }],
      }),
    });

    await expect(
      pdfNativeProviders.anthropicAnalyzePdf(makeAnthropicAnalyzeParams()),
    ).rejects.toThrow("Anthropic PDF returned no text");
  });

  it("geminiAnalyzePdf sends correct request shape", async () => {
    const fetchMock = mockFetchResponse({
      ok: true,
      json: async () => ({
        candidates: [{ content: { parts: [{ text: "Gemini PDF analysis" }] } }],
      }),
    });

    const result = await pdfNativeProviders.geminiAnalyzePdf(
      makeGeminiAnalyzeParams({
        modelId: "gemini-2.5-pro",
        prompt: "Summarize this",
      }),
    );

    expect(result).toBe("Gemini PDF analysis");
    expect(fetchMock).toHaveBeenCalledTimes(1);
    const [url, opts] = fetchMock.mock.calls[0];
    expect(url).toContain("generateContent");
    expect(url).toContain("gemini-2.5-pro");
    const body = JSON.parse(opts.body);
    expect(body.contents[0].parts).toHaveLength(2);
    expect(body.contents[0].parts[0].inline_data.mime_type).toBe("application/pdf");
    expect(body.contents[0].parts[1].text).toBe("Summarize this");
  });

  it("geminiAnalyzePdf throws on API error", async () => {
    mockFetchResponse({
      ok: false,
      status: 500,
      statusText: "Internal Server Error",
      text: async () => "server error",
    });

    await expect(pdfNativeProviders.geminiAnalyzePdf(makeGeminiAnalyzeParams())).rejects.toThrow(
      "Gemini PDF request failed",
    );
  });

  it("geminiAnalyzePdf throws when no candidates returned", async () => {
    mockFetchResponse({
      ok: true,
      json: async () => ({ candidates: [] }),
    });

    await expect(pdfNativeProviders.geminiAnalyzePdf(makeGeminiAnalyzeParams())).rejects.toThrow(
      "Gemini PDF returned no candidates",
    );
  });

  it("anthropicAnalyzePdf supports multiple PDFs", async () => {
    const fetchMock = mockFetchResponse({
      ok: true,
      json: async () => ({
        content: [{ type: "text", text: "Multi-doc analysis" }],
      }),
    });

    await pdfNativeProviders.anthropicAnalyzePdf(
      makeAnthropicAnalyzeParams({
        modelId: "claude-opus-4-6",
        prompt: "Compare these documents",
        pdfs: [
          { base64: "cGRmMQ==", filename: "doc1.pdf" },
          { base64: "cGRmMg==", filename: "doc2.pdf" },
        ],
      }),
    );

    const body = JSON.parse(fetchMock.mock.calls[0][1].body);
    expect(body.messages[0].content).toHaveLength(3);
    expect(body.messages[0].content[0].type).toBe("document");
    expect(body.messages[0].content[1].type).toBe("document");
    expect(body.messages[0].content[2].type).toBe("text");
  });

  it("anthropicAnalyzePdf uses custom base URL", async () => {
    const fetchMock = mockFetchResponse({
      ok: true,
      json: async () => ({
        content: [{ type: "text", text: "ok" }],
      }),
    });

    await pdfNativeProviders.anthropicAnalyzePdf(
      makeAnthropicAnalyzeParams({ baseUrl: "https://custom.example.com" }),
    );

    expect(fetchMock.mock.calls[0][0]).toContain("https://custom.example.com/v1/messages");
  });

  it("anthropicAnalyzePdf requires apiKey", async () => {
    await expect(
      pdfNativeProviders.anthropicAnalyzePdf(makeAnthropicAnalyzeParams({ apiKey: "" })),
    ).rejects.toThrow("apiKey required");
  });

  it("geminiAnalyzePdf requires apiKey", async () => {
    await expect(
      pdfNativeProviders.geminiAnalyzePdf(makeGeminiAnalyzeParams({ apiKey: "" })),
    ).rejects.toThrow("apiKey required");
  });

  it("geminiAnalyzePdf does not duplicate /v1beta when baseUrl already includes it", async () => {
    const fetchMock = mockFetchResponse({
      ok: true,
      json: async () => ({
        candidates: [{ content: { parts: [{ text: "ok" }] } }],
      }),
    });

    await pdfNativeProviders.geminiAnalyzePdf(
      makeGeminiAnalyzeParams({
        baseUrl: "https://generativelanguage.googleapis.com/v1beta",
      }),
    );

    const [url] = fetchMock.mock.calls[0];
    expect(url).toContain("/v1beta/models/");
    expect(url).not.toContain("/v1beta/v1beta");
  });

  it("geminiAnalyzePdf normalizes bare Google API hosts to a single /v1beta root", async () => {
    const fetchMock = mockFetchResponse({
      ok: true,
      json: async () => ({
        candidates: [{ content: { parts: [{ text: "ok" }] } }],
      }),
    });

    await pdfNativeProviders.geminiAnalyzePdf(
      makeGeminiAnalyzeParams({
        baseUrl: "https://generativelanguage.googleapis.com",
      }),
    );

    const [url] = fetchMock.mock.calls[0];
    expect(url).toContain("https://generativelanguage.googleapis.com/v1beta/models/");
    expect(url).not.toContain("/v1beta/v1beta");
  });
});

¤ Dauer der Verarbeitung: 0.24 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge