- Requirements & Prereqs
- Wiki
- Validators
- Address/Street/Organisation Providers
- Payment Providers
- Storage Providers
- Running High Availability
- UI Tests
- dotnet core 3.1
- GPG key added to collaborators
Comming Soon...
IAddressProvider
is provided to enable integration with different address data sources.
The interface requires a ProviderName and a SearchAsync method which must return an AddressSearchResult
object.
string ProviderName { get; }
Task<IEnumerable<AddressSearchResult>> SearchAsync(string streetOrPostcode);
You can register new/multiple address providers in startup
services.AddSingleton<IAddressProvider, FakeAddressProvider>();
services.AddSingleton<IAddressProvider, CRMAddressProvider>();
services.AddSingleton<IAddressProvider, MyCustomAddressProvider>();
You can specify in the JSON form defenition for Address elements, which address provider you want use. To do this set AddressProvider
to the value of the required IAddressProvider.ProviderName
, for example to use a Provider with a ProviderName of "Fake";
{
"Type": "Address",
"Properties": {
"QuestionId": "address",
"AddressProvider": "Fake",
}
}
IStreetProvider
is provided to enable integration with different street level data sources.
Implementation is almost identical to that described in the AddressProvider
Register for use
services.AddSingleton<IStreetProvider, FakeStreetProvider>();
services.AddSingleton<IStreetProvider, CRMStreetProvider>();
return services;
Specify which street provider to use.
"Elements": [
{
"Type": "Street",
"Properties": {
"QuestionId": "customersstreet",
"StreetProvider": "Fake",
}
IOrganisationProvider
is provided to enable integration with different organisation data sources.
Implementation is almost identical to that described in the AddressProvider/StreetProvider, however Organisation Providers return an OrganisationSearchResult
Register for user
services.AddSingleton<IOrganisationProvider, FakeOrganisationProvider>();
services.AddSingleton<IOrganisationProvider, CRMOrganisationProvider>();
return services;
Specify which organisation provider to use.
{
"Type": "Organisation",
"Properties": {
"QuestionId": "organisation",
"Label": "Enter the organisation",
"OrganisationProvider": "Fake",
}
Comming Soon...
As users submit data and move through forms the data they are submitting is temporarily stored before submission.
This function uses IDistributedCache.
Storage providers can be added from config and registered on app startup using.
services.AddStorageProvider(Configuration);
By default setup using config currently supports "Application", Distributed In Memory Cache (which ironically isn't actually distributed!), but allows us to develop locally and deploy to single instances.
This can be set up using the following config
{
"StorageProvider": {
"Type": "Application"
}
}
For a truly distributed we support Redis, this can be setup using the StorageProvider config below.
{
"StorageProvider": {
"Type": "Redis",
"Address": "YourRedisUrlHere",
"Instance": "YourPreferredInstanceNameHere"
}
}
If running in a load balanced environment you will need to be running a truly distributed cache (i.e. Redis).
In this case it's worth noting that for sessions to work correctly there needs to be a shared keystore.
Distributed cache and DataProtecton key storage specification is wrapped up in the services.AddStorageProvider(Configuration);
service registration (we should seperate this out!) so when you set storage provider to 'Redis' it also shares the data protection keys in redis as well (as per the code below).
var redis = ConnectionMultiplexer.Connect(storageProviderConfiguration["Address"]);
services.AddDataProtection().PersistKeysToStackExchangeRedis(redis, $"{storageProviderConfiguration["InstanceName"]}DataProtection-Keys");
The form builder app has UI tests to ensure that the UI is expected. Our UI Tests are written using SpecFlow
- chromdrivers.exe
- make (not required)
$ make ui-test
It is also possible to run just a specific test case rather then running the whole ui-test suite, this is made possible by running the ui-test-feature
make command. with a FEATURE paramater as the test suite to run. The example below runs only the organisation ui-tests.
$ make FEATURE=organisation ui-test-feature
without make you can also run the UI Test locally by running the two commands listed below
$ cd ./src && dotnet run
$ dotnet test ./form-builder-tests-ui/form-builder-tests-ui.csproj
It is possible to change the default browser the UI Tests are run from, to do this you need to modify the BrowserConfiguration to run with firefox or another browser of your choice.
This section will be used to document the decisions made throughout the development process.
The formbuilder storage components will be provisioned by a Cloudformation stack. Jon H & Jake decided that the stack would include an S3 Bucket, IAM User and a User Policy to handle the storage of json files.
The example below shows the policy we manually created and applied to a test user:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutAccountPublicAccessBlock",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListJobs",
"s3:CreateJob",
"s3:HeadBucket"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucketname/*",
"arn:aws:s3:::bucketname"
]
}
]
}
The S3 bucket used during testing was cofigured to 'Block all public access' to 'On'.
The bucket will be created using a Cloudformation template with the folder structure created by the template.