Skip to content

Commit

Permalink
Move answer field name to form field options, and conditionally expos…
Browse files Browse the repository at this point in the history
…e OptionJson field based on the field name
  • Loading branch information
andymantell committed Jan 9, 2025
1 parent eafd7ea commit 3c7893e
Show file tree
Hide file tree
Showing 15 changed files with 2,040 additions and 24 deletions.
10 changes: 5 additions & 5 deletions Frontend/CO.CDP.OrganisationApp.Tests/FormsEngineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private static (Guid organisationId, Guid formId, Guid sectionId, string session
return (organisationId, formId, sectionId, sessionKey);
}

private static WebApiClient.SectionQuestionsResponse CreateApiSectionQuestionsResponse(Guid sectionId, Guid questionId, Guid nextQuestionId, string? choiceProviderStrategy = null)
private static WebApiClient.SectionQuestionsResponse CreateApiSectionQuestionsResponse(Guid sectionId, Guid questionId, Guid nextQuestionId, string? choiceProviderStrategy = null, string? answerFieldName = null)
{
return new WebApiClient.SectionQuestionsResponse(
section: new WebApiClient.FormSection(
Expand Down Expand Up @@ -71,6 +71,7 @@ private static WebApiClient.SectionQuestionsResponse CreateApiSectionQuestionsRe
nextQuestionAlternative: null,
options: new WebApiClient.FormQuestionOptions(
choiceProviderStrategy: choiceProviderStrategy,
answerFieldName: answerFieldName,
choices: new List<WebApiClient.FormQuestionChoice>
{
new WebApiClient.FormQuestionChoice(
Expand Down Expand Up @@ -129,8 +130,7 @@ private static SectionQuestionsResponse CreateModelSectionQuestionsResponse(Guid
Options = new FormQuestionOptions
{
Choices = options == null ? new Dictionary<string, string>() { { "Option1", "Option1" } } : options,
ChoiceProviderStrategy = choiceProviderStrategy,
ChoiceAnswerFieldName = "OptionValue",
ChoiceProviderStrategy = choiceProviderStrategy
}
}
}
Expand Down Expand Up @@ -291,15 +291,15 @@ public async Task GetFormSectionAsync_ShouldFetchChoicesFromCustomChoiceProvider
var (organisationId, formId, sectionId, sessionKey) = CreateTestGuids();
var questionId = Guid.NewGuid();
var nextQuestionId = Guid.NewGuid();
var apiResponse = CreateApiSectionQuestionsResponse(sectionId, questionId, nextQuestionId, "ExclusionAppliesToChoiceProviderStrategy");
var apiResponse = CreateApiSectionQuestionsResponse(sectionId, questionId, nextQuestionId, "ExclusionAppliesToChoiceProviderStrategy", "JsonValue");
var expectedResponse = CreateModelSectionQuestionsResponse(sectionId, questionId, nextQuestionId, "ExclusionAppliesToChoiceProviderStrategy");

expectedResponse.Questions[0].Options.Choices = new Dictionary<string, string>() {
{ $@"{{""id"":""{organisationId}"",""type"":""organisation""}}", "User's current organisation" },
{ "{\"id\":\"e4bdd7ef-8200-4257-9892-b16f43d1803e\",\"type\":\"connected-entity\"}", "First name Last name" },
{ "{\"id\":\"4c8dccba-df39-4997-814b-7599ed9b5bed\",\"type\":\"connected-entity\"}", "Connected organisation" } };

expectedResponse.Questions[0].Options.ChoiceAnswerFieldName = "JsonValue";
expectedResponse.Questions[0].Options.AnswerFieldName = "JsonValue";

expectedResponse.Questions[0].Options.Groups = new List<FormQuestionGroup>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class FormElementSingleChoiceModelTest
public FormElementSingleChoiceModelTest()
{
_model = new FormElementSingleChoiceModel();
_model.Options = new FormQuestionOptions() { ChoiceAnswerFieldName = "OptionValue", Choices = new Dictionary<string, string>() {{ "Option 1", "Option 1" }, { "Option 2", "Option 2" }, { "Option 3", "Option 3" }}};
_model.Options = new FormQuestionOptions() { AnswerFieldName = "OptionValue", Choices = new Dictionary<string, string>() {{ "Option 1", "Option 1" }, { "Option 2", "Option 2" }, { "Option 3", "Option 3" }}};
}

[Theory]
Expand Down
2 changes: 1 addition & 1 deletion Frontend/CO.CDP.OrganisationApp/FormsEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public async Task<SectionQuestionsResponse> GetFormSectionAsync(Guid organisatio
Value = c.Value
}).ToList()
}).ToList(),
ChoiceAnswerFieldName = choiceProviderStrategy.AnswerFieldName
AnswerFieldName = q.Options.AnswerFieldName
}
};
}))).ToList()
Expand Down
2 changes: 1 addition & 1 deletion Frontend/CO.CDP.OrganisationApp/Models/DynamicForms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class FormQuestionOptions
public Dictionary<string, string>? Choices { get; set; }
public string? ChoiceProviderStrategy { get; set; }
public List<FormQuestionGroup> Groups { get; set; } = [];
public string? ChoiceAnswerFieldName { get; set; }
public string? AnswerFieldName { get; set; }
}

