Skip to content
This repository has been archived by the owner on Jan 17, 2024. It is now read-only.

Commit

Permalink
Merge pull request #87 from AppliedIS/feature-validation
Browse files Browse the repository at this point in the history
Feature validation
  • Loading branch information
MrMatt57 committed Nov 1, 2016
2 parents af5bde5 + a66601a commit f22e2b9
Show file tree
Hide file tree
Showing 74 changed files with 2,428 additions and 74 deletions.
16 changes: 16 additions & 0 deletions DOL.WHD.Section14c.Api/App_Start/DependencyResolutionConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Web.Http;
using DOL.WHD.Section14c.Business;
using DOL.WHD.Section14c.Business.Services;
using DOL.WHD.Section14c.Business.Validators;
using DOL.WHD.Section14c.DataAccess;
using DOL.WHD.Section14c.DataAccess.Repositories;
using SimpleInjector;
Expand All @@ -25,6 +26,21 @@ public static void Register()
container.Register<IApplicationRepository, ApplicationRepository>(Lifestyle.Scoped);
container.Register<IApplicationService, ApplicationService>(Lifestyle.Scoped);

// FluentValidation validators (make this singletons since the overhead of spinning up is high and they have no state)
container.Register<IApplicationSubmissionValidator, ApplicationSubmissionValidator>(Lifestyle.Singleton);
container.Register<IEmployerValidator, EmployerValidator>(Lifestyle.Singleton);
container.Register<IHourlyWageInfoValidator, HourlyWageInfoValidator>(Lifestyle.Singleton);
container.Register<IPieceRateWageInfoValidator, PieceRateWageInfoValidator>(Lifestyle.Singleton);
container.Register<IWIOAValidator, WIOAValidator>(Lifestyle.Singleton);
container.Register<IAddressValidator, AddressValidator>(Lifestyle.Singleton);
container.Register<IWorkerCountInfoValidator, WorkerCountInfoValidator>(Lifestyle.Singleton);
container.Register<IPrevailingWageSurveyInfoValidator, PrevailingWageSurveyInfoValidator>(Lifestyle.Singleton);
container.Register<IAlternateWageDataValidator, AlternateWageDataValidator>(Lifestyle.Singleton);
container.Register<ISourceEmployerValidator, SourceEmployerValidator>(Lifestyle.Singleton);
container.Register<IWorkSiteValidator, WorkSiteValidator>(Lifestyle.Singleton);
container.Register<IEmployeeValidator, EmployeeValidator>(Lifestyle.Singleton);
container.Register<IWIOAWorkerValidator, WIOAWorkerValidator>(Lifestyle.Singleton);

// This is an extension method from the integration package.
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

Expand Down
21 changes: 16 additions & 5 deletions DOL.WHD.Section14c.Api/Controllers/ApplicationController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.Threading.Tasks;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using DOL.WHD.Section14c.Business;
using DOL.WHD.Section14c.Business.Validators;
using DOL.WHD.Section14c.Domain.Models.Submission;

namespace DOL.WHD.Section14c.Api.Controllers
Expand All @@ -10,23 +13,31 @@ public class ApplicationController : ApiController
{
private readonly IIdentityService _identityService;
private readonly IApplicationService _applicationService;
public ApplicationController(IIdentityService identityService, IApplicationService applicationService)
private readonly IApplicationSubmissionValidator _applicationSubmissionValidator;
public ApplicationController(IIdentityService identityService, IApplicationService applicationService, IApplicationSubmissionValidator applicationSubmissionValidator)
{
_identityService = identityService;
_applicationService = applicationService;
_applicationSubmissionValidator = applicationSubmissionValidator;
}

public async Task<IHttpActionResult> Submit([FromBody]ApplicationSubmission submission)
public async Task<HttpResponseMessage> Submit([FromBody]ApplicationSubmission submission)
{
var results = _applicationSubmissionValidator.Validate(submission);
if (!results.IsValid)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, results.Errors);
}

// make sure user has rights to the EIN
var hasEINClaim = _identityService.UserHasEINClaim(User, submission.EIN);
if (!hasEINClaim)
{
return Unauthorized();
return Request.CreateResponse(HttpStatusCode.Unauthorized);
}

