Files
santifer--career-ops/tests/providers/smartrecruiters.test.mjs
T
wehub-resource-sync d083df1fdb
CodeQL Analysis / Analyze (javascript-typescript) (push) Failing after 2s
Web CI / web typecheck + build (push) Failing after 1s
Release Please / release-please (push) Failing after 1s
CodeQL Analysis / Analyze (go) (push) Failing after 16s
chore: import upstream snapshot with attribution
2026-07-13 12:02:43 +08:00

208 lines
8.6 KiB
JavaScript

// tests/providers/smartrecruiters.test.mjs — moved verbatim from test-all.mjs (#1440).
import { pass, fail, ROOT } from '../helpers.mjs';
import { join } from 'path';
import { pathToFileURL } from 'url';
console.log('\nProvider — smartrecruiters');
try {
const smartrecruitersModule = await import(pathToFileURL(join(ROOT, 'providers/smartrecruiters.mjs')).href);
const sr = smartrecruitersModule.default;
const { parseSmartRecruitersResponse } = smartrecruitersModule;
if (sr.id === 'smartrecruiters') pass('smartrecruiters.id is "smartrecruiters"');
else fail(`smartrecruiters.id is ${JSON.stringify(sr.id)}`);
const hitCareers = sr.detect({ name: 'Adyen', careers_url: 'https://careers.smartrecruiters.com/adyen' });
if (hitCareers && hitCareers.url.startsWith('https://api.smartrecruiters.com/v1/companies/adyen/postings')) {
pass('smartrecruiters.detect() resolves careers.smartrecruiters.com/<slug> → api URL');
} else {
fail(`smartrecruiters.detect(careers) returned ${JSON.stringify(hitCareers)}`);
}
const hitJobs = sr.detect({ name: 'X', careers_url: 'https://jobs.smartrecruiters.com/x' });
if (hitJobs && hitJobs.url.startsWith('https://api.smartrecruiters.com/v1/companies/x/postings')) {
pass('smartrecruiters.detect() also handles jobs.smartrecruiters.com');
} else {
fail(`smartrecruiters.detect(jobs) returned ${JSON.stringify(hitJobs)}`);
}
if (sr.detect({ name: 'X', careers_url: 'https://example.com/careers' }) === null) {
pass('smartrecruiters.detect() returns null for non-SR URLs');
} else {
fail('smartrecruiters.detect() should return null for non-SR URLs');
}
// entry.api precedence: a branded careers_url is kept while the SR slug is
// pinned via api: (mirrors greenhouse/ashby).
const hitApi = sr.detect({
name: 'Continental',
careers_url: 'https://jobs.continental.com',
api: 'https://careers.smartrecruiters.com/Continental',
});
if (hitApi && hitApi.url.startsWith('https://api.smartrecruiters.com/v1/companies/Continental/postings')) {
pass('smartrecruiters.detect() honors api: over a branded careers_url');
} else {
fail(`smartrecruiters.detect(api-pinned) returned ${JSON.stringify(hitApi)}`);
}
// parseSmartRecruitersResponse
const sample = {
content: [
{
id: 'abc-123',
name: 'Senior PM',
ref: 'https://api.smartrecruiters.com/v1/companies/sgs/postings/abc-123',
location: { fullLocation: 'Geneva, Switzerland', remote: false },
},
{
id: 'def-456',
name: 'Remote AI Engineer',
ref: 'https://api.smartrecruiters.com/v1/companies/sgs/postings/def-456',
location: { city: 'Paris', country: 'France', remote: true },
},
{
id: 'ghi-789',
name: 'No-ref Role',
location: { fullLocation: 'Berlin, Germany' },
},
],
};
const jobs = parseSmartRecruitersResponse(sample, 'SGS');
if (jobs.length === 3) pass('parseSmartRecruitersResponse extracts 3 jobs');
else fail(`parseSmartRecruitersResponse returned ${jobs.length} jobs`);
if (jobs[0]?.location === 'Geneva, Switzerland' && jobs[0]?.title === 'Senior PM') {
pass('parseSmartRecruitersResponse uses fullLocation when present');
} else {
fail(`row 0 = ${JSON.stringify(jobs[0])}`);
}
if (jobs[1]?.location === 'Paris, France, Remote') {
pass('parseSmartRecruitersResponse builds location from city/country/remote when no fullLocation');
} else {
fail(`row 1 location = ${JSON.stringify(jobs[1]?.location)}, expected "Paris, France, Remote"`);
}
if (jobs[0]?.url === 'https://jobs.smartrecruiters.com/sgs/postings/abc-123') {
pass('parseSmartRecruitersResponse rewrites api.smartrecruiters.com → jobs.smartrecruiters.com');
} else {
fail(`row 0 url = ${JSON.stringify(jobs[0]?.url)}`);
}
if (jobs[2]?.url && jobs[2].url.startsWith('https://jobs.smartrecruiters.com/sgs/ghi-789')) {
pass('parseSmartRecruitersResponse falls back to synthetic URL when ref is missing');
} else {
fail(`row 2 url = ${JSON.stringify(jobs[2]?.url)}`);
}
// Empty input safety
if (parseSmartRecruitersResponse({}, 'X').length === 0) pass('empty {} input → empty result');
else fail('empty {} input should yield empty result');
if (parseSmartRecruitersResponse({ content: 'not an array' }, 'X').length === 0) {
pass('non-array content → empty result (no crash)');
} else {
fail('non-array content should yield empty result');
}
// careers_url with non-string value → detect() returns null without crashing
if (sr.detect({ name: 'X', careers_url: { foo: 'bar' } }) === null) {
pass('smartrecruiters.detect() returns null for non-string careers_url (object)');
} else {
fail('smartrecruiters.detect() should treat non-string careers_url as missing');
}
// Fallback URL when both ref AND id are missing → empty string (not "undefined" in URL)
const noRefNoId = parseSmartRecruitersResponse(
{ content: [{ name: 'Stranded Role' }] },
'X',
);
if (noRefNoId.length === 1 && noRefNoId[0].url === '') {
pass('parseSmartRecruitersResponse returns url="" when both ref and id are missing');
} else {
fail(`expected url='' when ref+id both missing, got ${JSON.stringify(noRefNoId[0])}`);
}
// SSRF: malicious URL with smartrecruiters hostname in the PATH (not host) must not be detected.
if (sr.detect({ name: 'Spoof', careers_url: 'https://evil.example/careers.smartrecruiters.com/slug' }) === null) {
pass('smartrecruiters.detect() rejects path-spoofed URLs');
} else {
fail('smartrecruiters.detect() must NOT misdetect path-spoofed URLs');
}
// SmartRecruiters: untrusted j.ref host falls through to fallback rather than rewriting
const bogusRef = parseSmartRecruitersResponse(
{ content: [{ id: 'X1', name: 'Strange Role', ref: 'https://evil.example/v1/companies/x/postings/X1' }] },
'TestCo',
);
if (bogusRef[0]?.url && !bogusRef[0].url.includes('evil.example')) {
pass('parseSmartRecruitersResponse rejects untrusted j.ref host (falls through to fallback)');
} else {
fail(`untrusted j.ref leaked into url: ${JSON.stringify(bogusRef[0]?.url)}`);
}
// SmartRecruiters: companyName with spaces/symbols is slugified for the fallback URL
const slugifiedCompany = parseSmartRecruitersResponse(
{ content: [{ id: 'X2', name: 'Strange Role' }] },
'My Acme & Co.',
);
if (slugifiedCompany[0]?.url === 'https://jobs.smartrecruiters.com/my-acme-co/X2-strange-role') {
pass('parseSmartRecruitersResponse slugifies the companyName for the fallback URL');
} else {
fail(`fallback URL not properly slugified: ${JSON.stringify(slugifiedCompany[0]?.url)}`);
}
// Pagination: fetch() loops until an empty page (or short page) is returned
let pageRequests = 0;
const pagedJobs = await sr.fetch(
{ name: 'PagedCo', careers_url: 'https://careers.smartrecruiters.com/paged' },
{
transport: 'http',
fetchText: async () => { throw new Error('fetchText should not be called'); },
fetchJson: async (url) => {
pageRequests++;
const offset = parseInt(new URL(url).searchParams.get('offset') || '0', 10);
if (offset === 0) {
// Page 1: full page (100 items)
return { content: Array.from({ length: 100 }, (_, i) => ({ id: `P1-${i}`, name: `Role 1-${i}` })) };
}
if (offset === 100) {
// Page 2: short page (50 items) → loop stops after this
return { content: Array.from({ length: 50 }, (_, i) => ({ id: `P2-${i}`, name: `Role 2-${i}` })) };
}
// Should not be reached because page 2 was short
return { content: [] };
},
},
);
if (pageRequests === 2 && pagedJobs.length === 150) {
pass('smartrecruiters.fetch() paginates and aggregates results (2 pages → 150 total)');
} else {
fail(`pagination: pageRequests=${pageRequests}, total=${pagedJobs.length} (expected 2 requests / 150 results)`);
}
// Pagination stop condition: empty content terminates the loop
let emptyPageRequests = 0;
const emptyJobs = await sr.fetch(
{ name: 'EmptyCo', careers_url: 'https://careers.smartrecruiters.com/empty' },
{
transport: 'http',
fetchText: async () => { throw new Error('fetchText should not be called'); },
fetchJson: async () => {
emptyPageRequests++;
return { content: [] };
},
},
);
if (emptyPageRequests === 1 && emptyJobs.length === 0) {
pass('smartrecruiters.fetch() stops on the first empty page');
} else {
fail(`empty pagination: requests=${emptyPageRequests}, total=${emptyJobs.length}`);
}
} catch (e) {
fail(`smartrecruiters provider tests crashed: ${e.message}`);
}