Skip to content

Commit

Permalink
Merge into main for staging release
Browse files Browse the repository at this point in the history
  • Loading branch information
DrewAire authored Feb 3, 2025
2 parents 01504c1 + b5397dc commit aef8f95
Show file tree
Hide file tree
Showing 32 changed files with 936 additions and 540 deletions.
73 changes: 69 additions & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,81 @@ csharp_style_unused_value_assignment_preference = discard_variable
csharp_style_unused_value_expression_statement_preference = discard_variable

# Expression-level preferences
dotnet_style_coalesce_expression = true
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_collection_initializer = true
dotnet_style_null_propagation = true
dotnet_style_null_propagation = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_compound_assignment = true
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true
dotnet_style_prefer_simplified_interpolation = true

## Set warnings to errors to be auto-fixed by dotnet format
# Using directive is unnecessary
dotnet_diagnostic.IDE0005.severity = error
csharp_using_directive_placement = outside_namespace:silent
csharp_prefer_simple_using_statement = true:suggestion
csharp_prefer_braces = true:silent
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
csharp_style_prefer_primary_constructors = true:suggestion
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_indent_labels = one_less_than_current

[*.{cs,vb}]
#### Naming styles ####

# Naming rules

dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i

dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case

# Symbol specifications

dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =

dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =

dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =

# Naming styles

dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
end_of_line = lf
4 changes: 4 additions & 0 deletions .github/actions/run-unit-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ runs:
shell: bash
run: dotnet test ${{ inputs.solution_filename }} --no-restore --verbosity normal --collect:"XPlat Code Coverage" --logger:"trx;LogFileName=test-results.trx" || true

- name: Update apt-get packages
shell: bash
run: sudo apt-get update

- name: Install XML tools
shell: bash
run: sudo apt-get install -y libxml2-utils
Expand Down
3 changes: 2 additions & 1 deletion contentful/export-processor/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ output/
inserted-groups.json

#Env variables
.env
.env
.env.*
91 changes: 56 additions & 35 deletions contentful/export-processor/content-types/recommendation-section.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,64 @@ import RecommendationChunk from "./recommendation-chunk.js";
import ErrorLogger from "../errors/error-logger.js";

export default class RecommendationSection {
answers;
chunks;
id;
/**
* @type {Answer[]}
*/
answers;

constructor({ fields, sys }) {
this.id = sys.id;
/**
* @type {RecommendationChunk[]}
*/
chunks;

this.answers = fields.answers?.map((answer) => new Answer(answer)) ?? [];
/**
* @type {string}
*/
id;

this.chunks = fields.chunks?.map((chunk) => new RecommendationChunk(chunk)) ?? [];
this.logErrorIfMissingRelationships("chunks");
}
/**
*
* @param {{fields: Record<string, any>, sys: { id: string }}} param0
*/
constructor({ fields, sys }) {
this.id = sys.id;

logErrorIfMissingRelationships(field) {
const matching = this[field];
if (!matching || matching.length == 0) {
ErrorLogger.addError({ id: this.id, contentType: "recommendationSection", message: `No ${field} found` });
this.answers =
fields.answers?.map((answer) => new Answer(answer)) ?? [];

this.chunks =
fields.chunks?.map((chunk) => new RecommendationChunk(chunk)) ?? [];

this.logErrorIfMissingRelationships("chunks");
}

logErrorIfMissingRelationships(field) {
const matching = this[field];
if (!matching || matching.length == 0) {
ErrorLogger.addError({
id: this.id,
contentType: "recommendationSection",
message: `No ${field} found`,
});
}
}

getChunksForPath(path) {
const answerIds = path.map((pathPart) => pathPart.answer.id);

const filteredChunks = this.chunks.filter((chunk) =>
chunk.answers.some((answer) => answerIds.includes(answer.id))
);

const uniqueChunks = [];
const seen = new Set();

for (const chunk of filteredChunks) {
if (!seen.has(chunk.id)) {
seen.add(chunk.id);
uniqueChunks.push(chunk);
}
}
return uniqueChunks;
}
}

getChunksForPath(path) {
const answerIds = path.map(pathPart => pathPart.answer.id);

const filteredChunks = this.chunks.filter(chunk =>
chunk.answers.some(answer => answerIds.includes(answer.id))
);

const uniqueChunks = [];
const seen = new Set();

for (const chunk of filteredChunks) {
const chunkStr = JSON.stringify(chunk);
if (!seen.has(chunkStr)) {
seen.add(chunkStr);
uniqueChunks.push(chunk);
}
}
return uniqueChunks;
}
}
}
22 changes: 18 additions & 4 deletions contentful/export-processor/content-types/section.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Question } from "./question.js";
import { PathCalculator } from "../user-journey/path-calculator.js";
import { SectionStats } from "#src/user-journey/section-stats";
import { UserJourney } from "#src/user-journey/user-journey";

