Files
santifer--career-ops/tests/providers/recruitee.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

138 lines
6.4 KiB
JavaScript

// tests/providers/recruitee.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 — recruitee');
try {
const recruiteeModule = await import(pathToFileURL(join(ROOT, 'providers/recruitee.mjs')).href);
const recruitee = recruiteeModule.default;
const { parseRecruiteeResponse } = recruiteeModule;
if (recruitee.id === 'recruitee') pass('recruitee.id is "recruitee"');
else fail(`recruitee.id is ${JSON.stringify(recruitee.id)}`);
const hit = recruitee.detect({ name: 'Channable', careers_url: 'https://channable.recruitee.com' });
if (hit && hit.url === 'https://channable.recruitee.com/api/offers/') {
pass('recruitee.detect() resolves <slug>.recruitee.com → api offers');
} else {
fail(`recruitee.detect() returned ${JSON.stringify(hit)}`);
}
if (recruitee.detect({ name: 'X', careers_url: 'https://example.com/careers' }) === null) {
pass('recruitee.detect() returns null for non-recruitee URLs');
} else {
fail('recruitee.detect() should return null for non-recruitee URLs');
}
// parseRecruiteeResponse
const sample = {
offers: [
{ title: 'Senior PM', careers_url: 'https://channable.recruitee.com/o/senior-pm', city: 'Utrecht', country: 'Netherlands', remote: false },
{ title: 'Backend Eng', url: 'https://channable.recruitee.com/o/backend', city: 'Amsterdam', country: 'Netherlands', remote: true },
{ title: 'AI Lead', location: 'Remote, EMEA' },
],
};
const jobs = parseRecruiteeResponse(sample, 'Channable');
if (jobs.length === 3) pass('parseRecruiteeResponse extracts 3 offers');
else fail(`parseRecruiteeResponse returned ${jobs.length} offers`);
if (jobs[0]?.title === 'Senior PM' && jobs[0]?.company === 'Channable' && jobs[0]?.url === 'https://channable.recruitee.com/o/senior-pm') {
pass('parseRecruiteeResponse prefers careers_url field over url');
} else {
fail(`row 0 = ${JSON.stringify(jobs[0])}`);
}
if (jobs[1]?.location === 'Amsterdam, Netherlands, Remote') {
pass('parseRecruiteeResponse assembles city/country/remote when no location field');
} else {
fail(`row 1 location = ${JSON.stringify(jobs[1]?.location)}, expected "Amsterdam, Netherlands, Remote"`);
}
if (jobs[2]?.location === 'Remote, EMEA') {
pass('parseRecruiteeResponse uses explicit location field when present');
} else {
fail(`row 2 location = ${JSON.stringify(jobs[2]?.location)}`);
}
if (parseRecruiteeResponse({}, 'X').length === 0) pass('empty {} → empty result');
else fail('empty {} should yield empty result');
if (parseRecruiteeResponse({ offers: null }, 'X').length === 0) {
pass('null offers → empty result (no crash)');
} else {
fail('null offers should yield empty result');
}
// careers_url with non-string value → detect() returns null without crashing
if (recruitee.detect({ name: 'X', careers_url: null }) === null && recruitee.detect({ name: 'X', careers_url: 7 }) === null) {
pass('recruitee.detect() returns null for non-string careers_url (null and 7)');
} else {
fail('recruitee.detect() should treat non-string careers_url as missing');
}
// SSRF: malicious URL with recruitee.com in the PATH (not host) must not be detected.
if (recruitee.detect({ name: 'Spoof', careers_url: 'https://evil.example/channable.recruitee.com/foo' }) === null) {
pass('recruitee.detect() rejects path-spoofed URLs');
} else {
fail('recruitee.detect() must NOT misdetect path-spoofed URLs');
}
// Per-offer URL validation: custom-domain https URLs are KEPT (Recruitee
// tenants serve postings on their own domain, e.g. careers.hostaway.com);
// only non-https and malformed/missing URLs are dropped. The per-offer URL
// is display-only and not host-locked to *.recruitee.com — see #recruitee.
const offerUrlOffers = parseRecruiteeResponse(
{
offers: [
{ title: 'Recruitee domain', careers_url: 'https://channable.recruitee.com/o/good' },
{ title: 'Custom domain', careers_url: 'https://careers.hostaway.com/o/senior-backend' },
{ title: 'Insecure', careers_url: 'http://channable.recruitee.com/o/insecure' },
{ title: 'No URL field' },
],
},
'Channable',
);
if (offerUrlOffers[0]?.url === 'https://channable.recruitee.com/o/good' && offerUrlOffers[1]?.url === 'https://careers.hostaway.com/o/senior-backend' && offerUrlOffers[2]?.url === '' && offerUrlOffers[3]?.url === '') {
pass('parseRecruiteeResponse keeps custom-domain https URLs, drops non-https and missing');
} else {
fail(`URL validation: row0=${JSON.stringify(offerUrlOffers[0]?.url)}, row1=${JSON.stringify(offerUrlOffers[1]?.url)}, row2=${JSON.stringify(offerUrlOffers[2]?.url)}, row3=${JSON.stringify(offerUrlOffers[3]?.url)}`);
}
// fetch() — derives the API URL, forwards the SSRF guard (redirect:'error'),
// and returns parsed offers.
let fetchedUrl = null;
let fetchedOpts = null;
const fetchJobs = await recruitee.fetch(
{ name: 'Channable', careers_url: 'https://channable.recruitee.com/' },
{ fetchJson: async (url, opts) => { fetchedUrl = url; fetchedOpts = opts; return { offers: [{ title: 'Senior PM', careers_url: 'https://channable.recruitee.com/o/senior-pm' }] }; } },
);
if (fetchedUrl === 'https://channable.recruitee.com/api/offers/' && fetchedOpts?.redirect === 'error' && fetchJobs.length === 1) {
pass('recruitee.fetch() hits /api/offers/ with redirect:"error" and returns parsed offers');
} else {
fail(`recruitee.fetch() url=${JSON.stringify(fetchedUrl)} opts=${JSON.stringify(fetchedOpts)} jobs=${fetchJobs.length}`);
}
// fetch() refuses entries whose careers_url can't derive a trusted
// <slug>.recruitee.com API URL — the guard chain must run before any request.
try {
await recruitee.fetch(
{ name: 'Evil', careers_url: 'https://evil.example.com/careers' },
{ fetchJson: async () => { throw new Error('must not be called'); } },
);
fail('recruitee.fetch() should throw for an untrusted careers_url');
} catch (e) {
if (/cannot derive API URL for Evil/.test(e.message)) {
pass('recruitee.fetch() throws before fetching when the host is untrusted');
} else {
fail(`recruitee.fetch() threw the wrong error: ${e.message}`);
}
}
} catch (e) {
fail(`recruitee provider tests crashed: ${e.message}`);
}