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

209 lines
8.2 KiB
JavaScript

// tests/providers/glints.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 — glints');
try {
const glintsModule = await import(pathToFileURL(join(ROOT, 'providers/glints.mjs')).href);
const glints = glintsModule.default;
const { parseGlintsItem } = glintsModule;
// id check
if (glints.id === 'glints') pass('glints.id is "glints"');
else fail(`glints.id is ${JSON.stringify(glints.id)}`);
// detect() always returns null (job board, not ATS)
if (glints.detect({ name: 'X', careers_url: 'https://glints.com/id/jobs' }) === null) {
pass('glints.detect() returns null — explicit provider only, no URL auto-detection');
} else {
fail('glints.detect() should return null for any URL');
}
// parseGlintsItem — valid item (new searchJobsV3 shape)
const sampleItem = {
id: 'abc123',
title: 'Backend Engineer',
company: { name: 'StartupCorp', brandName: 'StartupCorp Brand' },
city: { name: 'Jakarta, Indonesia' },
country: { code: 'ID', name: 'Indonesia' },
createdAt: '2026-06-10T00:00:00Z',
};
const parsed = parseGlintsItem(sampleItem, 'https://glints.com', 'FallbackCo');
if (parsed && parsed.title === 'Backend Engineer'
&& parsed.url === 'https://glints.com/id/opportunities/jobs/abc123'
&& parsed.company === 'StartupCorp'
&& parsed.location === 'Jakarta, Indonesia'
&& parsed.postedAt != null) {
pass('parseGlintsItem extracts title, url, company, location, postedAt correctly');
} else {
fail(`parseGlintsItem returned ${JSON.stringify(parsed)}`);
}
// parseGlintsItem — uses brandName when name is absent
const brandItem = {
id: 'def456',
title: 'Data Scientist',
company: { brandName: 'BrandCorp' },
city: { name: 'Singapore' },
createdAt: '2026-06-15T00:00:00Z',
};
const brandParsed = parseGlintsItem(brandItem, 'https://glints.com', 'FallbackCo');
if (brandParsed && brandParsed.company === 'BrandCorp') {
pass('parseGlintsItem falls back to brandName when company.name is missing');
} else {
fail(`parseGlintsItem brandName fallback: ${JSON.stringify(brandParsed)}`);
}
// parseGlintsItem — rejects items without title
if (parseGlintsItem({ id: '1' }, 'https://glints.com', 'Co') === null) {
pass('parseGlintsItem returns null for title-less items');
} else {
fail('parseGlintsItem should return null for items without title');
}
// parseGlintsItem — rejects items without id (URL cannot be built)
if (parseGlintsItem({ title: 'Role' }, 'https://glints.com', 'Co') === null) {
pass('parseGlintsItem returns null for items without id');
} else {
fail('parseGlintsItem should return null for items without id');
}
// parseGlintsItem — rejects off-domain via URL validation
const offDomain = parseGlintsItem(
{ id: '1', title: 'Role' },
'https://evil.example.com', 'Co'
);
if (offDomain === null) pass('parseGlintsItem rejects off-domain base URLs');
else fail(`parseGlintsItem should reject off-domain base URLs, got ${JSON.stringify(offDomain)}`);
// parseGlintsItem — handles null/malformed input
if (parseGlintsItem(null, 'https://glints.com', 'Co') === null) pass('parseGlintsItem(null) → null');
else fail('parseGlintsItem(null) should return null');
if (parseGlintsItem(42, 'https://glints.com', 'Co') === null) pass('parseGlintsItem(number) → null');
else fail('parseGlintsItem(number) should return null');
// parseGlintsItem — fallback company when both company.name and brandName are missing
const noCompany = parseGlintsItem(
{ id: '99', title: 'Engineer' },
'https://glints.com', 'PortalName'
);
if (noCompany && noCompany.company === 'PortalName') {
pass('parseGlintsItem uses fallback company when company info is absent');
} else {
fail(`parseGlintsItem fallback company: ${JSON.stringify(noCompany)}`);
}
// parseGlintsItem — parseGlintsItem allows www.glints.com subdomain via baseUrl
const wwwItem = parseGlintsItem(
{ id: 'x', title: 'Role' },
'https://www.glints.com', 'Co'
);
if (wwwItem && wwwItem.url.startsWith('https://www.glints.com/')) {
pass('parseGlintsItem accepts www.glints.com base URL (subdomain)');
} else {
fail(`parseGlintsItem www subdomain: ${JSON.stringify(wwwItem)}`);
}
// fetch() — happy path with mock context (searchJobsV3 response shape)
const mockCtx = {
transport: 'http',
fetchJson: async (url, opts) => {
if (opts?.method !== 'POST') throw new Error('Expected POST');
const body = JSON.parse(opts.body || '{}');
if (!body.query) throw new Error('Expected GraphQL query');
if (body.operationName !== 'searchJobsV3') throw new Error('Expected searchJobsV3 operation');
return {
data: {
searchJobsV3: {
jobsInPage: [
{
id: 'job1',
title: 'AI PM',
company: { name: 'TechCo', brandName: 'TechCo Brand' },
city: { name: 'Remote' },
country: { code: 'ID', name: 'Indonesia' },
salaries: [],
createdAt: '2026-01-01T00:00:00Z',
},
],
expInfo: null,
hasMore: false,
},
},
};
},
fetchText: async () => { throw new Error('should not be called'); },
};
const jobs = await glints.fetch(
{ name: 'Glints ID', provider: 'glints', searchKeywords: 'AI' },
mockCtx,
);
if (jobs.length === 1 && jobs[0].title === 'AI PM') pass('glints.fetch() returns parsed jobs via searchJobsV3');
else fail(`glints.fetch() returned ${JSON.stringify(jobs)}`);
// fetch() — handles empty results
const emptyCtx = {
transport: 'http',
fetchJson: async () => ({ data: { searchJobsV3: { jobsInPage: [], hasMore: false } } }),
fetchText: async () => { throw new Error('should not be called'); },
};
const emptyJobs = await glints.fetch(
{ name: 'Glints ID', provider: 'glints', searchKeywords: 'nonexistent' },
emptyCtx,
);
if (emptyJobs.length === 0) pass('glints.fetch() handles empty results');
else fail(`glints.fetch() should return empty array for no results, got ${emptyJobs.length}`);
// fetch() — stops when hasMore is false (single page)
const singlePageCtx = {
transport: 'http',
fetchJson: async () => ({ data: { searchJobsV3: { jobsInPage: [{ id: '1', title: 'Dev' }], hasMore: false } } }),
fetchText: async () => { throw new Error('should not be called'); },
};
const singleJobs = await glints.fetch(
{ name: 'Glints ID', provider: 'glints', searchKeywords: 'dev' },
singlePageCtx,
);
if (singleJobs.length === 1) pass('glints.fetch() stops when hasMore is false');
else fail(`glints.fetch() single page: ${JSON.stringify(singleJobs)}`);
// fetch() — rejects invalid hostname
let hostRejected = false;
try {
await glints.fetch(
{ name: 'Bad', provider: 'glints', api: 'https://evil.example.com/graphql' },
{ transport: 'http', fetchJson: async () => ({}), fetchText: async () => '' },
);
} catch (e) {
if (e.message.includes('untrusted hostname')) hostRejected = true;
else fail(`glints.fetch() host rejection wrong error: ${e.message}`);
}
if (hostRejected) pass('glints.fetch() rejects untrusted hostnames');
else fail('glints.fetch() should reject non-glints hostnames');
// fetch() — throws on missing searchJobsV3 in response
let missingThrew = false;
try {
await glints.fetch(
{ name: 'Glints ID', provider: 'glints', searchKeywords: 'test' },
{
transport: 'http',
fetchJson: async () => ({ data: { somethingElse: [] } }),
fetchText: async () => { throw new Error('should not be called'); },
},
);
} catch (e) {
if (e.message.includes('unexpected API response')) missingThrew = true;
else fail(`glints.fetch() missing searchJobsV3 wrong error: ${e.message}`);
}
if (missingThrew) pass('glints.fetch() throws on unexpected API response shape');
else fail('glints.fetch() should throw when searchJobsV3 is missing');
} catch (e) {
fail(`glints provider tests crashed: ${e.message}`);
}