public class FormQuestionAnswerState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ namespace CO.CDP.OrganisationApp.Pages.Forms.ChoiceProviderStrategies;

public class DefaultChoiceProviderStrategy() : IChoiceProviderStrategy
{
public string AnswerFieldName { get; } = "OptionValue";
public async Task<Dictionary<string, string>?> Execute(FormQuestionOptions options)
{
return await Task.FromResult(options.Choices.ToDictionary(c => c.Title, c => c.Title));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ namespace CO.CDP.OrganisationApp.Pages.Forms.ChoiceProviderStrategies;

public class ExclusionAppliesToChoiceProviderStrategy(IUserInfoService userInfoService, IOrganisationClient organisationClient) : IChoiceProviderStrategy
{
public string AnswerFieldName { get; } = "JsonValue";

public async Task<Dictionary<string, string>?> Execute(FormQuestionOptions options)
{
var jsonSerializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ namespace CO.CDP.OrganisationApp.Pages.Forms.ChoiceProviderStrategies;

public interface IChoiceProviderStrategy
{
public string AnswerFieldName { get; }
Task<Dictionary<string, string>?> Execute(FormQuestionOptions options);
public Task<string?> RenderOption(CO.CDP.OrganisationApp.Models.FormAnswer? answer);
public Task<string?> RenderOption(CO.CDP.Forms.WebApiClient.FormAnswer? answer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class FormElementSingleChoiceModel : FormElementModel, IValidatableObject
{
FormAnswer formAnswer;

switch (Options.ChoiceAnswerFieldName)
switch (Options.AnswerFieldName)
{
case nameof(FormAnswer.OptionValue):
formAnswer = new FormAnswer { OptionValue = SelectedOption };
Expand All @@ -30,7 +30,7 @@ public class FormElementSingleChoiceModel : FormElementModel, IValidatableObject
formAnswer = new FormAnswer { JsonValue = SelectedOption };
break;
default:
throw new InvalidOperationException($"Unsupported field: {Options.ChoiceAnswerFieldName}");
throw new InvalidOperationException($"Unsupported field: {Options.AnswerFieldName}");
}

return formAnswer;
Expand All @@ -44,7 +44,7 @@ public override void SetAnswer(FormAnswer? answer)
{
string? value;

switch (Options?.ChoiceAnswerFieldName)
switch (Options?.AnswerFieldName)
{
case nameof(FormAnswer.OptionValue):
value = answer?.OptionValue;
Expand Down Expand Up @@ -73,7 +73,7 @@ public override void SetAnswer(FormAnswer? answer)

break;
default:
throw new InvalidOperationException($"Unsupported field: {Options?.ChoiceAnswerFieldName}");
throw new InvalidOperationException($"Unsupported field: {Options?.AnswerFieldName}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public CustomFormQuestionTypeResolverTests()
[InlineData(OrganisationInformation.Persistence.Forms.FormQuestionType.FileUpload, FormQuestionType.FileUpload)]
[InlineData(OrganisationInformation.Persistence.Forms.FormQuestionType.Address, FormQuestionType.Text)]
[InlineData(OrganisationInformation.Persistence.Forms.FormQuestionType.SingleChoice, FormQuestionType.Option)]
[InlineData(OrganisationInformation.Persistence.Forms.FormQuestionType.SingleChoice, FormQuestionType.OptionJson, "JsonValue")]
[InlineData(OrganisationInformation.Persistence.Forms.FormQuestionType.MultipleChoice, FormQuestionType.Option)]
[InlineData(OrganisationInformation.Persistence.Forms.FormQuestionType.GroupedSingleChoice, FormQuestionType.Option)]
[InlineData(OrganisationInformation.Persistence.Forms.FormQuestionType.Date, FormQuestionType.Date)]
Expand All @@ -29,9 +30,10 @@ public CustomFormQuestionTypeResolverTests()
[InlineData(OrganisationInformation.Persistence.Forms.FormQuestionType.CheckYourAnswers, FormQuestionType.None)]
public void Resolve_ReturnsExpectedFormQuestionType(
OrganisationInformation.Persistence.Forms.FormQuestionType sourceType,
FormQuestionType expectedType)
FormQuestionType expectedType,
string? answerFieldName = null)
{
OrganisationInformation.Persistence.Forms.FormQuestion sourceQuestion = GivenQuestion(sourceType);
OrganisationInformation.Persistence.Forms.FormQuestion sourceQuestion = GivenQuestion(sourceType, answerFieldName);

var result = _resolver.Resolve(sourceQuestion, null!, default, null!);

Expand All @@ -49,7 +51,7 @@ public void Resolve_ShouldHandleAllFormQuestionTypesWithoutException()
}
}

private static OrganisationInformation.Persistence.Forms.FormQuestion GivenQuestion(OrganisationInformation.Persistence.Forms.FormQuestionType type)
private static OrganisationInformation.Persistence.Forms.FormQuestion GivenQuestion(OrganisationInformation.Persistence.Forms.FormQuestionType type, string? answerFieldName = null)
{
return new OrganisationInformation.Persistence.Forms.FormQuestion {
Type = type,
Expand All @@ -61,10 +63,12 @@ private static OrganisationInformation.Persistence.Forms.FormQuestion GivenQuest
IsRequired = false,
CreatedOn = DateTime.Now,
Name = null!,
Options = null!,
Options = new () {
AnswerFieldName = answerFieldName
},
Section = null!,
SortOrder = 1,
Title = null!
Title = null!,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,14 @@ public FormQuestionType Resolve(Persistence.FormQuestion source,
case Persistence.FormQuestionType.SingleChoice:
case Persistence.FormQuestionType.GroupedSingleChoice:
case Persistence.FormQuestionType.MultipleChoice:
return FormQuestionType.Option;

if(source.Options.AnswerFieldName == "JsonValue")
{
return FormQuestionType.OptionJson;
} else
{
return FormQuestionType.Option;
}

case Persistence.FormQuestionType.Date:
return FormQuestionType.Date;

Expand Down
3 changes: 2 additions & 1 deletion Services/CO.CDP.DataSharing.WebApi/Model/FormQuestionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public enum FormQuestionType
DateTimeRange,
Date,
Url,
FileUpload
FileUpload,
OptionJson
}
1 change: 1 addition & 0 deletions Services/CO.CDP.Forms.WebApi/Model/FormQuestionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ public record FormQuestionOptions
{
public List<FormQuestionChoice>? Choices { get; init; } = new();
public string? ChoiceProviderStrategy { get; init; }
public string? AnswerFieldName { get; init; }
public List<FormQuestionGroup>? Groups { get; set; } = new();
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public record FormQuestionOptions
{
public ICollection<FormQuestionChoice>? Choices { get; set; } = null;
public string? ChoiceProviderStrategy { get; set; } = null;
public string? AnswerFieldName { get; set; } = null;
public ICollection<FormQuestionGroup>? Groups { get; set; } = null;
}

Expand Down
Loading

0 comments on commit 3c7893e

Please sign in to comment.