Jobber/shared/src/testing/factories.ts
Shaheer Sarfaraz 7514aa1b28
Add RxResume v4/v5 dual support (#230)
* feat(settings): add rxresume mode and v5 api key settings

* feat(server): add mode-aware rxresume adapter with auto v5-first selection

* refactor(server): route settings profile and pdf generation through rxresume adapter

* feat(api): support rxresume v4/v5 in onboarding and settings routes with ok/meta responses

* feat(client): add rxresume mode selector and v5 api key setup flow

* docs: document rxresume auto mode with v5-first self-hosted setup

* test: verify dual-mode rxresume support and ci parity checks

* comments

* services folder

* correct types for v5

* tests and docs fix

* Fix RxResume auto fallback and route API consistency

* warning for both being set

* simpler response

* onboarding component improvements, v5 check still not working

* fix list resume endpoint...

* fix api endpoints to latest v5 docs

* don't show the entire project field on v5

* remove auto entirely

* formatting

* ci green

* v5 has a different resume schema

* remove redundant check

* remove requirement that only one must be specified

* consolidate sections

* base resume can be v4 or v5

* saving now works

* status indicator

* actually render some pills

* reason for failure

* fix apikey verification

* dedupe isValidatingMode

* reefactoor

* simplification?

* refactor?

* ci passing

* remove auto from docs

* tailoring is schema dependent

* skills object tighter

* remove redundant text

* fix lint

* mode
2026-02-25 02:26:15 +00:00

207 lines
5.5 KiB
TypeScript

import type {
ApplicationTask,
AppSettings,
Job,
PipelineRun,
ResumeProjectCatalogItem,
StageEvent,
} from "../types";
export const createJob = (overrides: Partial<Job> = {}): Job => ({
id: "job-1",
source: "linkedin",
sourceJobId: null,
jobUrlDirect: null,
datePosted: null,
title: "Backend Engineer",
employer: "Acme Labs",
employerUrl: null,
jobUrl: "https://example.com/job-1",
applicationLink: "https://example.com/apply",
disciplines: null,
deadline: null,
salary: null,
location: "California",
degreeRequired: null,
starting: null,
jobDescription: "Job description content",
status: "ready",
outcome: null,
closedAt: null,
suitabilityScore: 90,
suitabilityReason: "Strong fit",
tailoredSummary: null,
tailoredHeadline: null,
tailoredSkills: null,
selectedProjectIds: null,
pdfPath: null,
tracerLinksEnabled: false,
sponsorMatchScore: null,
sponsorMatchNames: null,
jobType: null,
salarySource: null,
salaryInterval: null,
salaryMinAmount: null,
salaryMaxAmount: null,
salaryCurrency: null,
isRemote: null,
jobLevel: null,
jobFunction: null,
listingType: null,
emails: null,
companyIndustry: null,
companyLogo: null,
companyUrlDirect: null,
companyAddresses: null,
companyNumEmployees: null,
companyRevenue: null,
companyDescription: null,
skills: null,
experienceRange: null,
companyRating: null,
companyReviewsCount: null,
vacancyCount: null,
workFromHomeType: null,
discoveredAt: "2025-01-01T00:00:00Z",
processedAt: null,
appliedAt: null,
createdAt: "2025-01-01T00:00:00Z",
updatedAt: "2025-01-01T00:00:00Z",
...overrides,
});
export const createStageEvent = (
overrides: Partial<StageEvent> = {},
): StageEvent => ({
id: "event-1",
applicationId: "job-1",
title: "Moved to applied",
groupId: null,
fromStage: null,
toStage: "applied",
occurredAt: Date.now(),
metadata: null,
outcome: null,
...overrides,
});
export const createApplicationTask = (
overrides: Partial<ApplicationTask> = {},
): ApplicationTask => ({
id: "task-1",
applicationId: "job-1",
type: "todo",
title: "Follow up",
dueDate: null,
isCompleted: false,
notes: null,
...overrides,
});
export const createPipelineRun = (
overrides: Partial<PipelineRun> = {},
): PipelineRun => ({
id: "run-1",
startedAt: "2025-01-01T00:00:00Z",
completedAt: null,
status: "running",
jobsDiscovered: 0,
jobsProcessed: 0,
errorMessage: null,
...overrides,
});
export const createResumeProjectCatalogItem = (
overrides: Partial<ResumeProjectCatalogItem> = {},
): ResumeProjectCatalogItem => ({
id: "p1",
name: "Project 1",
description: "Description 1",
date: "2024",
isVisibleInBase: true,
...overrides,
});
export const createAppSettings = (
overrides: Partial<AppSettings> = {},
): AppSettings => ({
model: { value: "gpt-4o", default: "gpt-4o", override: null },
modelScorer: { value: "gpt-4o", override: null },
modelTailoring: { value: "gpt-4o", override: null },
modelProjectSelection: { value: "gpt-4o", override: null },
llmProvider: { value: "openai", default: "openai", override: null },
llmBaseUrl: {
value: "https://api.openai.com/v1",
default: "https://api.openai.com/v1",
override: null,
},
pipelineWebhookUrl: { value: "", default: "", override: null },
jobCompleteWebhookUrl: { value: "", default: "", override: null },
profileProjects: [],
resumeProjects: {
value: { maxProjects: 3, lockedProjectIds: [], aiSelectableProjectIds: [] },
default: {
maxProjects: 3,
lockedProjectIds: [],
aiSelectableProjectIds: [],
},
override: null,
},
rxresumeBaseResumeId: null,
rxresumeBaseResumeIdV4: null,
rxresumeBaseResumeIdV5: null,
ukvisajobsMaxJobs: { value: 50, default: 50, override: null },
adzunaMaxJobsPerTerm: { value: 50, default: 50, override: null },
gradcrackerMaxJobsPerTerm: { value: 50, default: 50, override: null },
searchTerms: {
value: ["Software Engineer"],
default: ["Software Engineer"],
override: null,
},
blockedCompanyKeywords: {
value: [],
default: [],
override: null,
},
searchCities: {
value: "United Kingdom",
default: "United Kingdom",
override: null,
},
jobspyResultsWanted: { value: 20, default: 20, override: null },
jobspyCountryIndeed: {
value: "united kingdom",
default: "united kingdom",
override: null,
},
showSponsorInfo: { value: true, default: true, override: null },
chatStyleTone: {
value: "professional",
default: "professional",
override: null,
},
chatStyleFormality: { value: "medium", default: "medium", override: null },
chatStyleConstraints: { value: "", default: "", override: null },
chatStyleDoNotUse: { value: "", default: "", override: null },
llmApiKeyHint: null,
rxresumeApiKeyHint: null,
rxresumeEmail: null,
rxresumePasswordHint: null,
basicAuthUser: null,
basicAuthPasswordHint: null,
ukvisajobsEmail: null,
ukvisajobsPasswordHint: null,
adzunaAppId: null,
adzunaAppKeyHint: null,
webhookSecretHint: null,
basicAuthActive: false,
backupEnabled: { value: false, default: false, override: null },
backupHour: { value: 3, default: 3, override: null },
backupMaxCount: { value: 7, default: 7, override: null },
penalizeMissingSalary: { value: false, default: false, override: null },
missingSalaryPenalty: { value: 10, default: 10, override: null },
autoSkipScoreThreshold: { value: null, default: null, override: null },
rxresumeMode: { value: "v5", default: "v5", override: null },
...overrides,
});