Add startup.jobs extractor support (#279)

* Add startup.jobs extractor support

* Harden startup.jobs extractor inputs

* Wire startupjobs into Docker and CI

* Tighten startupjobs review follow-ups

* fix: publish ghcr during release workflow

* feat: add startupjobs max jobs configuration and update related tests
This commit is contained in:
Shaheer Sarfaraz
2026-03-17 12:20:45 +00:00
committed by GitHub
parent 26275e4ee8
commit 71e640b563
28 changed files with 1177 additions and 132 deletions
@@ -0,0 +1,38 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("../src/run", () => ({
runStartupJobs: vi.fn(),
}));
describe("startupjobs manifest", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("prefers startupjobsMaxJobsPerTerm when provided", async () => {
const { manifest } = await import("../src/manifest");
const { runStartupJobs } = await import("../src/run");
const runStartupJobsMock = vi.mocked(runStartupJobs);
runStartupJobsMock.mockResolvedValue({
success: true,
jobs: [],
});
await manifest.run({
source: "startupjobs",
selectedSources: ["startupjobs"],
settings: {
startupjobsMaxJobsPerTerm: "70",
jobspyResultsWanted: "30",
},
searchTerms: ["software engineer"],
selectedCountry: "united kingdom",
});
expect(runStartupJobsMock).toHaveBeenCalledWith(
expect.objectContaining({
maxJobsPerTerm: 70,
}),
);
});
});
+75
View File
@@ -0,0 +1,75 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("startup-jobs-scraper", () => ({
scrapeStartupJobsViaAlgolia: vi.fn(),
}));
describe("runStartupJobs", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("falls back to the default max jobs per term when options.maxJobsPerTerm is NaN", async () => {
const { scrapeStartupJobsViaAlgolia } = await import(
"startup-jobs-scraper"
);
const scrapeMock = vi.mocked(scrapeStartupJobsViaAlgolia);
scrapeMock.mockResolvedValueOnce([]);
const { runStartupJobs } = await import("../src/run");
await runStartupJobs({
searchTerms: ["backend engineer"],
maxJobsPerTerm: Number.NaN,
});
expect(scrapeMock).toHaveBeenCalledWith(
expect.objectContaining({
requestedCount: 50,
}),
);
});
it("drops broad location sentinels and falls back to selectedCountry behavior", async () => {
const { scrapeStartupJobsViaAlgolia } = await import(
"startup-jobs-scraper"
);
const scrapeMock = vi.mocked(scrapeStartupJobsViaAlgolia);
scrapeMock.mockResolvedValueOnce([]);
const { runStartupJobs } = await import("../src/run");
await runStartupJobs({
searchTerms: ["platform engineer"],
selectedCountry: "worldwide",
locations: ["Worldwide"],
});
expect(scrapeMock).toHaveBeenCalledWith(
expect.objectContaining({
location: undefined,
}),
);
});
it("normalizes explicit city-country aliases before passing location to the scraper", async () => {
const { scrapeStartupJobsViaAlgolia } = await import(
"startup-jobs-scraper"
);
const scrapeMock = vi.mocked(scrapeStartupJobsViaAlgolia);
scrapeMock.mockResolvedValueOnce([]);
const { runStartupJobs } = await import("../src/run");
await runStartupJobs({
searchTerms: ["software engineer"],
locations: ["UK"],
});
expect(scrapeMock).toHaveBeenCalledWith(
expect.objectContaining({
location: "United Kingdom",
}),
);
});
});