Files
OmniRoute/tests/unit/resolve-web-provider-host.test.ts
Diego Rodrigues de Sa e Souza 7d57d9f4a1 fix(providers): retire common ChatGPT Web provider (#11754)
Rebased onto the current release/v3.8.51 tip as part of a combined provider-retirement/provenance merge batch (Designer Web, Felo Web, Runtime, GPL-derived removal, Qwen Web already landed). Large conflict set (this is the biggest PR in the batch — the common ChatGPT Web provider touches chat, images, count-tokens, session leases, and combos). Conflicts resolved:

- `open-sse/config/providers/registry/chatgpt-web/*`, `open-sse/executors/chatgpt-web*`, `open-sse/handlers/imageGeneration/providers/chatgptWeb.ts`, and their tests: kept deleted, matching the PR's stated scope.
- `open-sse/config/providers/registry/minimax/web/index.ts`, `open-sse/handlers/imageGeneration/providers/geminiWeb.ts`, `open-sse/executors/gemini-web.ts`'s stale image-mode branch: base-drift collisions against already-merged sibling retirements (#11691, #11708) — kept deleted / dropped the dead code, since this PR's own branch forked before those merged.
- `src/shared/constants/reservedProviderPrefixes.ts`, `open-sse/executors/index.ts`, `executorProxy.ts`, `virtualFactory.ts`, `autoStrategy.ts`, `src/lib/db/providers.ts`, `src/sse/handlers/chat.ts`: combined the Designer + Runtime (Felo/Qwen) + common-ChatGPT-Web retirement guard calls at each shared chokepoint — compute-once-then-OR pattern, consistent with prior combinations in this batch.
- `src/sse/services/model.ts` / `src/sse/handlers/chatHelpers.ts`: adopted this PR's new `getModelInfoOrRetirementResponse()` central wrapper (a real improvement over ad-hoc try/catch), and extended it to also catch the Designer + Runtime retirement errors it didn't originally cover, so the consolidation doesn't regress the other two mechanisms.
- `src/app/api/v1/images/edits/route.ts`: this PR moved the retirement check earlier (before `enforceApiKeyPolicy`) but left the old later call+catch block in place from base drift — removed the now-redundant duplicate `resolveImageRouteModel()` call and merged the Designer catch into the earlier one.
- `open-sse/config/imageRegistry.ts`, `tests/snapshots/executors/executor-map.json` (`keyCount` recomputed to 133), `tests/snapshots/provider/translate-path.json`: same "both sides inserted a different retired provider at the same slot" pattern — resolved by dropping both.
- `tests/unit/chatcore-executor-proxy.test.ts`, `provider-node-reserved-prefix.test.ts`, `combo-auto-candidate-expansion.test.ts`, `messages-count-tokens-route.test.ts`, `virtual-auto-combo.test.ts`: split into independent per-mechanism test blocks (established pattern); `virtual-auto-combo.test.ts`'s old "includes cookie web-session providers" positive-inclusion test (which used chatgpt-web as its example) was retired along with the provider and replaced by this PR's negative-exclusion test for the same slot.
- `docs/architecture/ARCHITECTURE.md`, `CODEBASE_DOCUMENTATION.md` (+ 4 i18n mirrors), `README.md`, `FREE-TIERS-GUIDE.md`, `docs/diagrams/free-tier-budget.svg`, `docs/screenshots/free-tier-budget-card.svg`, `docs/reference/PROVIDER_REFERENCE.md`: recomputed every stale count from the real merged state — 104 executors (`countFiles` gate logic), 351 providers (regenerated via `gen:provider-reference`), 152/351 `hasFree` entries, 445/438/7 free-tier catalog rows, 13 ToS-avoid providers, budget-card regenerated via its real generator script. One doc conflict (`oauth/` module list) needed picking HEAD's side specifically — theirs still listed the already-removed `raycast` module instead of the real `openference`.
- `config/quality/test-masking-allowlist.json`: additive merge of the PR's 17 `_deletedWithReplacement` entries alongside the batch's existing ones (one real duplicate-key mistake in my first pass, caught and fixed via a `object_pairs_hook` duplicate-key check before finalizing).

Also fixed two real, unrelated-to-my-merge issues surfaced by the focused suite:
- `tests/unit/resolve-web-provider-host.test.ts`: the PR's own test had a typo — it asserted `perplexity-web`'s resolved host as `"perplexity.ai"`, but the provider's registered `website` is `"https://www.perplexity.ai"` and the resolver returns the URL's `host` verbatim (no www-stripping), so the correct value is `"www.perplexity.ai"` (consistent with the same test's own `url` assertion).
- `tests/unit/hard-session-lease-bypass-inventory.test.ts`: this golden call-site inventory was already stale on the pristine post-#11713 tip (confirmed via a throwaway probe worktree) — `src/lib/db/providers.ts`'s 3 connection-fallback sites and a third `src/app/api/providers/route.ts` site were never added to the golden list by the earlier-merged #11698/#11720 PRs. Updated it to the real current inventory (dated inline comments explain each delta and which PR introduced it), plus this PR's own legitimate deltas (image-edits duplicate-call removal, `ChatGptWebExecutor.execute()` site removed).

Focused suite green (433/433 across executor-proxy, reserved-prefix, hard-session-lease-bypass-inventory, resolve-web-provider-host, retirement/runtime-block/source-retirement/management-retirement/image-handler-retirement, migration-168, combo-auto-candidate-expansion, virtual-auto-combo, executor-map-golden and siblings), plus `typecheck:core`, `check-file-size`, and `check-changelog-integrity` clean. Thanks for the thorough provenance-hold retirement work — appreciated.
2026-08-28 06:52:46 -03:00

62 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test } from "node:test";
import assert from "node:assert/strict";
import {
resolveWebProviderHost,
WEB_COOKIE_PROVIDERS,
} from "@/shared/constants/providers/web-cookie";
// Feature #6268 — "Open host →" link in the "Add session cookie" modal.
// Pure host-resolution helper backing the modal link.
test("known -web provider returns the host derived from its `website`", () => {
const link = resolveWebProviderHost("perplexity-web");
assert.ok(link, "expected a resolved link for perplexity-web");
// perplexity-web's registered website is "https://www.perplexity.ai", and
// resolveWebProviderHost returns URL.host verbatim (no www-stripping), so
// both host and url carry the "www." prefix.
assert.equal(link.host, "www.perplexity.ai");
assert.equal(link.url, "https://www.perplexity.ai");
});
test("retired common ChatGPT Web ids no longer resolve provider links", () => {
assert.equal(resolveWebProviderHost("chatgpt-web"), null);
assert.equal(resolveWebProviderHost("cgpt-web"), null);
assert.equal(resolveWebProviderHost("chatgpt-web-codex")?.host, "chatgpt.com");
});
test("website with a path keeps the full URL but exposes the bare host", () => {
// huggingchat's website is https://huggingface.co/chat
const link = resolveWebProviderHost("huggingchat");
assert.ok(link);
assert.equal(link.host, "huggingface.co");
assert.equal(link.url, "https://huggingface.co/chat");
});
test("provider with no `website` but a registry baseUrl returns the origin", () => {
// duckduckgo-web is a real web-session provider that is NOT in
// WEB_COOKIE_PROVIDERS and has no `website`; the caller supplies its registry
// baseUrl as a fallback, from which only the origin is kept.
assert.equal(
(WEB_COOKIE_PROVIDERS as Record<string, unknown>)["duckduckgo-web"],
undefined,
"test premise: duckduckgo-web must be absent from WEB_COOKIE_PROVIDERS"
);
const link = resolveWebProviderHost("duckduckgo-web", "https://duckduckgo.com/duckchat/v1/chat");
assert.ok(link);
assert.equal(link.host, "duckduckgo.com");
assert.equal(link.url, "https://duckduckgo.com");
});
test("non-web / unknown provider returns null", () => {
assert.equal(resolveWebProviderHost("openai"), null);
assert.equal(resolveWebProviderHost("totally-made-up"), null);
assert.equal(resolveWebProviderHost(null), null);
assert.equal(resolveWebProviderHost(undefined), null);
assert.equal(resolveWebProviderHost(""), null);
});
test("unparseable fallback baseUrl yields null instead of throwing", () => {
assert.equal(resolveWebProviderHost("duckduckgo-web", "not a url"), null);
});