Skip to content

Commit

Permalink
Merge branch 'development' into task/run-contentful-tests-on-pr
Browse files Browse the repository at this point in the history
  • Loading branch information
DrewAire authored Feb 27, 2025
2 parents b7a3c9f + 9be84c6 commit a2f755d
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 2 deletions.
1 change: 1 addition & 0 deletions contentful/export-processor/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ OUTPUT_FILE_DIR="./output/"

#If true, will save user journey path information for subtopics
EXPORT_USER_JOURNEY_PATHS="true"

#If true, will export ALL possible user journey paths per subtopic for the above
EXPORT_ALL_PATHS="false"

Expand Down
1 change: 1 addition & 0 deletions contentful/export-processor/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ content-errors*.md
plan-tech-test-suite*.csv
output/
inserted-groups.json
csv-test.csv

#Env variables
.env
Expand Down
16 changes: 15 additions & 1 deletion contentful/export-processor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,18 @@ DELIVERY_TOKEN
USE_PREVIEW
SPACE_ID
ENVIRONMENT
FUNCTION_APP_URL
FUNCTION_APP_URL


## Recommendations Exporter

[recommmendations_csv_outputter.js](/src/contentful/export-processor/recommendations_csv_outputter.js) exports data from Contentful (uses the exporter) and generates a .csv in the output directory with the recommendations attached to each answer and a link to view on staging:

### Usage

The recommendations exporter does not need any additional environment variables. It relies on the data-exporter so ensure you have those required environment variables.

3. Run `npm run export-recommendations-csv` to run the script.

You may need to add the following parameter infront of the script in package.json (--max-old-space-size=9000) [`"export-recommendations-csv": "node --max-old-space-size=9000 recommendations_csv_outputter.js"`]

15 changes: 15 additions & 0 deletions contentful/export-processor/helpers/slugify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const matchNonAlphanumericExceptHyphensRegex = /[^a-zA-Z0-9-]/g;
const matchWhitespaceCharactersRegex = /\s/g;

/**
* Slugify text. Should match the implementation in /src/Dfe.PlanTech.Domain/Extensions/StringHelpers.cs
* @param {*} text
*/
const slugify = (text) =>
text
.trim()
.replace(matchWhitespaceCharactersRegex, "-")
.replace(matchNonAlphanumericExceptHyphensRegex, "")
.toLowerCase();

export { slugify };
3 changes: 2 additions & 1 deletion contentful/export-processor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@
"generate-test-suites": "node data-tools.js -ts true",
"data-tools": "node data-tools.js -ts false -uj true -s true",
"export-all-only": "node data-tools.js -ts false -uj false -s true -e content contentmodel editorinterfaces tags webhooks roles",
"lint": "eslint"
"lint": "eslint",
"export-recommendations-csv": "node --max-old-space-size=9000 recommendations_csv_outputter.js"
},
"keywords": [],
"author": "",
Expand Down
100 changes: 100 additions & 0 deletions contentful/export-processor/recommendations_csv_outputter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import "dotenv/config";
import DataMapper from "./data-mapper.js";
import ExportContentfulData from "./exporter.js";
import { writeFileSync } from "fs";
import { slugify } from "./helpers/slugify.js";

const getDataMapper = async () => {
const contentfulData = await ExportContentfulData({});

const dataMapper = new DataMapper(contentfulData);

return dataMapper;
};

const createRowsFromSections = (sections) => {
const getParentQuestionForAnswer = (section, answer) =>
section.questions.find((q) => q.answers.some((a) => a.id == answer.id));

const getRowValuesForAnswer = (section, answer, chunk) => {
const matchingQuestion = getParentQuestionForAnswer(section, answer);

const createLinkForRecommendation = (section) =>
`https://staging.plan-technology-for-your-school.education.gov.uk/${slugify(
section.name
)}/recommendation/preview/${section.recommendation.intros[0].maturity.toLowerCase()}#${chunk.header.toLowerCase().replace(/ /g, '-')}`;

if (!matchingQuestion) {
return;
}

const link = createLinkForRecommendation(section);
const hyperlink = `=HYPERLINK(""${link}"",""Preview Link"")`;

return [
section.name,
matchingQuestion.text,
answer.text,
chunk.header,
hyperlink,
];
};

return sections.flatMap((section) => {
if (!section || !section.name || !section.recommendation?.section?.chunks) {
return [];
}

const createRow = ({ answer, chunk }) =>
getRowValuesForAnswer(section, answer, chunk);

return section.recommendation.section.chunks
.flatMap((chunk) =>
chunk.answers.map((answer) => ({
answer,
chunk,
}))
)
.map(createRow);
});
};

const Csv = () => {
const csvHeaders = [
"Topic",
"Question",
"Answer",
"Outcome",
"Staging (Preview) URL",
];

const joinRow = (columns) => columns.map(value => `"${value}"`).join(",");

const create = (rows) => [[joinRow(csvHeaders)], ...rows].join("\n");

return {
joinRow,
create,
};
};

const main = async () => {
const dataMapper = await getDataMapper();
const csv = Csv();

const rows = createRowsFromSections(dataMapper.mappedSections).map(
csv.joinRow
);

const output = csv.create(rows);

const environment = process.env.ENV ?? process.env.ENVIRONMENT ?? "master";
const now = new Date().toISOString().replaceAll(":", "").replaceAll("-", "").replace("T", "").split(".")[0];
writeFileSync(`output/recommendations-export-${environment}-${now}.csv`, output);
};

main()
.then(() => console.log("Done"))
.catch(console.error);

export default main;

0 comments on commit a2f755d

Please sign in to comment.