Enrich administrative profiles from SGU
This commit is contained in:
@@ -56,6 +56,100 @@ public sealed class SguProfileParserTests
|
||||
Assert.Null(SguProfileParser.ParseAdministrative(html, "999999"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParsesStructuredAdministrativeNameWithoutReadingOtherPersonalData()
|
||||
{
|
||||
const string html = """
|
||||
<html><body>
|
||||
<input id="ctl00_contenedor_txtNombre" value="MARÍA DEL CARMEN" />
|
||||
<input id="ctl00_contenedor_txtApaterno" value="DE LA FUENTE" />
|
||||
<input id="ctl00_contenedor_txtAmaterno" value="O'CONNOR" />
|
||||
<input id="ctl00_contenedor_txtCURP" value="DATO-QUE-NO-DEBE-EXTRAERSE" />
|
||||
<select id="ctl00_contenedor_ddlNacimientoFecha_ddlYear">
|
||||
<option selected="selected">1990</option>
|
||||
</select>
|
||||
</body></html>
|
||||
""";
|
||||
|
||||
InstitutionalProfile? profile = SguProfileParser.ParseAdministrativePersonal(html);
|
||||
|
||||
Assert.NotNull(profile);
|
||||
Assert.Equal("María del Carmen", profile.GivenName);
|
||||
Assert.Equal("de la Fuente O'Connor", profile.Surname);
|
||||
Assert.Equal("María del Carmen de la Fuente O'Connor", profile.DisplayName);
|
||||
Assert.Null(profile.EmployeeNumber);
|
||||
Assert.Null(profile.Email);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParsesAdministrativeAddressFromInputsAndSelectedOptions()
|
||||
{
|
||||
const string html = """
|
||||
<html><body>
|
||||
<input id='ctl00_contenedor_txtCalle' value='AVENIDA DE LA UNIVERSIDAD' />
|
||||
<input id='ctl00_contenedor_txtNoExt' value='123' />
|
||||
<input id='ctl00_contenedor_txtNoInt' value='B-4' />
|
||||
<input id='ctl00_contenedor_txtCP' value='8500' />
|
||||
<select id='ctl00_contenedor_ddlEstado'>
|
||||
<option value='0'>Seleccione...</option>
|
||||
<option selected='selected' value='9'>CIUDAD DE MÉXICO</option>
|
||||
</select>
|
||||
<select id='ctl00_contenedor_ddlLocalidad'>
|
||||
<option value='1'>AZCAPOTZALCO</option>
|
||||
<option selected='selected' value='4'>BENITO JUÁREZ</option>
|
||||
</select>
|
||||
<select id='ctl00_contenedor_ddlColonia'>
|
||||
<option value='10'>COLONIA DEL VALLE</option>
|
||||
</select>
|
||||
<input id='ctl00_contenedor_txtTelefono' value='5555555555' />
|
||||
<textarea id='ctl00_contenedor_txtDirEmergencia'>NO EXTRAER</textarea>
|
||||
</body></html>
|
||||
""";
|
||||
|
||||
InstitutionalProfile? profile = SguProfileParser.ParseAdministrativeLocation(html);
|
||||
|
||||
Assert.NotNull(profile);
|
||||
Assert.Equal(
|
||||
"Avenida de la Universidad 123, Int. B-4\r\nColonia del Valle",
|
||||
profile.StreetAddress);
|
||||
Assert.Equal("Benito Juárez", profile.City);
|
||||
Assert.Equal("Ciudad de México", profile.State);
|
||||
Assert.Equal("08500", profile.PostalCode);
|
||||
Assert.Null(profile.Email);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AdministrativePagesOverlayTheVerifiedIncidentsProfile()
|
||||
{
|
||||
InstitutionalProfile verified = new(
|
||||
EmployeeNumber: "017045",
|
||||
DisplayName: "Nombre Anterior",
|
||||
Email: "persona@lasalle.mx",
|
||||
JobTitle: "Analista",
|
||||
Department: "Ingeniería");
|
||||
InstitutionalProfile personal = new(
|
||||
DisplayName: "María del Carmen de la Fuente",
|
||||
GivenName: "María del Carmen",
|
||||
Surname: "de la Fuente");
|
||||
InstitutionalProfile location = new(
|
||||
StreetAddress: "Calle Uno 10",
|
||||
City: "Ciudad de México",
|
||||
State: "Ciudad de México",
|
||||
PostalCode: "01000");
|
||||
|
||||
InstitutionalProfile combined = verified.Overlay(personal).Overlay(location);
|
||||
|
||||
Assert.Equal("017045", combined.EmployeeNumber);
|
||||
Assert.Equal("María del Carmen de la Fuente", combined.DisplayName);
|
||||
Assert.Equal("María del Carmen", combined.GivenName);
|
||||
Assert.Equal("de la Fuente", combined.Surname);
|
||||
Assert.Equal("persona@lasalle.mx", combined.Email);
|
||||
Assert.Equal("Analista", combined.JobTitle);
|
||||
Assert.Equal("Ingeniería", combined.Department);
|
||||
Assert.Equal("Calle Uno 10", combined.StreetAddress);
|
||||
Assert.Equal("01000", combined.PostalCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParsesTheRequiredStudentIdentityCareerAndAddressFields()
|
||||
{
|
||||
|
||||
@@ -11,6 +11,12 @@ namespace SGU.AuthBroker.Tests;
|
||||
|
||||
public sealed class NtlmCredentialValidatorTests
|
||||
{
|
||||
private static readonly UserIdentity Administrative = new(
|
||||
"AD017045",
|
||||
"AD",
|
||||
"017045",
|
||||
InstitutionalRole.Administrative);
|
||||
|
||||
private static readonly UserIdentity Student = new(
|
||||
"AL123456",
|
||||
"AL",
|
||||
@@ -101,6 +107,91 @@ public sealed class NtlmCredentialValidatorTests
|
||||
handler.RequestPaths[4]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task VerifiedAdministrativeProfileIsEnrichedFromPersonalAndLocationPages()
|
||||
{
|
||||
SequenceHandler handler = new(
|
||||
Challenge(),
|
||||
Response(HttpStatusCode.OK),
|
||||
Response(
|
||||
HttpStatusCode.OK,
|
||||
"""
|
||||
<span id="ctl00_contenedor_decEncabezado_lblNombre">017045 - NOMBRE ANTERIOR</span>
|
||||
<span id="ctl00_contenedor_decEncabezado_lblCorreo">persona@lasalle.mx</span>
|
||||
<span id="ctl00_contenedor_decEncabezado_lblPuesto">ANALISTA</span>
|
||||
"""),
|
||||
Response(
|
||||
HttpStatusCode.OK,
|
||||
"""
|
||||
<input id="ctl00_contenedor_txtNombre" value="MARÍA DEL CARMEN" />
|
||||
<input id="ctl00_contenedor_txtApaterno" value="DE LA FUENTE" />
|
||||
<input id="ctl00_contenedor_txtAmaterno" value="O'CONNOR" />
|
||||
"""),
|
||||
Response(
|
||||
HttpStatusCode.OK,
|
||||
"""
|
||||
<input id="ctl00_contenedor_txtCalle" value="CALLE DEL SOL" />
|
||||
<input id="ctl00_contenedor_txtNoExt" value="15" />
|
||||
<input id="ctl00_contenedor_txtCP" value="01000" />
|
||||
<select id="ctl00_contenedor_ddlEstado">
|
||||
<option selected="selected">CIUDAD DE MÉXICO</option>
|
||||
</select>
|
||||
<select id="ctl00_contenedor_ddlLocalidad">
|
||||
<option selected="selected">ÁLVARO OBREGÓN</option>
|
||||
</select>
|
||||
<select id="ctl00_contenedor_ddlColonia">
|
||||
<option>FLORIDA</option>
|
||||
</select>
|
||||
"""));
|
||||
NtlmCredentialValidator validator = CreateValidator(handler);
|
||||
|
||||
NtlmValidationResult result = await validator.ValidateAsync(
|
||||
Administrative,
|
||||
"test-password",
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(NtlmValidationStatus.Valid, result.Status);
|
||||
Assert.NotNull(result.Profile);
|
||||
Assert.Equal("017045", result.Profile.EmployeeNumber);
|
||||
Assert.Equal("María del Carmen de la Fuente O'Connor", result.Profile.DisplayName);
|
||||
Assert.Equal("María del Carmen", result.Profile.GivenName);
|
||||
Assert.Equal("de la Fuente O'Connor", result.Profile.Surname);
|
||||
Assert.Equal("persona@lasalle.mx", result.Profile.Email);
|
||||
Assert.Equal("Analista", result.Profile.JobTitle);
|
||||
Assert.Equal("Calle del Sol 15\r\nFlorida", result.Profile.StreetAddress);
|
||||
Assert.Equal("Álvaro Obregón", result.Profile.City);
|
||||
Assert.Equal("Ciudad de México", result.Profile.State);
|
||||
Assert.Equal("01000", result.Profile.PostalCode);
|
||||
Assert.Equal(
|
||||
[
|
||||
"/psulsa/",
|
||||
"/psulsa/",
|
||||
"/psulsa/gadmon/capitalhumano/controlincidencias/incidencias.aspx",
|
||||
"/psulsa/gadmon/capitalhumano/datos/personales.aspx",
|
||||
"/psulsa/gadmon/capitalhumano/datos/ubicacion.aspx"
|
||||
],
|
||||
handler.RequestPaths);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AdministrativeSupplementalPagesRequireAVerifiedEmployeeNumber()
|
||||
{
|
||||
SequenceHandler handler = new(
|
||||
Challenge(),
|
||||
Response(HttpStatusCode.OK),
|
||||
Response(HttpStatusCode.OK, "<html><body>Datos inesperados</body></html>"));
|
||||
NtlmCredentialValidator validator = CreateValidator(handler);
|
||||
|
||||
NtlmValidationResult result = await validator.ValidateAsync(
|
||||
Administrative,
|
||||
"test-password",
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.Equal(NtlmValidationStatus.Valid, result.Status);
|
||||
Assert.Null(result.Profile);
|
||||
Assert.Equal(3, handler.RequestPaths.Count);
|
||||
}
|
||||
|
||||
private static NtlmCredentialValidator CreateValidator(SequenceHandler handler)
|
||||
{
|
||||
BrokerOptions options = new()
|
||||
@@ -109,6 +200,9 @@ public sealed class NtlmCredentialValidatorTests
|
||||
{
|
||||
Endpoint = "https://sgu.example/",
|
||||
AuthenticationPath = "/psulsa/",
|
||||
AdministrativeProfilePath = "/psulsa/gadmon/capitalhumano/controlincidencias/incidencias.aspx",
|
||||
AdministrativePersonalProfilePath = "/psulsa/gadmon/capitalhumano/datos/personales.aspx",
|
||||
AdministrativeLocationProfilePath = "/psulsa/gadmon/capitalhumano/datos/ubicacion.aspx",
|
||||
StudentProfilePath = "/psulsa/alumnos/consultainformacionalumnos/consultainformacion.aspx",
|
||||
AllowedRedirectHosts = ["sgu.example"],
|
||||
TimeoutSeconds = 5,
|
||||
@@ -136,10 +230,12 @@ public sealed class NtlmCredentialValidatorTests
|
||||
return response;
|
||||
}
|
||||
|
||||
private static HttpResponseMessage Response(HttpStatusCode statusCode) =>
|
||||
private static HttpResponseMessage Response(
|
||||
HttpStatusCode statusCode,
|
||||
string content = "<html></html>") =>
|
||||
new(statusCode)
|
||||
{
|
||||
Content = new StringContent("<html></html>")
|
||||
Content = new StringContent(content)
|
||||
};
|
||||
|
||||
private sealed class SequenceHandler(params HttpResponseMessage[] responses) : HttpMessageHandler
|
||||
|
||||
Reference in New Issue
Block a user