From 0f73b90334d940e972ad64df20f96d9be80fc6f2 Mon Sep 17 00:00:00 2001 From: Khurdhula-Harshavardhan Date: Wed, 6 May 2026 13:05:14 -0700 Subject: [PATCH 1/3] feat(stt): add word timestamps to stt and cleanup test suites --- src/audio/interfaces.ts | 1 + tests/classification.test.ts | 2 +- tests/validate.test.ts | 366 +---------------------------------- tests/vision.test.ts | 4 +- tests/web-scraper.test.ts | 2 +- 5 files changed, 10 insertions(+), 365 deletions(-) diff --git a/src/audio/interfaces.ts b/src/audio/interfaces.ts index c5403d4..5a4f508 100644 --- a/src/audio/interfaces.ts +++ b/src/audio/interfaces.ts @@ -10,6 +10,7 @@ export interface SpeechToTextParams { webhook_url?: string; batch_size?: number; chunk_duration?: number; + word_timestamps?: boolean; } export interface SpeechToTextParamsWithWebhook extends SpeechToTextParams { diff --git a/tests/classification.test.ts b/tests/classification.test.ts index 7fdcfa8..1618593 100644 --- a/tests/classification.test.ts +++ b/tests/classification.test.ts @@ -62,7 +62,7 @@ const IMAGE_LABELS = [ }, { type: "image" as const, - value: "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Instagram_icon.png/2048px-Instagram_icon.png", + value: "https://upload.wikimedia.org/wikipedia/commons/a/a5/Instagram_icon.png", }, ]; diff --git a/tests/validate.test.ts b/tests/validate.test.ts index 276638b..45787fd 100644 --- a/tests/validate.test.ts +++ b/tests/validate.test.ts @@ -501,7 +501,7 @@ describe("NSFW validation", () => { test("should prioritize url when both parameters are provided", async () => { const result = await client.validate.nsfw({ - url: "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Logo_of_Twitter.svg/512px-Logo_of_Twitter.svg.png", + url: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2070", file_store_key: "test_key", // This should be ignored in favor of URL }); @@ -525,7 +525,7 @@ describe("NSFW validation", () => { test("should validate response structure completely", async () => { const result = await client.validate.nsfw({ - url: "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Logo_of_Twitter.svg/512px-Logo_of_Twitter.svg.png", + url: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2070", }); // Verify the complete response structure @@ -568,7 +568,7 @@ describe("NSFW validation", () => { test("should handle very long URL", async () => { const longUrl = - "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Logo_of_Twitter.svg/512px-Logo_of_Twitter.svg.png" + "?param=" + "a".repeat(1000); + "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2070" + "?param=" + "a".repeat(1000); try { const result = await client.validate.nsfw({ url: longUrl }); @@ -597,7 +597,7 @@ describe("NSFW validation", () => { test("NSFW detection with URL", async () => { const result = await client.validate.nsfw({ - url: "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Logo_of_Twitter.svg/512px-Logo_of_Twitter.svg.png", + url: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2070", }); expectSuccess(result); @@ -621,7 +621,7 @@ describe("NSFW validation", () => { test("NSFW detection with safe image URL", async () => { const result = await client.validate.nsfw({ - url: "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Logo_of_Twitter.svg/512px-Logo_of_Twitter.svg.png", + url: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2070", }); expectSuccess(result); @@ -659,359 +659,3 @@ describe("NSFW validation", () => { } }); }); - -// Comprehensive SpellCheck API Tests -// describe("SpellCheck validation", () => { -// let client: ReturnType; - -// beforeEach(() => { -// client = createJigsawStackClient(); -// }); - -// test("should fail when text parameter is missing", async () => { -// try { -// // @ts-expect-error Testing missing required parameter -// await client.validate.spellcheck({}); -// throw new Error("Expected API call to fail with missing text parameter"); -// } catch (error) { -// // Should throw an error for missing required parameter -// expectType(error, "object"); -// } -// }); - -// test("should fail when text parameter is undefined", async () => { -// try { -// // @ts-expect-error Testing undefined required parameter -// await client.validate.spellcheck({ text: undefined }); -// throw new Error("Expected API call to fail with undefined text parameter"); -// } catch (error) { -// expectType(error, "object"); -// } -// }); - -// test("should fail when text parameter is null", async () => { -// try { -// // @ts-expect-error Testing null required parameter -// await client.validate.spellcheck({ text: null }); -// throw new Error("Expected API call to fail with null text parameter"); -// } catch (error) { -// expectType(error, "object"); -// } -// }); - -// test("should work with only required text parameter", async () => { -// const result = await client.validate.spellcheck({ -// text: "This is a correctly spelled sentence.", -// }); - -// // Verify success -// expectSuccess(result); - -// // Verify all required response properties exist -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "misspellings"); -// expectProperty(result, "auto_correct_text"); - -// // Verify correct types -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); -// }); - -// test("should work with custom language_code parameter", async () => { -// const result = await client.validate.spellcheck({ -// text: "Hola mundo como estas", -// language_code: "es", -// }); - -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "misspellings"); -// expectProperty(result, "auto_correct_text"); - -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); -// }); - -// test("should handle empty text", async () => { -// const result = await client.validate.spellcheck({ -// text: "", -// }); - -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "misspellings"); -// expectProperty(result, "auto_correct_text"); - -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); - -// // Empty text should have no misspellings -// if (result.misspellings_found !== false) { -// console.log("Note: Misspellings found in empty text"); -// } -// }); - -// test("should handle text with intentional misspellings", async () => { -// const result = await client.validate.spellcheck({ -// text: "Ths is a mispelled sentance with erors.", -// language_code: "en", -// }); - -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "misspellings"); -// expectProperty(result, "auto_correct_text"); - -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); - -// // Should find misspellings in our intentionally misspelled text -// if (result.misspellings_found === false) { -// console.log("Note: No misspellings found in intentionally misspelled text"); -// } - -// // Validate misspellings array structure when misspellings are found -// if (result.misspellings_found === true) { -// result.misspellings.forEach((misspelling) => { -// expectType(misspelling, "object"); -// expectProperty(misspelling, "word"); -// expectProperty(misspelling, "startIndex"); -// expectProperty(misspelling, "endIndex"); -// expectProperty(misspelling, "expected"); -// expectProperty(misspelling, "auto_corrected"); -// expectType(misspelling.word, "string"); -// expectType(misspelling.startIndex, "number"); -// expectType(misspelling.endIndex, "number"); -// expectArray(misspelling.expected); -// expectType(misspelling.auto_corrected, "boolean"); -// }); -// } - -// // Auto-corrected text should be different from original -// if (result.auto_correct_text === "Ths is a mispelled sentance with erors.") { -// console.log("Note: Auto-corrected text is identical to original misspelled text"); -// } -// }); - -// test("should handle text with special characters", async () => { -// const result = await client.validate.spellcheck({ -// text: "Special chars: !@#$%^&*()_+-=[]{}|;':\",./<>?", -// language_code: "en", -// }); - -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "misspellings"); -// expectProperty(result, "auto_correct_text"); - -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); -// }); - -// test("should handle text with numbers", async () => { -// const result = await client.validate.spellcheck({ -// text: "The year 2024 has 365 days and 12 months.", -// language_code: "en", -// }); - -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "misspellings"); -// expectProperty(result, "auto_correct_text"); - -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); -// }); - -// test("should handle unicode characters", async () => { -// const result = await client.validate.spellcheck({ -// text: "Unicode: 你好 🌟 émojis 🚀 ñoño café résumé", -// language_code: "en", -// }); - -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "misspellings"); -// expectProperty(result, "auto_correct_text"); - -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); -// }); - -// test("should handle very long text", async () => { -// const longText = "This is a very long text that contains many words. ".repeat(50); -// const result = await client.validate.spellcheck({ -// text: longText, -// language_code: "en", -// }); - -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "misspellings"); -// expectProperty(result, "auto_correct_text"); - -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); -// }); - -// test("should handle different supported language codes", async () => { -// const testCases = [ -// { text: "Hello world", language_code: "en", name: "English" }, -// { text: "Hola mundo", language_code: "es", name: "Spanish" }, -// { text: "Bonjour monde", language_code: "fr", name: "French" }, -// { text: "Hallo Welt", language_code: "de", name: "German" }, -// { text: "Ciao mondo", language_code: "it", name: "Italian" }, -// ]; - -// // Run all API calls in parallel -// const results = await Promise.allSettled( -// testCases.map(async (testCase) => { -// try { -// const result = await client.validate.spellcheck({ -// text: testCase.text, -// language_code: testCase.language_code, -// }); - -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "misspellings"); -// expectProperty(result, "auto_correct_text"); - -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); - -// return { success: true, testCase }; -// } catch (error) { -// expectType(error, "object"); -// return { success: false, testCase, error }; -// } -// }) -// ); - -// // Process results and log outcomes -// results.forEach((result, index) => { -// const testCase = testCases[index]; -// if (result.status === "fulfilled") { -// if (result.value.success) { -// console.log(`✓ ${testCase.name} (${testCase.language_code}) works`); -// } else { -// console.log(`Note: ${testCase.name} (${testCase.language_code}) failed - may not be supported`); -// } -// } else { -// console.log(`Note: ${testCase.name} (${testCase.language_code}) failed - may not be supported`); -// } -// }); -// }); - -// test("should handle invalid language code", async () => { -// try { -// const result = await client.validate.spellcheck({ -// text: "This is a test sentence.", -// language_code: "invalid_code", -// }); - -// // If it doesn't throw an error, validate the response -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "auto_correct_text"); - -// console.log("Note: Invalid language code was accepted"); -// } catch (error) { -// console.log("Note: Invalid language code was rejected (expected)"); -// expectType(error, "object"); -// } -// }); - -// test("should handle empty language code", async () => { -// try { -// const result = await client.validate.spellcheck({ -// text: "This is a test sentence.", -// language_code: "", -// }); - -// expectSuccess(result); -// expectProperty(result, "success"); -// expectProperty(result, "misspellings_found"); -// expectProperty(result, "auto_correct_text"); -// } catch (error) { -// console.log("Note: Empty language code was rejected"); -// expectType(error, "object"); -// } -// }); - -// test("should validate response structure completely", async () => { -// const result = await client.validate.spellcheck({ -// text: "This is a test sentence with some mispellings.", -// language_code: "en", -// }); - -// // Verify the complete response structure -// expectSuccess(result); -// expectType(result, "object"); - -// // Check if response has expected properties -// const expectedProperties = ["success", "misspellings_found", "misspellings", "auto_correct_text"]; -// const resultKeys = Object.keys(result); - -// // Ensure all expected properties exist -// for (const expectedProp of expectedProperties) { -// expectProperty(result, expectedProp); -// } - -// // Log any unexpected properties (might be from documentation but not in interface) -// for (const key of resultKeys) { -// if (!expectedProperties.includes(key)) { -// console.log(`Note: Additional property '${key}' found in SpellCheck response`); -// } -// } - -// // Validate types -// expectType(result.success, "boolean"); -// expectType(result.misspellings_found, "boolean"); -// expectArray(result.misspellings); -// expectType(result.auto_correct_text, "string"); - -// // Validate misspellings array structure -// result.misspellings.forEach((misspelling) => { -// expectType(misspelling, "object"); -// expectProperty(misspelling, "word"); -// expectProperty(misspelling, "startIndex"); -// expectProperty(misspelling, "endIndex"); -// expectProperty(misspelling, "expected"); -// expectProperty(misspelling, "auto_corrected"); -// expectType(misspelling.word, "string"); -// expectType(misspelling.startIndex, "number"); -// expectType(misspelling.endIndex, "number"); -// expectArray(misspelling.expected); -// expectType(misspelling.auto_corrected, "boolean"); -// }); -// }); -// }); diff --git a/tests/vision.test.ts b/tests/vision.test.ts index 940f442..594f0cc 100644 --- a/tests/vision.test.ts +++ b/tests/vision.test.ts @@ -319,7 +319,7 @@ describe("VOCR (Visual OCR) API", () => { test("should work with different image formats", async () => { const imageUrls = [ - "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png", // PNG + "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png", // PNG "https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg", // SVG ]; @@ -684,7 +684,7 @@ describe("Object Detection API", () => { test("should work with different image formats", async () => { const imageUrls = [ - "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png", // PNG + "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png", // PNG "https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg", // SVG ]; diff --git a/tests/web-scraper.test.ts b/tests/web-scraper.test.ts index ab58596..3d972c5 100644 --- a/tests/web-scraper.test.ts +++ b/tests/web-scraper.test.ts @@ -2,7 +2,7 @@ import { beforeEach, describe, test } from "node:test"; import { createJigsawStackClient, expectArray, expectProperty, expectSuccess, expectType } from "./test-helpers.js"; const TEST_URLS = { - image: "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png", + image: "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png", pdf: "https://www.w3.org/WAI/WCAG21/working-examples/pdf-table/table.pdf", audio: "https://jigsawstack.com/preview/stt-example.wav", webpage: "https://www.wikipedia.org", From 303bf06ed03ee13240a6d2ff292a455035a16e6e Mon Sep 17 00:00:00 2001 From: Khurdhula-Harshavardhan Date: Wed, 6 May 2026 13:18:27 -0700 Subject: [PATCH 2/3] tests: update invalidated urls --- tests/vision.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/vision.test.ts b/tests/vision.test.ts index 594f0cc..d536757 100644 --- a/tests/vision.test.ts +++ b/tests/vision.test.ts @@ -320,7 +320,7 @@ describe("VOCR (Visual OCR) API", () => { test("should work with different image formats", async () => { const imageUrls = [ "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png", // PNG - "https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg", // SVG + "https://upload.wikimedia.org/wikipedia/commons/8/8a/Banana-Single.jpg", // JPG ]; // Run all API calls in parallel @@ -685,7 +685,7 @@ describe("Object Detection API", () => { test("should work with different image formats", async () => { const imageUrls = [ "https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png", // PNG - "https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg", // SVG + "https://upload.wikimedia.org/wikipedia/commons/8/8a/Banana-Single.jpg", // JPG ]; // Run all API calls in parallel From 7651a59b880470419329a97ce9697460a19f4d4b Mon Sep 17 00:00:00 2001 From: Khurdhula-Harshavardhan Date: Wed, 6 May 2026 13:20:50 -0700 Subject: [PATCH 3/3] chore: formatting --- tests/validate.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/validate.test.ts b/tests/validate.test.ts index 45787fd..1c535d1 100644 --- a/tests/validate.test.ts +++ b/tests/validate.test.ts @@ -567,8 +567,7 @@ describe("NSFW validation", () => { }); test("should handle very long URL", async () => { - const longUrl = - "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2070" + "?param=" + "a".repeat(1000); + const longUrl = "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2070" + "?param=" + "a".repeat(1000); try { const result = await client.validate.nsfw({ url: longUrl });