Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions __tests__/workers/opportunity/parseOpportunity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,15 +192,17 @@ describe('parseOpportunity worker', () => {
// Verify content
expect(opportunity!.content).toMatchObject({
overview: {
content: 'This is the overview of the mocked opportunity.',
content: '<p>This is the overview of the mocked opportunity.</p>\n',
html: '<p>This is the overview of the mocked opportunity.</p>\n',
},
responsibilities: {
content: 'These are the responsibilities of the mocked opportunity.',
content:
'<p>These are the responsibilities of the mocked opportunity.</p>\n',
html: '<p>These are the responsibilities of the mocked opportunity.</p>\n',
},
requirements: {
content: 'These are the requirements of the mocked opportunity.',
content:
'<p>These are the requirements of the mocked opportunity.</p>\n',
html: '<p>These are the requirements of the mocked opportunity.</p>\n',
},
});
Expand Down
26 changes: 16 additions & 10 deletions src/common/opportunity/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '../../types';
import { getBrokkrClient } from '../brokkr';
import { opportunityCreateParseSchema } from '../schema/opportunities';
import { markdown } from '../markdown';
import { markdown, sanitizeHtml } from '../markdown';
import { OpportunityJob } from '../../entity/opportunities/OpportunityJob';
import { OpportunityLocation } from '../../entity/opportunities/OpportunityLocation';
import { OpportunityKeyword } from '../../entity/OpportunityKeyword';
Expand Down Expand Up @@ -139,25 +139,29 @@ export async function validateOpportunityFileType(

/**
* Renders markdown content for opportunity fields
* Converts markdown to HTML and stores HTML in both content and html fields
*/
function renderOpportunityMarkdownContent(
const renderOpportunityMarkdownContent = async (
content: Record<string, { content?: string }> | undefined,
): OpportunityContent {
): Promise<OpportunityContent> => {
const renderedContent: Record<string, { content: string; html: string }> = {};

Object.entries(content || {}).forEach(([key, value]) => {
for (const [key, value] of Object.entries(content || {})) {
if (typeof value?.content !== 'string') {
return;
continue;
}

const html = markdown.render(value.content);
const sanitizedHtml = await sanitizeHtml(html);

renderedContent[key] = {
content: value.content,
html: markdown.render(value.content),
content: sanitizedHtml,
html: sanitizedHtml,
};
});
}

return new OpportunityContent(renderedContent);
}
};

/**
* Parses an opportunity file using the Brokkr service
Expand Down Expand Up @@ -259,7 +263,9 @@ export async function parseOpportunityWithBrokkr({
const parsedOpportunity =
await opportunityCreateParseSchema.parseAsync(sanitizedOpportunity);

const content = renderOpportunityMarkdownContent(parsedOpportunity.content);
const content = await renderOpportunityMarkdownContent(
parsedOpportunity.content,
);

return {
opportunity: parsedOpportunity,
Expand Down
Loading