/**
* @typedef {import("./subtopic-recommendation.js").SubtopicRecommendation} SubtopicRecommendation
Expand All @@ -14,7 +15,6 @@ import { SectionStats } from "#src/user-journey/section-stats";
* @typedef {import("#src/user-journey/user-journey").UserJourneyMinimalOutput} UserJourneyMinimalOutput
*/


/**
* @typedef {import("#src/user-journey/user-journey").UserJourney} UserJourney
*/
Expand Down Expand Up @@ -86,10 +86,22 @@ export class Section {
* @returns {SectionMinimalOutput} Minimal section info
*/
toMinimalOutput(writeAllPossiblePaths) {
return {
const recommendationPaths =
this.pathInfo.minimumPathsForRecommendations;

for (const [maturity, path] of Object.entries(recommendationPaths)) {
recommendationPaths[maturity] = path.map((part) =>
part.toMinimalOutput()
);
}

const result = {
section: this.name,
allPathsStats: this.stats.pathsPerMaturity,
minimumQuestionPaths: this.pathInfo.minimumPathsToNavigateQuestions,
minimumQuestionPaths:
this.pathInfo.minimumPathsToNavigateQuestions.map((path) =>
path.map((part) => part.toMinimalOutput())
),
minimumRecommendationPaths:
this.pathInfo.minimumPathsForRecommendations,
pathsForAnswers: this.pathInfo.pathsForAllPossibleAnswers.map(
Expand All @@ -99,6 +111,8 @@ export class Section {
? this.pathInfo.paths.map((path) => path.toMinimalOutput())
: undefined,
};

return result;
}
}

Expand All @@ -110,4 +124,4 @@ export class Section {
* @property {Record<string, PathPart[]>} minimumRecommendationPaths Shortest amount of paths possible to get every possible recommendation chunk
* @property {UserJourneyMinimalOutput[]} pathsForAnswers Shortest amount of paths possible to navigate through every answer
* @property {(UserJourneyMinimalOutput[] | undefined)} allPossiblePaths All possible paths
*/
*/
16 changes: 13 additions & 3 deletions contentful/export-processor/data-mapper.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ContentType from "./content-types/content-type.js";
import SubtopicRecommendation from "./content-types/subtopic-recommendation.js";
import ErrorLogger from "./errors/error-logger.js";
import { log } from "#src/helpers/log";

/**
* @typedef {import("./content-types/section.js").Section} Section
Expand All @@ -20,7 +21,7 @@ export default class DataMapper {

/**
* Get the mapped sections
* @returns {IterableIterator<Section>} Iterator for mapped sections
* @returns {Section[]} Iterator for mapped sections
*/
get mappedSections() {
if (!this._alreadyMappedSections)
Expand Down Expand Up @@ -130,9 +131,18 @@ export default class DataMapper {
}

for (const [, subtopicRecommendation] of subtopicRecommendations) {
const mapped = new SubtopicRecommendation(subtopicRecommendation);
try {
const mapped = new SubtopicRecommendation(
subtopicRecommendation
);

yield mapped.subtopic;
yield mapped.subtopic;
} catch (e) {
console.error(
`Error trying to created SubtopicRecommendation: ${e}`,
subtopicRecommendation
);
}
}
}

Expand Down
62 changes: 35 additions & 27 deletions contentful/export-processor/data-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,40 @@ import WriteUserJourneyPaths from "./write-user-journey-paths.js";
import { options } from "./options.js";

async function processContentfulData(args) {
const contentfulData = await ExportContentfulData({ ...args });

if (!args.generateTestSuites && !args.exportUserJourneyPaths && !args.exportUserJourneyPaths) {
console.log(`No options set for using data - ending run`);
return;
}

if (!contentfulData.entries || !contentfulData.contentTypes) {
console.error('Missing entries or content types');
return;
}

const dataMapper = new DataMapper(contentfulData);

const outputDir = args.outputDir;

if (args.generateTestSuites) {
GenerateTestSuites({ dataMapper, outputDir });
}

if (!!args.exportUserJourneyPaths) {
WriteUserJourneyPaths({ dataMapper, outputDir, saveAllJourneys: args.saveAllJourneys });
}

ErrorLogger.outputDir = outputDir;
ErrorLogger.writeErrorsToFile();
const contentfulData = await ExportContentfulData({ ...args });

if (
!args.generateTestSuites &&
!args.exportUserJourneyPaths &&
!args.exportUserJourneyPaths
) {
console.log(`No options set for using data - ending run`);
return;
}

if (!contentfulData.entries || !contentfulData.contentTypes) {
console.error("Missing entries or content types");
return;
}

const dataMapper = new DataMapper(contentfulData);

const outputDir = args.outputDir;

if (args.generateTestSuites) {
GenerateTestSuites({ dataMapper, outputDir });
}

if (args.exportUserJourneyPaths) {
WriteUserJourneyPaths({
dataMapper,
outputDir,
saveAllJourneys: args.saveAllJourneys,
});
}

ErrorLogger.outputDir = outputDir;
ErrorLogger.writeErrorsToFile();
}

await processContentfulData(options);
await processContentfulData(options);
Loading

0 comments on commit aef8f95

Please sign in to comment.