Skip to content

Commit 16a21b7

Browse files
committed
feat: apply the language and residency codesets-based validations to the productizer routes, allow nullable basic infos
1 parent 3adf0d4 commit 16a21b7

3 files changed

Lines changed: 60 additions & 21 deletions

File tree

VirtualFinland.UserAPI/src/VirtualFinland.UsersAPI/Activities/Productizer/Operations/BasicInformation/UpdatePersonBasicInformation.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
using FluentValidation;
12
using MediatR;
23
using Microsoft.EntityFrameworkCore;
34
using Swashbuckle.AspNetCore.Annotations;
45
using VirtualFinland.UserAPI.Data;
6+
using VirtualFinland.UserAPI.Data.Repositories;
57
using VirtualFinland.UserAPI.Exceptions;
68
using VirtualFinland.UserAPI.Helpers;
79
using VirtualFinland.UserAPI.Helpers.Services;
@@ -27,6 +29,22 @@ public Command(string? givenName, string? lastName, string email, string? phoneN
2729
public string Email { get; }
2830
public string? PhoneNumber { get; }
2931
public string? Residency { get; }
32+
33+
public class CommandValidator : AbstractValidator<Command>
34+
{
35+
public CommandValidator(ICountriesRepository countriesRepository)
36+
{
37+
RuleFor(command => command.User.PersonId).NotNull().NotEmpty();
38+
39+
var knownCountries = countriesRepository.GetAllCountries().Result;
40+
var knownCountryCodes = knownCountries.Select(x => x.IsoCodeThreeLetter).ToList();
41+
RuleFor(command => command.Residency).Must((residency) =>
42+
{
43+
if (residency is null) return true;
44+
return knownCountryCodes.Contains(residency);
45+
}).WithMessage("Residency is not valid");
46+
}
47+
}
3048
}
3149

