feat: implement building alias and comment tables
This commit is contained in:
@@ -2,10 +2,24 @@ namespace SanctionsSearch.Worker.Tests.Integration;
|
|||||||
|
|
||||||
public class DatabaseMaintainerTests : DatabaseTest
|
public class DatabaseMaintainerTests : DatabaseTest
|
||||||
{
|
{
|
||||||
|
private const string TestSdnCsv = """
|
||||||
|
6906,"AL-IRAQI, Abd al-Hadi","individual","SDGT",-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,"DOB 1961; POB Mosul, Iraq; nationality Iraq; Gender Male."
|
||||||
|
6907,"SHIHATA, Thirwat Salah","individual","SDGT",-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,"DOB 29 Jun 1960; POB Egypt."
|
||||||
|
6908,"AHMAD, Tariq Anwar al-Sayyid","individual","SDGT",-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,"DOB 15 Mar 1963; POB Alexandria, Egypt."
|
||||||
|
""";
|
||||||
private const string TestAddressCsv = """
|
private const string TestAddressCsv = """
|
||||||
306,201,"Dai-Ichi Bldg. 6th Floor, 10-2 Nihombashi, 2-chome, Chuo-ku","Tokyo 103","Japan",-0-
|
306,201,"Dai-Ichi Bldg. 6th Floor, 10-2 Nihombashi, 2-chome, Chuo-ku","Tokyo 103","Japan",-0-
|
||||||
306,202,"Federico Boyd Avenue & 51 Street","Panama City","Panama",-0-
|
306,202,"Federico Boyd Avenue & 51 Street","Panama City","Panama",-0-
|
||||||
""";
|
""";
|
||||||
|
private const string TestAliasCsv = """
|
||||||
|
555,477,"aka","COPROVA",-0-
|
||||||
|
555,478,"aka","COPROVA SARL",-0-
|
||||||
|
""";
|
||||||
|
private const string TestCommentCsv = """
|
||||||
|
27307,"G TEAM'; a.k.a. 'RED DOT'; a.k.a. 'TEMP.HERMIT'; a.k.a. 'GROUP 77'; a.k.a. 'ZINC'; a.k.a. 'APT-C-26'; a.k.a. 'APPLEWORM'."
|
||||||
|
28263,"hn'; Linked To: LAZARUS GROUP."
|
||||||
|
""";
|
||||||
|
|
||||||
private readonly MockHttpMessageHandler _mockHttp = new();
|
private readonly MockHttpMessageHandler _mockHttp = new();
|
||||||
private readonly OfacFileServiceOptionsFaker _ofacFileServiceOptionsFaker = new();
|
private readonly OfacFileServiceOptionsFaker _ofacFileServiceOptionsFaker = new();
|
||||||
private readonly OfacFileServiceOptions _ofacFileServiceOptions;
|
private readonly OfacFileServiceOptions _ofacFileServiceOptions;
|
||||||
@@ -30,13 +44,7 @@ public class DatabaseMaintainerTests : DatabaseTest
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task BuildSdnTableAsync_WhenCalled_ItShouldAddSdnCsvRecordsToDatabase()
|
public async Task BuildSdnTableAsync_WhenCalled_ItShouldAddSdnCsvRecordsToDatabase()
|
||||||
{
|
{
|
||||||
var testCsv = """
|
using var testStream = CreateCsvStream(TestSdnCsv);
|
||||||
6906,"AL-IRAQI, Abd al-Hadi","individual","SDGT",-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,"DOB 1961; POB Mosul, Iraq; nationality Iraq; Gender Male."
|
|
||||||
6907,"SHIHATA, Thirwat Salah","individual","SDGT",-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,"DOB 29 Jun 1960; POB Egypt."
|
|
||||||
6908,"AHMAD, Tariq Anwar al-Sayyid","individual","SDGT",-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,-0- ,"DOB 15 Mar 1963; POB Alexandria, Egypt."
|
|
||||||
""";
|
|
||||||
|
|
||||||
var testStream = CreateCsvStream(testCsv);
|
|
||||||
|
|
||||||
_mockHttp
|
_mockHttp
|
||||||
.When(_ofacFileServiceOptions.GetSdnFileUri().ToString())
|
.When(_ofacFileServiceOptions.GetSdnFileUri().ToString())
|
||||||
@@ -91,7 +99,7 @@ public class DatabaseMaintainerTests : DatabaseTest
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task BuildAddressTableAsync_WhenCalledAndNoSdnRecordFound_ItShouldNotAddAddressCsvRecordsToDatabase()
|
public async Task BuildAddressTableAsync_WhenCalledAndNoSdnRecordFound_ItShouldNotAddAddressCsvRecordsToDatabase()
|
||||||
{
|
{
|
||||||
var testStream = CreateCsvStream(TestAddressCsv);
|
using var testStream = CreateCsvStream(TestAddressCsv);
|
||||||
|
|
||||||
_mockHttp
|
_mockHttp
|
||||||
.When(_ofacFileServiceOptions.GetAddressFileUri().ToString())
|
.When(_ofacFileServiceOptions.GetAddressFileUri().ToString())
|
||||||
@@ -107,7 +115,7 @@ public class DatabaseMaintainerTests : DatabaseTest
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task BuildAddressTableAsync_WhenCalledAndSdnRecordFound_ItShouldAddAddressCsvRecordsToDatabase()
|
public async Task BuildAddressTableAsync_WhenCalledAndSdnRecordFound_ItShouldAddAddressCsvRecordsToDatabase()
|
||||||
{
|
{
|
||||||
var testStream = CreateCsvStream(TestAddressCsv);
|
using var testStream = CreateCsvStream(TestAddressCsv);
|
||||||
|
|
||||||
_mockHttp
|
_mockHttp
|
||||||
.When(_ofacFileServiceOptions.GetAddressFileUri().ToString())
|
.When(_ofacFileServiceOptions.GetAddressFileUri().ToString())
|
||||||
@@ -154,4 +162,121 @@ public class DatabaseMaintainerTests : DatabaseTest
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task BuildAliasTableAsync_WhenCalledAndSdnRecordNotFound_ItShouldNotAddAliasCsvRecordsToDatabase()
|
||||||
|
{
|
||||||
|
using var testStream = CreateCsvStream(TestAliasCsv);
|
||||||
|
|
||||||
|
_mockHttp
|
||||||
|
.When(_ofacFileServiceOptions.GetAltNamesFileUri().ToString())
|
||||||
|
.Respond("text/csv", testStream);
|
||||||
|
|
||||||
|
await _databaseMaintainer.BuiltAliasTableAsync();
|
||||||
|
|
||||||
|
var aliases = await _context.Set<Alias>().ToListAsync();
|
||||||
|
|
||||||
|
aliases.Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task BuildAliasTableAsync_WhenCalledAndSdnRecordFound_ItShouldAddAliasCsvRecordsToDatabase()
|
||||||
|
{
|
||||||
|
using var testStream = CreateCsvStream(TestAliasCsv);
|
||||||
|
|
||||||
|
_mockHttp
|
||||||
|
.When(_ofacFileServiceOptions.GetAltNamesFileUri().ToString())
|
||||||
|
.Respond("text/csv", testStream);
|
||||||
|
|
||||||
|
var now = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
_timeProviderMock
|
||||||
|
.Setup(x => x.GetUtcNow())
|
||||||
|
.Returns(now);
|
||||||
|
|
||||||
|
var sdn = new Sdn() { Id = 555 };
|
||||||
|
await _context.Set<Sdn>().AddAsync(sdn);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
await _databaseMaintainer.BuiltAliasTableAsync();
|
||||||
|
|
||||||
|
var aliases = await _context.Set<Alias>().ToListAsync();
|
||||||
|
|
||||||
|
aliases.Should().BeEquivalentTo(new[]
|
||||||
|
{
|
||||||
|
new Alias()
|
||||||
|
{
|
||||||
|
SdnId = sdn.Id,
|
||||||
|
Id = 477,
|
||||||
|
Name = "COPROVA",
|
||||||
|
Type = "aka",
|
||||||
|
CreatedAt = now.DateTime,
|
||||||
|
UpdatedAt = now.DateTime,
|
||||||
|
Sdn = sdn
|
||||||
|
},
|
||||||
|
new Alias()
|
||||||
|
{
|
||||||
|
SdnId = sdn.Id,
|
||||||
|
Id = 478,
|
||||||
|
Name = "COPROVA SARL",
|
||||||
|
Type = "aka",
|
||||||
|
CreatedAt = now.DateTime,
|
||||||
|
UpdatedAt = now.DateTime,
|
||||||
|
Sdn = sdn
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task BuildCommentTableAsync_WhenCalledAndSdnRecordNotFound_ItShouldNotAddCommentCsvRecordsToDatabase()
|
||||||
|
{
|
||||||
|
using var testStream = CreateCsvStream(TestCommentCsv);
|
||||||
|
|
||||||
|
_mockHttp
|
||||||
|
.When(_ofacFileServiceOptions.GetCommentsFileUri().ToString())
|
||||||
|
.Respond("text/csv", testStream);
|
||||||
|
|
||||||
|
await _databaseMaintainer.BuildCommentTableAsync();
|
||||||
|
|
||||||
|
var comments = await _context.Set<Comment>().ToListAsync();
|
||||||
|
|
||||||
|
comments.Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task BuildCommentTableAsync_WhenCalledAndSdnRecordFound_ItShouldAddCommentCsvRecordsToDatabase()
|
||||||
|
{
|
||||||
|
using var testStream = CreateCsvStream(TestCommentCsv);
|
||||||
|
|
||||||
|
_mockHttp
|
||||||
|
.When(_ofacFileServiceOptions.GetCommentsFileUri().ToString())
|
||||||
|
.Respond("text/csv", testStream);
|
||||||
|
|
||||||
|
var now = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
_timeProviderMock
|
||||||
|
.Setup(x => x.GetUtcNow())
|
||||||
|
.Returns(now);
|
||||||
|
|
||||||
|
var sdn = new Sdn() { Id = 27307 };
|
||||||
|
await _context.Set<Sdn>().AddAsync(sdn);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
await _databaseMaintainer.BuildCommentTableAsync();
|
||||||
|
|
||||||
|
var comments = await _context.Set<Comment>().ToListAsync();
|
||||||
|
|
||||||
|
comments.Should().BeEquivalentTo(new[]
|
||||||
|
{
|
||||||
|
new Comment()
|
||||||
|
{
|
||||||
|
SdnId = sdn.Id,
|
||||||
|
Id = 1,
|
||||||
|
Remarks = "G TEAM'; a.k.a. 'RED DOT'; a.k.a. 'TEMP.HERMIT'; a.k.a. 'GROUP 77'; a.k.a. 'ZINC'; a.k.a. 'APT-C-26'; a.k.a. 'APPLEWORM'.",
|
||||||
|
CreatedAt = now.DateTime,
|
||||||
|
UpdatedAt = now.DateTime,
|
||||||
|
Sdn = sdn
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace SanctionsSearch.Worker.Models;
|
||||||
|
|
||||||
|
class AliasMap : ClassMap<Alias>
|
||||||
|
{
|
||||||
|
public AliasMap()
|
||||||
|
{
|
||||||
|
Map(m => m.SdnId).Index(0);
|
||||||
|
Map(m => m.Id).Index(1);
|
||||||
|
Map(m => m.Type).Index(2).TypeConverter<NullCharacterConverter>();
|
||||||
|
Map(m => m.Name).Index(3).TypeConverter<NullCharacterConverter>();
|
||||||
|
Map(m => m.Remarks).Index(4).TypeConverter<NullCharacterConverter>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace SanctionsSearch.Worker.Models;
|
||||||
|
|
||||||
|
class CommentMap : ClassMap<Comment>
|
||||||
|
{
|
||||||
|
public CommentMap()
|
||||||
|
{
|
||||||
|
Map(m => m.SdnId).Index(0);
|
||||||
|
Map(m => m.Remarks).Index(1).TypeConverter<NullCharacterConverter>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,8 @@ class DatabaseMaintainer(
|
|||||||
|
|
||||||
csv.Context.RegisterClassMap<SdnMap>();
|
csv.Context.RegisterClassMap<SdnMap>();
|
||||||
csv.Context.RegisterClassMap<AddressMap>();
|
csv.Context.RegisterClassMap<AddressMap>();
|
||||||
|
csv.Context.RegisterClassMap<AliasMap>();
|
||||||
|
csv.Context.RegisterClassMap<CommentMap>();
|
||||||
|
|
||||||
_streamReaders.Add(reader);
|
_streamReaders.Add(reader);
|
||||||
_csvReaders.Add(csv);
|
_csvReaders.Add(csv);
|
||||||
@@ -77,14 +79,62 @@ class DatabaseMaintainer(
|
|||||||
await _unitOfWork.SaveChangesAsync();
|
await _unitOfWork.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task BuildCommentTableAsync()
|
public async Task BuiltAliasTableAsync()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var result = await _ofacFileService.GetAltNamesFileAsync();
|
||||||
|
|
||||||
|
if (result.IsFailed)
|
||||||
|
{
|
||||||
|
_logger.LogError("Failed to get Alias file from OFAC.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var stream = result.Value;
|
||||||
|
var records = GetRecordsFromStream<Alias>(stream);
|
||||||
|
|
||||||
|
foreach (var record in records)
|
||||||
|
{
|
||||||
|
var sdn = await _unitOfWork.Sdns.Find(s => s.Id == record.SdnId);
|
||||||
|
|
||||||
|
if (sdn.Count() is 0)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Alias's SDN with ID {Id} not found. Skipping alias.", record.SdnId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _unitOfWork.Aliases.Upsert(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
await _unitOfWork.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task BuiltAliasTableAsync()
|
public async Task BuildCommentTableAsync()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var result = await _ofacFileService.GetCommentsFileAsync();
|
||||||
|
|
||||||
|
if (result.IsFailed)
|
||||||
|
{
|
||||||
|
_logger.LogError("Failed to get Comment file from OFAC.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var stream = result.Value;
|
||||||
|
var records = GetRecordsFromStream<Comment>(stream);
|
||||||
|
|
||||||
|
foreach (var record in records)
|
||||||
|
{
|
||||||
|
var sdn = await _unitOfWork.Sdns.Find(s => s.Id == record.SdnId);
|
||||||
|
|
||||||
|
if (sdn.Count() is 0)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Comment's SDN with ID {Id} not found. Skipping comment.", record.SdnId);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _unitOfWork.Comments.Upsert(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
await _unitOfWork.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
Reference in New Issue
Block a user