await _applicationService.SubmitApplicationAsync(submission);
return Created("", (object)null);
return Request.CreateResponse(HttpStatusCode.Created);
}
}
}
4 changes: 4 additions & 0 deletions DOL.WHD.Section14c.Api/DOL.WHD.Section14c.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
<HintPath>..\packages\EntityFramework6.Npgsql.3.1.1\lib\net45\EntityFramework6.Npgsql.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentValidation, Version=6.2.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\FluentValidation.6.2.1.0\lib\Net45\FluentValidation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.2\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
<Private>True</Private>
Expand Down
1 change: 1 addition & 0 deletions DOL.WHD.Section14c.Api/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<packages>
<package id="EntityFramework" version="6.1.3" targetFramework="net461" />
<package id="EntityFramework6.Npgsql" version="3.1.1" targetFramework="net461" />
<package id="FluentValidation" version="6.2.1.0" targetFramework="net452" />
<package id="Microsoft.AspNet.Cors" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net461" />
<package id="Microsoft.AspNet.Identity.EntityFramework" version="2.2.1" targetFramework="net461" />
Expand Down
32 changes: 32 additions & 0 deletions DOL.WHD.Section14c.Business/DOL.WHD.Section14c.Business.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentValidation, Version=6.2.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\FluentValidation.6.2.1.0\lib\Net45\FluentValidation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
Expand Down Expand Up @@ -64,6 +68,34 @@
<Compile Include="Services\ReCaptchaService.cs" />
<Compile Include="Services\ResponseService.cs" />
<Compile Include="Services\SaveService.cs" />
<Compile Include="Validators\AddressValidator.cs" />
<Compile Include="Validators\AlternateWageDataValidator.cs" />
<Compile Include="Validators\ApplicationSubmissionValidator.cs" />
<Compile Include="Validators\BaseValidator.cs" />
<Compile Include="Validators\EmployeeValidator.cs" />
<Compile Include="Validators\EmployerValidator.cs" />
<Compile Include="Validators\IAddressValidator.cs" />
<Compile Include="Validators\IAlternateWageDataValidator.cs" />
<Compile Include="Validators\IEmployeeValidator.cs" />
<Compile Include="Validators\IPrevailingWageSurveyInfoValidator.cs" />
<Compile Include="Validators\ISourceEmployerValidator.cs" />
<Compile Include="Validators\IWIOAValidator.cs" />
<Compile Include="Validators\IWIOAWorkerValidator.cs" />
<Compile Include="Validators\IWorkerCountInfoValidator.cs" />
<Compile Include="Validators\IWorkSiteValidator.cs" />
<Compile Include="Validators\PieceRateWageInfoValidator.cs" />
<Compile Include="Validators\HourlyWageInfoValidator.cs" />
<Compile Include="Validators\IApplicationSubmissionValidator.cs" />
<Compile Include="Validators\IEmployerValidator.cs" />
<Compile Include="Validators\IPieceRateWageInfoValidator.cs" />
<Compile Include="Validators\IHourlyWageInfoValidator.cs" />
<Compile Include="Validators\PrevailingWageSurveyInfoValidator.cs" />
<Compile Include="Validators\SourceEmployerValidator.cs" />
<Compile Include="Validators\WageTypeInfoValidator.cs" />
<Compile Include="Validators\WIOAValidator.cs" />
<Compile Include="Validators\WIOAWorkerValidator.cs" />
<Compile Include="Validators\WorkerCountInfoValidator.cs" />
<Compile Include="Validators\WorkSiteValidator.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DOL.WHD.Section14c.DataAccess\DOL.WHD.Section14c.DataAccess.csproj">
Expand Down
17 changes: 17 additions & 0 deletions DOL.WHD.Section14c.Business/Validators/AddressValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using DOL.WHD.Section14c.Domain.Models;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public class AddressValidator : BaseValidator<Address>, IAddressValidator
{
public AddressValidator()
{
RuleFor(a => a.StreetAddress).NotEmpty();
RuleFor(a => a.City).NotEmpty();
RuleFor(a => a.State).NotEmpty();
RuleFor(a => a.ZipCode).NotEmpty();
RuleFor(a => a.County).NotEmpty();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using DOL.WHD.Section14c.Domain.Models.Submission;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public class AlternateWageDataValidator : BaseValidator<AlternateWageData>, IAlternateWageDataValidator
{
public AlternateWageDataValidator()
{
RuleFor(a => a.AlternateWorkDescription).NotEmpty();
RuleFor(a => a.AlternateDataSourceUsed).NotEmpty();
RuleFor(a => a.PrevailingWageProvidedBySource).NotNull();
RuleFor(a => a.DataRetrieved).NotEmpty();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Linq;
using DOL.WHD.Section14c.Domain.Models.Submission;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public class ApplicationSubmissionValidator : BaseValidator<ApplicationSubmission>, IApplicationSubmissionValidator
{
public ApplicationSubmissionValidator(IEmployerValidator employerValidator, IHourlyWageInfoValidator hourlyWageInfoValidator, IPieceRateWageInfoValidator pieceRateWageInfoValidator, IWorkSiteValidator workSiteValidator, IWIOAValidator wioaValidator)
{
// required
RuleFor(a => a.RepresentativePayeeSocialSecurityBenefits).NotNull();
RuleFor(a => a.ProvidingFacilities).NotNull();
RuleFor(a => a.ReviewedDocumentation).NotNull();
RuleFor(a => a.EIN).NotEmpty();
RuleFor(a => a.ApplicationTypeId).NotNull();
RuleFor(a => a.HasPreviousApplication).NotNull();
RuleFor(a => a.HasPreviousCertificate).NotNull();
RuleFor(a => a.EstablishmentType).NotNull().Must(et => et.Any());
RuleFor(a => a.ContactName).NotEmpty();
RuleFor(a => a.ContactPhone).NotEmpty();
RuleFor(a => a.ContactEmail).NotEmpty();
RuleFor(a => a.PayTypeId).NotEmpty();
RuleFor(a => a.TotalNumWorkSites).NotNull();
RuleFor(a => a.Employer).NotNull().SetValidator(employerValidator);
RuleFor(a => a.WorkSites).NotNull().Must(w => w.Any()).SetCollectionValidator(workSiteValidator);
RuleFor(a => a.WIOA).NotNull().SetValidator(wioaValidator);

// conditional required
RuleFor(a => a.NumEmployeesRepresentativePayee)
.NotEmpty()
.When(a => a.RepresentativePayeeSocialSecurityBenefits.GetValueOrDefault());

When(a => a.ProvidingFacilities.GetValueOrDefault(), () =>
{
RuleFor(a => a.ProvidingFacilitiesDeductionType)
.NotNull()
.Must(p => p.Any());
RuleFor(a => a.ProvidingFacilitiesDeductionTypeOther)
.NotEmpty()
.When(a => a.ProvidingFacilitiesDeductionType != null && a.ProvidingFacilitiesDeductionType.Any(x => x.ProvidingFacilitiesDeductionTypeId == 20));
});

RuleFor(a => a.CertificateNumber)
.NotEmpty()
.When(a => a.HasPreviousCertificate.GetValueOrDefault());

RuleFor(a => a.HourlyWageInfo)
.NotNull()
.SetValidator(hourlyWageInfoValidator)
.When(x => x.PayTypeId == 21 || x.PayTypeId == 23);

RuleFor(a => a.PieceRateWageInfo)
.NotNull()
.SetValidator(pieceRateWageInfoValidator)
.When(x => x.PayTypeId == 22 || x.PayTypeId == 23);

// Other validation
RuleFor(a => a.ContactEmail).EmailAddress();
RuleFor(a => a.WorkSites.Count)
.Equal(a => a.TotalNumWorkSites.GetValueOrDefault())
.When(a => a.WorkSites != null);
}
}
}
12 changes: 12 additions & 0 deletions DOL.WHD.Section14c.Business/Validators/BaseValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public class BaseValidator<T> : AbstractValidator<T> where T : class
{
public BaseValidator()
{
CascadeMode = CascadeMode.StopOnFirstFailure;
}
}
}
26 changes: 26 additions & 0 deletions DOL.WHD.Section14c.Business/Validators/EmployeeValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using DOL.WHD.Section14c.Domain.Models.Submission;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public class EmployeeValidator : BaseValidator<Employee>, IEmployeeValidator
{
public EmployeeValidator()
{
RuleFor(e => e.Name).NotEmpty();
RuleFor(e => e.PrimaryDisabilityId).NotNull();
RuleFor(e => e.WorkType).NotEmpty();
RuleFor(e => e.NumJobs).NotNull();
RuleFor(e => e.AvgWeeklyHours).NotNull();
RuleFor(e => e.AvgHourlyEarnings).NotNull();
RuleFor(e => e.PrevailingWage).NotNull();
RuleFor(e => e.ProductivityMeasure).NotNull();
RuleFor(e => e.CommensurateWageRate).NotEmpty();
RuleFor(e => e.TotalHours).NotNull();
RuleFor(e => e.WorkAtOtherSite).NotNull();

// conditional
RuleFor(e => e.PrimaryDisabilityOther).NotEmpty().When(e => e.PrimaryDisabilityId == 38);
}
}
}
45 changes: 45 additions & 0 deletions DOL.WHD.Section14c.Business/Validators/EmployerValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using DOL.WHD.Section14c.Domain.Models.Submission;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public class EmployerValidator : BaseValidator<EmployerInfo>, IEmployerValidator
{
public EmployerValidator(IAddressValidator addressValidator, IWorkerCountInfoValidator workerCountInfoValidator)
{
// required
RuleFor(e => e.LegalName).NotEmpty();
RuleFor(e => e.HasTradeName).NotNull();
RuleFor(e => e.LegalNameHasChanged).NotNull();
RuleFor(e => e.PhysicalAddress).NotNull().SetValidator(addressValidator);
RuleFor(e => e.HasDifferentMailingAddress).NotNull();
RuleFor(e => e.HasParentOrg).NotNull();
RuleFor(e => e.EmployerStatusId).NotNull();
RuleFor(e => e.IsEducationalAgency).NotNull();
RuleFor(e => e.FiscalQuarterEndDate).NotEmpty();
RuleFor(e => e.NumSubminimalWageWorkers).NotNull().SetValidator(workerCountInfoValidator);
RuleFor(e => e.PCA).NotNull();
RuleFor(e => e.SCAId).NotNull();
RuleFor(e => e.EO13658Id).NotNull();
RuleFor(e => e.RepresentativePayee).NotNull();
RuleFor(e => e.TakeCreditForCosts).NotNull();
RuleFor(e => e.ProvidingFacilitiesDeductionTypeId).NotNull();
RuleFor(e => e.TemporaryAuthority).NotNull();

// conditional required
RuleFor(e => e.TradeName).NotEmpty().When(e => e.HasTradeName.GetValueOrDefault());
RuleFor(e => e.PriorLegalName).NotEmpty().When(e => e.LegalNameHasChanged.GetValueOrDefault());
When(e => e.HasParentOrg.GetValueOrDefault(), () =>
{
RuleFor(e => e.ParentLegalName).NotEmpty();
RuleFor(e => e.ParentTradeName).NotEmpty();
RuleFor(e => e.ParentAddress).NotNull().SetValidator(addressValidator);
RuleFor(e => e.SendMailToParent).NotNull();
});
RuleFor(e => e.EmployerStatusOther).NotEmpty().When(e => e.EmployerStatusId == 10);
RuleFor(e => e.ProvidingFacilitiesDeductionTypeOther)
.NotEmpty()
.When(e => e.ProvidingFacilitiesDeductionTypeId == 20);
}
}
}
14 changes: 14 additions & 0 deletions DOL.WHD.Section14c.Business/Validators/HourlyWageInfoValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using DOL.WHD.Section14c.Domain.Models.Submission;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public class HourlyWageInfoValidator : WageTypeInfoValidator<HourlyWageInfo>, IHourlyWageInfoValidator
{
public HourlyWageInfoValidator(IPrevailingWageSurveyInfoValidator prevailingWageSurveyInfoValidator, IAlternateWageDataValidator alternateWageDataValidator)
:base(prevailingWageSurveyInfoValidator, alternateWageDataValidator)
{
RuleFor(h => h.WorkMeasurementFrequency).NotEmpty();
}
}
}
9 changes: 9 additions & 0 deletions DOL.WHD.Section14c.Business/Validators/IAddressValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using DOL.WHD.Section14c.Domain.Models;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public interface IAddressValidator : IValidator<Address>
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using DOL.WHD.Section14c.Domain.Models.Submission;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public interface IAlternateWageDataValidator : IValidator<AlternateWageData>
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using DOL.WHD.Section14c.Domain.Models.Submission;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public interface IApplicationSubmissionValidator : IValidator<ApplicationSubmission>
{
}
}
9 changes: 9 additions & 0 deletions DOL.WHD.Section14c.Business/Validators/IEmployeeValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using DOL.WHD.Section14c.Domain.Models.Submission;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public interface IEmployeeValidator : IValidator<Employee>
{
}
}
9 changes: 9 additions & 0 deletions DOL.WHD.Section14c.Business/Validators/IEmployerValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using DOL.WHD.Section14c.Domain.Models.Submission;
using FluentValidation;

namespace DOL.WHD.Section14c.Business.Validators
{
public interface IEmployerValidator : IValidator<EmployerInfo>
{
}
}
Loading

0 comments on commit f22e2b9

Please sign in to comment.