Hotfix location in pipeline search (#108)

* feat(shared): centralize supported country list and source-country rules

* feat(orchestrator): add country selector and UK-only source gating in automatic run modal

* feat(orchestrator): persist country selection and run only compatible extractors

* fix(pipeline): enforce country-source compatibility during discovery

* test(orchestrator): cover country-based source gating and pipeline enforcement

* formatting

* test fix

* lint

* comments

* prevent auto focus grab

* verification

* command and popover

* make sure scroll is working
This commit is contained in:
Shaheer Sarfaraz
2026-02-08 13:02:52 +00:00
committed by GitHub
parent 9b80c2e05d
commit bd6834f99e
20 changed files with 2156 additions and 974 deletions
+1
View File
@@ -1,2 +1,3 @@
export * from "./location-support";
export * from "./types";
export * from "./utils/type-conversion";
+62
View File
@@ -0,0 +1,62 @@
import { describe, expect, it } from "vitest";
import {
formatCountryLabel,
getCompatibleSourcesForCountry,
isSourceAllowedForCountry,
isUkCountry,
normalizeCountryKey,
SUPPORTED_COUNTRY_KEYS,
} from "./location-support";
describe("location-support", () => {
it("normalizes country aliases", () => {
expect(normalizeCountryKey("UK")).toBe("united kingdom");
expect(normalizeCountryKey("us")).toBe("united states");
expect(normalizeCountryKey("usa")).toBe("united states");
expect(normalizeCountryKey("czech republic")).toBe("czechia");
});
it("formats country labels", () => {
expect(formatCountryLabel("united kingdom")).toBe("United Kingdom");
expect(formatCountryLabel("usa/ca")).toBe("USA/CA");
expect(formatCountryLabel("south korea")).toBe("South Korea");
});
it("keeps supported country keys unique and canonical", () => {
expect(SUPPORTED_COUNTRY_KEYS).toContain("united kingdom");
expect(SUPPORTED_COUNTRY_KEYS).toContain("united states");
expect(SUPPORTED_COUNTRY_KEYS).toContain("worldwide");
expect(SUPPORTED_COUNTRY_KEYS).not.toContain("uk");
expect(SUPPORTED_COUNTRY_KEYS).not.toContain("us");
});
it("treats only united kingdom as UK country", () => {
expect(isUkCountry("united kingdom")).toBe(true);
expect(isUkCountry("UK")).toBe(true);
expect(isUkCountry("worldwide")).toBe(false);
expect(isUkCountry("usa/ca")).toBe(false);
expect(isUkCountry("united states")).toBe(false);
});
it("applies source compatibility rules by country", () => {
expect(isSourceAllowedForCountry("gradcracker", "united kingdom")).toBe(
true,
);
expect(isSourceAllowedForCountry("ukvisajobs", "uk")).toBe(true);
expect(isSourceAllowedForCountry("gradcracker", "united states")).toBe(
false,
);
expect(isSourceAllowedForCountry("ukvisajobs", "worldwide")).toBe(false);
expect(isSourceAllowedForCountry("indeed", "united states")).toBe(true);
expect(isSourceAllowedForCountry("linkedin", "worldwide")).toBe(true);
});
it("filters incompatible sources while preserving compatible order", () => {
expect(
getCompatibleSourcesForCountry(
["gradcracker", "indeed", "ukvisajobs", "linkedin"],
"united states",
),
).toEqual(["indeed", "linkedin"]);
});
});
+141
View File
@@ -0,0 +1,141 @@
import type { JobSource } from "./types";
const COUNTRY_ALIASES: Record<string, string> = {
uk: "united kingdom",
us: "united states",
usa: "united states",
türkiye: "turkey",
"czech republic": "czechia",
};
const COUNTRY_LABELS: Record<string, string> = {
"united kingdom": "United Kingdom",
"united states": "United States",
"usa/ca": "USA/CA",
turkey: "Turkey",
czechia: "Czechia",
};
// Keep this list aligned with the JobSpy supported country inputs.
export const SUPPORTED_COUNTRY_INPUTS = [
"argentina",
"australia",
"austria",
"bahrain",
"bangladesh",
"belgium",
"bulgaria",
"brazil",
"canada",
"chile",
"china",
"colombia",
"costa rica",
"croatia",
"cyprus",
"czech republic",
"czechia",
"denmark",
"ecuador",
"egypt",
"estonia",
"finland",
"france",
"germany",
"greece",
"hong kong",
"hungary",
"india",
"indonesia",
"ireland",
"israel",
"italy",
"japan",
"kuwait",
"latvia",
"lithuania",
"luxembourg",
"malaysia",
"malta",
"mexico",
"morocco",
"netherlands",
"new zealand",
"nigeria",
"norway",
"oman",
"pakistan",
"panama",
"peru",
"philippines",
"poland",
"portugal",
"qatar",
"romania",
"saudi arabia",
"singapore",
"slovakia",
"slovenia",
"south africa",
"south korea",
"spain",
"sweden",
"switzerland",
"taiwan",
"thailand",
"türkiye",
"turkey",
"ukraine",
"united arab emirates",
"uk",
"united kingdom",
"usa",
"us",
"united states",
"uruguay",
"venezuela",
"vietnam",
"usa/ca",
"worldwide",
] as const;
const UK_ONLY_SOURCES = new Set<JobSource>(["gradcracker", "ukvisajobs"]);
export function normalizeCountryKey(value: string | null | undefined): string {
const normalized = value?.trim().toLowerCase() ?? "";
return COUNTRY_ALIASES[normalized] ?? normalized;
}
export function formatCountryLabel(value: string): string {
const normalized = normalizeCountryKey(value);
if (!normalized) return "";
return (
COUNTRY_LABELS[normalized] ||
normalized.replace(/\b\w/g, (char) => char.toUpperCase())
);
}
export const SUPPORTED_COUNTRY_KEYS = Array.from(
new Set(
SUPPORTED_COUNTRY_INPUTS.map((country) => normalizeCountryKey(country)),
),
).filter(Boolean);
export function isUkCountry(country: string | null | undefined): boolean {
return normalizeCountryKey(country) === "united kingdom";
}
export function isSourceAllowedForCountry(
source: JobSource,
country: string | null | undefined,
): boolean {
if (!UK_ONLY_SOURCES.has(source)) return true;
return isUkCountry(country);
}
export function getCompatibleSourcesForCountry(
sources: JobSource[],
country: string | null | undefined,
): JobSource[] {
return sources.filter((source) => isSourceAllowedForCountry(source, country));
}