3250
public class Handler : IRequestHandler<Command, UpdatePersonBasicInformationResponse>
@@ -45,11 +63,11 @@ public async Task<UpdatePersonBasicInformationResponse> Handle(Command request,
4563
{
4664
var person = await _context.Persons.SingleAsync(p => p.Id == request.User.PersonId, cancellationToken);
4765

48-
person.GivenName = request.GivenName ?? person.GivenName;
49-
person.LastName = request.LastName ?? person.LastName;
66+
person.GivenName = request.GivenName;
67+
person.LastName = request.LastName;
5068
person.Email = request.Email;
51-
person.PhoneNumber = request.PhoneNumber ?? person.PhoneNumber;
52-
person.ResidencyCode = request.Residency ?? person.ResidencyCode;
69+
person.PhoneNumber = request.PhoneNumber;
70+
person.ResidencyCode = request.Residency;
5371

5472
try
5573
{

VirtualFinland.UserAPI/src/VirtualFinland.UsersAPI/Activities/Productizer/Operations/JobApplicantProfile/UpdateJobApplicantProfile.cs

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using VirtualFinland.UserAPI.Exceptions;
99
using VirtualFinland.UserAPI.Helpers;
1010
using VirtualFinland.UserAPI.Helpers.Services;
11-
using VirtualFinland.UserAPI.Helpers.Extensions;
1211
using VirtualFinland.UserAPI.Models.Shared;
1312
using VirtualFinland.UserAPI.Models.UsersDatabase;
1413
using VirtualFinland.UserAPI.Security.Models;
@@ -47,7 +46,7 @@ public Command(
4746

4847
private sealed class WorkPreferencesValidator : AbstractValidator<Request.WorkPreferenceValues>
4948
{
50-
public WorkPreferencesValidator()
49+
public WorkPreferencesValidator(ILanguageRepository languagesRepository)
5150
{
5251
RuleForEach(wp => wp.PreferredMunicipality)
5352
.Must(x => EnumUtilities.TryParseWithMemberName<Municipality>(x, out _));
@@ -63,25 +62,27 @@ public WorkPreferencesValidator()
6362
.Must(x => EnumUtilities.TryParseWithMemberName<WorkingTime>(x!, out _))
6463
.When(x => !string.IsNullOrEmpty(x.WorkingTime));
6564

65+
var knownLanguages = languagesRepository.GetAllLanguages().Result;
66+
var knownLanguageCodes = knownLanguages.Select(x => x.TwoLetterISOLanguageName).ToList();
6667
RuleForEach(wp => wp.WorkingLanguage)
67-
.Must(x => !string.IsNullOrEmpty(x) && x.Length == 2); // TODO: Check if language code is valid ISO 639-1 code
68+
.Must(x =>
69+
{
70+
return !string.IsNullOrEmpty(x) && x.Length == 2 && knownLanguageCodes.Contains(x);
71+
}).WithMessage("WorkingLanguage(s) are not valid");
6872
}
6973
}
7074

7175
public sealed class OccupationsValidator : AbstractValidator<List<Request.Occupation>>
7276
{
73-
private readonly IOccupationsFlatRepository _occupationsFlatRepository;
74-
7577
public OccupationsValidator(IOccupationsFlatRepository occupationsFlatRepository)
7678
{
77-
_occupationsFlatRepository = occupationsFlatRepository;
79+
var knownOccupations = occupationsFlatRepository.GetAllOccupationsFlat().Result;
7880

7981
RuleFor(occupations => occupations)
80-
.MustAsync(async (occupations, cancellationToken) =>
82+
.Must((occupations, cancellationToken) =>
8183
{
8284
if (occupations is null || !occupations.Any()) return true;
8385

84-
var knownOccupations = await _occupationsFlatRepository.GetAllOccupationsFlat();
8586
return occupations.Any(x =>
8687
{
8788
var occupation = knownOccupations.FirstOrDefault(y => y.Notation == x.EscoCode);
@@ -91,12 +92,35 @@ public OccupationsValidator(IOccupationsFlatRepository occupationsFlatRepository
9192
}
9293
}
9394

95+
public sealed class LanguageSkillsValidator : AbstractValidator<List<Request.LanguageSkill>>
96+
{
97+
public LanguageSkillsValidator(ILanguageRepository languagesRepository)
98+
{
99+
var knownLanguages = languagesRepository.GetAllLanguages().Result;
100+
var knownLanguageCodes = knownLanguages.Select(x => x.TwoLetterISOLanguageName).ToList();
101+
102+
RuleFor(languageSkills => languageSkills)
103+
.Must((languageSkills, cancellationToken) =>
104+
{
105+
if (languageSkills is null || !languageSkills.Any()) return true;
106+
107+
return languageSkills.Any(x =>
108+
{
109+
var language = knownLanguages.FirstOrDefault(y => y.TwoLetterISOLanguageName == x.LanguageCode);
110+
return language != null;
111+
});
112+
}).WithMessage("LanguageSkills are not valid");
113+
}
114+
}
115+
94116
public class CommandValidator : AbstractValidator<Command>
95117
{
96-
public CommandValidator()
118+
public CommandValidator(ILanguageRepository languagesRepository, IOccupationsFlatRepository occupationsFlatRepository)
97119
{
98120
RuleFor(command => command.User.PersonId).NotNull().NotEmpty();
99-
RuleFor(command => command.WorkPreferences).SetValidator(new WorkPreferencesValidator());
121+
RuleFor(command => command.WorkPreferences).SetValidator(new WorkPreferencesValidator(languagesRepository));
122+
RuleFor(command => command.Occupations).SetValidator(new OccupationsValidator(occupationsFlatRepository));
123+
RuleFor(command => command.LanguageSkills).SetValidator(new LanguageSkillsValidator(languagesRepository));
100124
}
101125
}
102126
}
@@ -105,21 +129,15 @@ public class Handler : IRequestHandler<Command, Request>
105129
{
106130
private readonly UsersDbContext _context;
107131
private readonly AnalyticsLogger<Handler> _logger;
108-
private readonly IOccupationsFlatRepository _occupationsFlatRepository;
109132

110-
public Handler(UsersDbContext context, AnalyticsLoggerFactory loggerFactory, IOccupationsFlatRepository occupationsFlatRepository)
133+
public Handler(UsersDbContext context, AnalyticsLoggerFactory loggerFactory)
111134
{
112135
_context = context;
113136
_logger = loggerFactory.CreateAnalyticsLogger<Handler>();
114-
_occupationsFlatRepository = occupationsFlatRepository;
115137
}
116138

117139
public async Task<Request> Handle(Command command, CancellationToken cancellationToken)
118140
{
119-
// Validate command async parts
120-
var validator = new Command.OccupationsValidator(_occupationsFlatRepository);
121-
await validator.ValidateAndThrowAsync(command.Occupations, cancellationToken);
122-
123141
var person = await _context.Persons
124142
.Include(p => p.Occupations)
125143
.Include(p => p.Educations)

VirtualFinland.UserAPI/src/VirtualFinland.UsersAPI/Models/Repositories/Language.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ public record class Language
77
{
88
[JsonPropertyName("id")]
99
public string? Id { get; set; }
10+
11+
[JsonPropertyName("twoLetterISOLanguageName")]
12+
public string? TwoLetterISOLanguageName { get; set; }
1013
}

0 commit comments

Comments
 (0)