fix(pl24): Hyundai/Kia illustration açıklamasını kod-yaprağa ekle
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Upstream doğrulandı: illustration satırında td[0]=figür kodu ("20-201A .1"),
td[1]=açıklama ("SUB ENGINE ASSY") — parser ilk td'yi (kod) alıp açıklamayı
düşürüyordu. Artık ilk td figür-koduysa (\d\d-\d\d\d[A-Z]?) açıklamalı sonraki
td eklenir → "20-201A .1 SUB ENGINE ASSY", canonical eşleşir (engine→motor).
Diğer markalar etkilenmez (yalnız kod-only ilk td'de tetiklenir). 10/10 test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -91,6 +91,20 @@ describe("PL24FordLegacyService.parseFordGroupsFromHtml — nav-crumb junk filte
|
||||
expect(groups.some((g) => g.linkPath.includes("eu.nissan.biz"))).toBe(false);
|
||||
});
|
||||
|
||||
it("appends the Hyundai illustration description to the bare figure code", () => {
|
||||
// Real Hyundai row shape: first <td> is the figure code (in a link), the
|
||||
// second <td> is the human description — which the parser used to drop.
|
||||
const html = [
|
||||
"<table>",
|
||||
'<tr class="tc-data-row" url="image-board.action?mainGroup=EN&subGroup=20-201A&illustration=1&lang=tr">' +
|
||||
'<td class="identifier"><a href="image-board.action?subGroup=20-201A">20-201A .1</a></td>' +
|
||||
"<td>SUB ENGINE ASSY</td><td></td></tr>",
|
||||
"</table>",
|
||||
].join("");
|
||||
const groups = pg.parseFordGroupsFromHtml(html, "hyundai_parts", "");
|
||||
expect(groups[0]?.nameTr).toBe("20-201A .1 SUB ENGINE ASSY");
|
||||
});
|
||||
|
||||
it("keeps Volvo vin-group.action?...group1=... (real category) but drops the bare breadcrumb", () => {
|
||||
const html = [
|
||||
'<tr class="tc-data-row" url="vin-group.action?group1=2&lang=tr" caption="Motor"><td>Motor</td></tr>',
|
||||
|
||||
@@ -3633,24 +3633,6 @@ export class PL24FordLegacyService {
|
||||
const groups: PL24DecodedCategory[] = [];
|
||||
const seen = new Set<string>();
|
||||
|
||||
// TEMP DEBUG (katalogJob Faz 2): dump the Hyundai/Kia illustration rows
|
||||
// (subGroup=/image-board), showing every <td> so we can see whether a
|
||||
// description sits next to the figure code.
|
||||
if (/hyundai|kia/i.test(serviceName)) {
|
||||
const rows = html
|
||||
.split(/<tr\s/)
|
||||
.filter((s) => s.includes("tc-data-row") && /subGroup=|image-board/.test(s))
|
||||
.slice(0, 5)
|
||||
.map((s) => {
|
||||
const tds = [...s.matchAll(/<td[^>]*>([\s\S]*?)<\/td>/g)].map((m) =>
|
||||
m[1].replace(/<[^>]+>/g, "·").replace(/ /g, " ").replace(/\s+/g, " ").trim(),
|
||||
);
|
||||
const cap = s.match(/caption="([^"]*)"/)?.[1] ?? "";
|
||||
return { caption: cap, tds };
|
||||
});
|
||||
this.logger.warn(`[hyundai-debug2] ${serviceName} illus rows: ${JSON.stringify(rows)}`);
|
||||
}
|
||||
|
||||
const config = getServiceConfig(serviceName);
|
||||
const basePath = config ? `${config.basePath}/${serviceName}` : `/ford/${serviceName}`;
|
||||
|
||||
@@ -3681,9 +3663,10 @@ export class PL24FordLegacyService {
|
||||
seen.add(url);
|
||||
|
||||
const captionMatch = segment.match(/\bcaption="([^"]+)"/);
|
||||
// Try to extract any text from <td> elements, including those with nested tags
|
||||
let tdName = "";
|
||||
// Collect all <td> texts (nested tags stripped). The first non-empty one
|
||||
// is the primary name for most brands.
|
||||
const tdPattern = /<td[^>]*>([\s\S]*?)<\/td>/g;
|
||||
const tdTexts: string[] = [];
|
||||
for (const tdMatch2 of segment.matchAll(tdPattern)) {
|
||||
const text = tdMatch2[1]
|
||||
.replace(/<[^>]+>/g, " ")
|
||||
@@ -3692,10 +3675,22 @@ export class PL24FordLegacyService {
|
||||
.replace(/\xa0/g, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
if (text.length >= 3) {
|
||||
tdName = text;
|
||||
break;
|
||||
}
|
||||
if (text.length >= 2) tdTexts.push(text);
|
||||
}
|
||||
let tdName = tdTexts.find((t) => t.length >= 3) ?? "";
|
||||
// Hyundai/Kia illustration rows put a bare figure code in the first cell
|
||||
// ("09-091 .1") and the human description in the next ("SUB ENGINE ASSY").
|
||||
// When the chosen name is code-only, append the first later cell that has
|
||||
// real words so the leaf is nameable (and canonically mappable via ENGINE).
|
||||
// Figure code like "09-091", "20-201A .1" (optional letter suffix + " .N"),
|
||||
// or a purely numeric/dotted code.
|
||||
const isCodeOnly = (s: string) => {
|
||||
const t = s.trim();
|
||||
return /^\d{1,3}-\d{1,4}[a-z]?(\s*\.\s*\d+)?$/i.test(t) || /^[\d.\s-]+$/.test(t);
|
||||
};
|
||||
if (tdName && isCodeOnly(tdName)) {
|
||||
const desc = tdTexts.find((t) => t !== tdName && /[a-zA-ZğüşıöçĞÜŞİÖÇ]{3,}/.test(t));
|
||||
if (desc) tdName = `${tdName} ${desc}`.replace(/\s+/g, " ").trim();
|
||||
}
|
||||
|
||||
// Caption may contain HTML-encoded content (e.g. <div class="restrictionBlock"...>)
|
||||
|
||||
Reference in New Issue
Block a user