Add structured CV editor to profile page
This commit is contained in:
@@ -22,6 +22,37 @@ jest.mock('./components/CropImageDialog', () => () => null);
|
||||
|
||||
const mockedApi = api as jest.Mocked<typeof api>;
|
||||
|
||||
const structuredCv = {
|
||||
version: '1',
|
||||
contact: {
|
||||
fullName: 'Demo User',
|
||||
headline: 'Backend Developer',
|
||||
email: 'demo@example.com',
|
||||
},
|
||||
summary: ['Built backend systems'],
|
||||
jobs: [
|
||||
{
|
||||
title: 'System Developer',
|
||||
company: 'Demo Co',
|
||||
location: 'Oslo',
|
||||
start: '2020',
|
||||
end: '2024',
|
||||
isCurrent: false,
|
||||
bullets: ['Built backend systems'],
|
||||
skills: ['.NET', 'SQL'],
|
||||
},
|
||||
],
|
||||
education: [],
|
||||
skills: ['.NET', 'SQL'],
|
||||
languages: [{ name: 'English', level: 'Native' }],
|
||||
interests: ['Cooking'],
|
||||
otherSections: [],
|
||||
sections: [
|
||||
{ name: 'Professional Summary', content: 'Built backend systems', wordCount: 3 },
|
||||
{ name: 'Skills', content: '.NET\nSQL', wordCount: 2 },
|
||||
],
|
||||
};
|
||||
|
||||
function renderPage() {
|
||||
return render(
|
||||
<ToastProvider>
|
||||
@@ -44,9 +75,7 @@ beforeEach(() => {
|
||||
lastName: 'User',
|
||||
displayName: 'Demo User',
|
||||
profileCvText: 'Professional Summary\nBuilt backend systems',
|
||||
profileCvStructureJson: JSON.stringify([
|
||||
{ name: 'Professional Summary', content: 'Built backend systems', wordCount: 3 },
|
||||
]),
|
||||
profileCvStructureJson: JSON.stringify(structuredCv),
|
||||
googleLink: { linked: false },
|
||||
},
|
||||
} as any);
|
||||
@@ -57,10 +86,14 @@ beforeEach(() => {
|
||||
if (url === '/profile-cv/parse') {
|
||||
return Promise.resolve({
|
||||
data: {
|
||||
sections: [
|
||||
{ name: 'Professional Summary', content: 'Built backend systems', wordCount: 3 },
|
||||
{ name: 'Core Skills', content: '.NET\nSQL\nAzure', wordCount: 3 },
|
||||
],
|
||||
structuredCv: {
|
||||
...structuredCv,
|
||||
sections: [
|
||||
{ name: 'Professional Summary', content: 'Built backend systems', wordCount: 3 },
|
||||
{ name: 'Core Skills', content: '.NET\nSQL\nAzure', wordCount: 3 },
|
||||
],
|
||||
skills: ['.NET', 'SQL', 'Azure'],
|
||||
},
|
||||
},
|
||||
} as any);
|
||||
}
|
||||
@@ -74,12 +107,14 @@ afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('profile page loads persisted cv sections and can re-parse them', async () => {
|
||||
test('profile page loads persisted structured cv and can re-parse it', async () => {
|
||||
renderPage();
|
||||
|
||||
expect(await screen.findByText(/cv ready/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/cv structure overview/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/structured cv editor/i)).toBeInTheDocument();
|
||||
expect(screen.getAllByText(/professional summary/i).length).toBeGreaterThan(0);
|
||||
expect(screen.getByLabelText(/full name/i)).toHaveValue('Demo User');
|
||||
|
||||
const analyzeButton = screen.getByRole('button', { name: /analyze sections/i });
|
||||
await waitFor(() => expect(analyzeButton).toBeEnabled());
|
||||
@@ -89,22 +124,27 @@ test('profile page loads persisted cv sections and can re-parse them', async ()
|
||||
expect(mockedApi.post).toHaveBeenCalledWith('/profile-cv/parse', { text: 'Professional Summary\nBuilt backend systems' });
|
||||
});
|
||||
|
||||
expect(await screen.findByText(/core skills/i)).toBeInTheDocument();
|
||||
expect(screen.getAllByText(/core skills/i).length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('saving profile persists structured cv json', async () => {
|
||||
renderPage();
|
||||
|
||||
expect(await screen.findByText(/cv ready/i)).toBeInTheDocument();
|
||||
const fullNameInput = screen.getByLabelText(/full name/i);
|
||||
fireEvent.change(fullNameInput, { target: { value: 'Updated Demo User' } });
|
||||
|
||||
const saveButton = screen.getByRole('button', { name: /save changes/i });
|
||||
await waitFor(() => expect(saveButton).toBeEnabled());
|
||||
fireEvent.click(saveButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockedApi.put).toHaveBeenCalledWith('/auth/profile', expect.objectContaining({
|
||||
profileCvStructureJson: JSON.stringify([
|
||||
{ name: 'Professional Summary', content: 'Built backend systems', wordCount: 3 },
|
||||
]),
|
||||
}));
|
||||
expect(mockedApi.put).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
const payload = mockedApi.put.mock.calls[0][1] as any;
|
||||
const parsed = JSON.parse(payload.profileCvStructureJson);
|
||||
expect(parsed.contact.fullName).toBe('Updated Demo User');
|
||||
expect(parsed.skills).toEqual(['.NET', 'SQL']);
|
||||
expect(parsed.jobs[0].title).toBe('System Developer');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user