Suit le même schéma que marmitonAdapter (construit sur jsonLdRecipeAdapter), avec deux différences propres à 750g.com : - list() n'a pas d'ItemList JSON-LD à lire sur ses résultats de recherche (la recherche du site est un widget client-side) — appelle donc directement le endpoint GET que ce widget interroge lui-même en interne (un « moteur de réponse IA » qui renvoie un lot de recettes pour une requête en texte libre), et scrape les cartes de résultat par regex en associant à chaque lien de recette sa dernière image précédente plutôt qu'un zip naïf par index (des images décoratives sans carte associée existent réellement dans ce fragment). Vérifié en direct : demander une « page 2 » revient toujours vide, donc nextCursor vaut toujours null, comme theMealDbAdapter. - parse() ne délègue pas aussi directement à jsonLdRecipeAdapter.parse que marmitonAdapter — le générateur JSON-LD de 750g.com a deux bugs réels : des caractères de contrôle bruts non échappés dans certaines chaînes JSON (~1 recette sur 3 dans un échantillon vérifié en direct, sinon JSON.parse échoue et jsonLdRecipeAdapter rapporte à tort « aucun Recipe trouvé »), et un texte parfois doublement encodé en entités HTML (ex. un vrai « é » devient &eacute; au lieu de é). Les deux sont corrigés en pré/post-traitement autour de la même délégation, pas une réimplémentation. Enregistre sevenFiftyGAdapter dans registerAllRecipeSources (sources/index.ts), au même titre que marmitonAdapter. Complète aussi test/sources/sources-index.test.ts, qui ne couvrait encore que TheMealDB malgré l'ajout de Marmiton dans une PR précédente. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
52 lines
2 KiB
TypeScript
52 lines
2 KiB
TypeScript
import { expect } from "chai";
|
|
import {
|
|
clearRecipeSources,
|
|
getRecipeSource,
|
|
listRecipeSources,
|
|
} from "../../src/lib/recipe-sources/recipe-source-registry.js";
|
|
import { registerAllRecipeSources } from "../../src/sources/index.js";
|
|
|
|
// Not exercised by any other test file — `registerAllRecipeSources` is
|
|
// deliberately never imported by `app.ts` (see its own doc comment), so
|
|
// nothing else in the suite triggers it. Registers/clears explicitly here
|
|
// rather than relying on module-load order, so this test's outcome doesn't
|
|
// depend on which other test file Mocha happens to load first.
|
|
describe("registerAllRecipeSources", () => {
|
|
afterEach(() => {
|
|
clearRecipeSources();
|
|
});
|
|
|
|
it("registers TheMealDB into the shared registry", () => {
|
|
registerAllRecipeSources();
|
|
|
|
const theMealDb = getRecipeSource("theMealDb");
|
|
expect(theMealDb).to.not.be.undefined;
|
|
expect(theMealDb?.name).to.equal("TheMealDB");
|
|
expect(listRecipeSources().map((adapter) => adapter.key)).to.include("theMealDb");
|
|
});
|
|
|
|
it("registers Marmiton into the shared registry", () => {
|
|
registerAllRecipeSources();
|
|
|
|
const marmiton = getRecipeSource("marmiton");
|
|
expect(marmiton).to.not.be.undefined;
|
|
expect(marmiton?.name).to.equal("Marmiton");
|
|
expect(listRecipeSources().map((adapter) => adapter.key)).to.include("marmiton");
|
|
});
|
|
|
|
it("registers 750g into the shared registry", () => {
|
|
registerAllRecipeSources();
|
|
|
|
const sevenFiftyG = getRecipeSource("750g");
|
|
expect(sevenFiftyG).to.not.be.undefined;
|
|
expect(sevenFiftyG?.name).to.equal("750g");
|
|
expect(listRecipeSources().map((adapter) => adapter.key)).to.include("750g");
|
|
});
|
|
|
|
it("does not register the generic JSON-LD adapter — it's not a household-toggleable source in its own right", () => {
|
|
registerAllRecipeSources();
|
|
|
|
expect(getRecipeSource("jsonLdRecipe")).to.be.undefined;
|
|
expect(listRecipeSources().map((adapter) => adapter.key)).to.not.include("jsonLdRecipe");
|
|
});
|
|
});
|