Skip to content

Commit 5345856

Browse files
authored
DC-245 Update test scenarios and create DC specific test cases (#134)
* Update test scenarios and create DC specific test cases * Update expiriation from PR feedback
1 parent e804053 commit 5345856

File tree

7 files changed

+101
-27
lines changed

7 files changed

+101
-27
lines changed

src/SEBT.Portal.Api/appsettings.co.example.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"PreferredHouseholdIdTypes": ["Phone"]
1313
},
1414
"Seeding": {
15-
"EmailPattern": "sebt.co+{0}@codeforamerica.org"
15+
"EmailPattern": "sebt.co+{0}@codeforamerica.org",
16+
"State": "co"
1617
},
1718
"Oidc": {
1819
"CompleteLoginSigningKey": "SAME_VALUE_AS_NEXT_JS_OIDC_COMPLETE_LOGIN_SIGNING_KEY_AT_LEAST_32_CHARS",

src/SEBT.Portal.Api/appsettings.dc.example.json

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"PreferredHouseholdIdTypes": ["Email"]
1515
},
1616
"Seeding": {
17-
"EmailPattern": "sebt.dc+{0}@codeforamerica.org"
17+
"EmailPattern": "sebt.dc+{0}@codeforamerica.org",
18+
"State": "dc"
1819
},
1920
"AddressValidationPolicy": {
2021
"AllowGeneralDelivery": true
@@ -38,22 +39,5 @@
3839
"show_application_number": false,
3940
"show_case_number": false,
4041
"show_card_last4": false
41-
},
42-
"PluginAssemblyPaths": ["plugins-dc"],
43-
"DCConnector": {
44-
"ConnectionString": "Server=localhost,1434;Database=DcSource;User Id=sa;Password=YOUR_PASSWORD;TrustServerCertificate=True;"
45-
},
46-
"EmailOtpSenderServiceSettings": {
47-
"SenderEmail": "noreply@sunbucks.dc.gov",
48-
"SenderName": "DC SUN Bucks",
49-
"Subject": "Your DC SUN Bucks Login Code",
50-
"ProgramName": "DC SUN Bucks",
51-
"StateName": "DC SUN Bucks"
52-
},
53-
"StateHouseholdId": {
54-
"PreferredHouseholdIdTypes": [" Email"]
55-
},
56-
"Seeding": {
57-
"EmailPattern": "sebt.dc+{0}@codeforamerica.org"
5842
}
5943
}

src/SEBT.Portal.Core/AppSettings/SeedingSettings.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ public class SeedingSettings
3030
/// </summary>
3131
public bool Enabled { get; set; }
3232

33+
/// <summary>
34+
/// The state code (e.g., "dc", "co") from the STATE environment variable.
35+
/// Used to conditionally seed state-specific scenarios.
36+
/// </summary>
37+
public string? State { get; set; }
38+
3339
/// <summary>
3440
/// Constructs a full email address from a scenario name using the configured pattern.
3541
/// </summary>

src/SEBT.Portal.Core/Seeding/SeedScenarios.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,32 @@ public static class SeedScenarios
3030
// Household-only scenario (not seeded as a User in the database)
3131
public static readonly SeedScenario MultipleApps = new("multipleapps", UserIalLevel.None);
3232

33+
// Simple scenarios (non-co-loaded, Summer EBT, active benefits)
34+
public static readonly SeedScenario Simple1 = new("simple1", UserIalLevel.None);
35+
public static readonly SeedScenario Simple2 = new("simple2", UserIalLevel.None);
36+
public static readonly SeedScenario Simple3 = new("simple3", UserIalLevel.None);
37+
public static readonly SeedScenario Simple4 = new("simple4", UserIalLevel.None);
38+
public static readonly SeedScenario Simple5 = new("simple5", UserIalLevel.None);
39+
public static readonly SeedScenario Simple6 = new("simple6", UserIalLevel.None);
40+
public static readonly SeedScenario Simple7 = new("simple7", UserIalLevel.None);
41+
3342
/// <summary>
3443
/// Scenarios that are seeded as User entities in the database.
3544
/// </summary>
3645
public static readonly IReadOnlyList<SeedScenario> UserScenarios =
3746
[
3847
CoLoaded, Verified, SingleChild, LargeFamily, Expired,
3948
NonCoLoaded, NotStarted, Pending, Minimal, Denied,
40-
Review, Cancelled, Unknown
49+
Review, Cancelled, Unknown,
50+
Simple1, Simple2, Simple3, Simple4, Simple5, Simple6, Simple7
4151
];
4252

53+
/// <summary>
54+
/// Scenarios that should only be seeded when STATE=dc.
55+
/// </summary>
56+
public static readonly IReadOnlySet<SeedScenario> DcOnlyScenarios =
57+
new HashSet<SeedScenario> { Simple1, Simple2, Simple3, Simple4, Simple5, Simple6, Simple7 };
58+
4359
/// <summary>
4460
/// All scenarios including household-only entries (e.g., MultipleApps).
4561
/// </summary>

src/SEBT.Portal.Infrastructure.Seeding/Services/DatabaseSeeder.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public class DatabaseSeeder : Core.Services.IDatabaseSeeder
2525
private const int DaysSinceBasicIdProofingCompleted = -10;
2626
private const int DaysUntilBasicIdProofingExpires = 355;
2727

28+
private bool IsDc => string.Equals(_settings.State, "dc", StringComparison.OrdinalIgnoreCase);
29+
2830
public DatabaseSeeder(
2931
IDataSeeder dataSeeder,
3032
SeedingSettings? settings = null,
@@ -125,6 +127,12 @@ public async Task SeedTestUsersAsync(bool useMockHouseholdData, CancellationToke
125127

126128
foreach (var scenario in SeedScenarios.UserScenarios)
127129
{
130+
// Skip DC-only scenarios when not running as DC
131+
if (!IsDc && SeedScenarios.DcOnlyScenarios.Contains(scenario))
132+
{
133+
continue;
134+
}
135+
128136
var normalizedEmail = EmailNormalizer.Normalize(_settings.BuildEmail(scenario.Name));
129137

130138
var existingEmails = await _dataSeeder.GetExistingUserEmailsAsync(new[] { normalizedEmail }, cancellationToken);
@@ -253,9 +261,14 @@ public void SeedTestUsers(bool useMockHouseholdData)
253261
{
254262
var coLoadedEmail = EmailNormalizer.Normalize(_settings.BuildEmail(SeedScenarios.CoLoaded.Name));
255263
var verifiedEmail = EmailNormalizer.Normalize(_settings.BuildEmail(SeedScenarios.Verified.Name));
256-
257264
foreach (var scenario in SeedScenarios.UserScenarios)
258265
{
266+
// Skip DC-only scenarios when not running as DC
267+
if (!IsDc && SeedScenarios.DcOnlyScenarios.Contains(scenario))
268+
{
269+
continue;
270+
}
271+
259272
var normalizedEmail = EmailNormalizer.Normalize(_settings.BuildEmail(scenario.Name));
260273

261274
var existingEmails = _dataSeeder.GetExistingUserEmails(new[] { normalizedEmail });

src/SEBT.Portal.Infrastructure/Repositories/MockHouseholdRepository.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ private void SeedMockData()
150150
app.BenefitIssueDate = now.AddDays(-20);
151151
app.BenefitExpirationDate = now.AddDays(70);
152152
app.Last4DigitsOfCard = "0000";
153+
app.CardStatus = CardStatus.Active;
153154
// Set specific children names for test
154155
app.Children = new List<Child>
155156
{
@@ -183,6 +184,7 @@ private void SeedMockData()
183184
app.BenefitIssueDate = now.AddDays(-30);
184185
app.BenefitExpirationDate = now.AddDays(60);
185186
app.Last4DigitsOfCard = "1234"; // Specific value for test
187+
app.CardStatus = CardStatus.Active;
186188
// Set specific children names for test
187189
app.Children = new List<Child>
188190
{
@@ -259,6 +261,7 @@ private void SeedMockData()
259261
var app = h.Applications.FirstOrDefault();
260262
if (app != null)
261263
{
264+
app.CardStatus = CardStatus.Active;
262265
// Use Bogus to generate child name
263266
var childFaker = new Faker<Child>()
264267
.RuleFor(c => c.FirstName, f => f.Name.FirstName())
@@ -346,6 +349,7 @@ private void SeedMockData()
346349
{
347350
app.BenefitIssueDate = now.AddDays(-15);
348351
app.BenefitExpirationDate = now.AddDays(75);
352+
app.CardStatus = CardStatus.Active;
349353
// Use Bogus to generate child name
350354
var childFaker = new Faker<Child>()
351355
.RuleFor(c => c.FirstName, f => f.Name.FirstName())
@@ -369,6 +373,7 @@ private void SeedMockData()
369373
app.BenefitIssueDate = now.AddDays(-45);
370374
app.BenefitExpirationDate = now.AddDays(45);
371375
app.Last4DigitsOfCard = "4321";
376+
app.CardStatus = CardStatus.Active;
372377
// Set specific children names for test
373378
app.Children = new List<Child>
374379
{
@@ -419,6 +424,7 @@ private void SeedMockData()
419424
{
420425
app.BenefitIssueDate = now.AddDays(-120);
421426
app.BenefitExpirationDate = now.AddDays(-10); // Expired
427+
app.CardStatus = CardStatus.Deactivated;
422428
// Use Bogus to generate child name
423429
var childFaker = new Faker<Child>()
424430
.RuleFor(c => c.FirstName, f => f.Name.FirstName())
@@ -498,6 +504,52 @@ private void SeedMockData()
498504
_households[multipleAppsEmail] = multipleApps;
499505
IndexByPhone(multipleApps);
500506

507+
// DC Scenarios 1-7: Simple non-co-loaded households with 1 child, Summer EBT, active benefits
508+
if (string.Equals(_settings.State, "dc", StringComparison.OrdinalIgnoreCase))
509+
{
510+
var dcChildFaker = new Faker<Child>()
511+
.RuleFor(c => c.FirstName, f => f.Name.FirstName())
512+
.RuleFor(c => c.LastName, f => f.Name.LastName());
513+
514+
var dcUserFaker = new Faker();
515+
516+
SeedScenario[] dcScenarioList = [SeedScenarios.Simple1, SeedScenarios.Simple2, SeedScenarios.Simple3,
517+
SeedScenarios.Simple4, SeedScenarios.Simple5, SeedScenarios.Simple6, SeedScenarios.Simple7];
518+
519+
foreach (var dcScenario in dcScenarioList)
520+
{
521+
var dcEmail = _settings.BuildEmail(dcScenario.Name);
522+
var dcHousehold = HouseholdFactory.CreateHouseholdDataWithStatus(ApplicationStatus.Approved, h =>
523+
{
524+
h.BenefitIssuanceType = BenefitIssuanceType.SummerEbt;
525+
var app = h.Applications.FirstOrDefault();
526+
if (app != null)
527+
{
528+
app.BenefitIssueDate = now.AddDays(-20);
529+
app.BenefitExpirationDate = now.AddDays(122);
530+
app.CardStatus = CardStatus.Active;
531+
app.Children = dcChildFaker.Generate(1);
532+
}
533+
h.AddressOnFile = new Address
534+
{
535+
StreetAddress1 = dcUserFaker.Address.StreetAddress(),
536+
City = "Washington",
537+
State = "DC",
538+
PostalCode = "20002"
539+
};
540+
});
541+
dcHousehold.Email = dcEmail;
542+
dcHousehold.UserProfile = new UserProfile
543+
{
544+
FirstName = dcUserFaker.Name.FirstName(),
545+
MiddleName = null,
546+
LastName = dcUserFaker.Name.LastName()
547+
};
548+
_households[dcEmail] = dcHousehold;
549+
IndexByPhone(dcHousehold);
550+
}
551+
}
552+
501553
_logger.LogInformation("Seeded {Count} mock household records using Bogus", _households.Count);
502554
}
503555

test/SEBT.Portal.Tests/Unit/Repositories/MockHouseholdRepositoryTests.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ public MockHouseholdRepositoryTests()
3030
_repository = new MockHouseholdRepository(logger, timeProvider: _timeProvider);
3131
}
3232

33-
private static MockHouseholdRepository CreateRepository(string emailPattern)
33+
private static MockHouseholdRepository CreateRepository(string emailPattern, string? state = null)
3434
{
3535
var logger = NullLogger<MockHouseholdRepository>.Instance;
36-
var settings = Options.Create(new SeedingSettings { EmailPattern = emailPattern });
36+
var settings = Options.Create(new SeedingSettings { EmailPattern = emailPattern, State = state });
3737
return new MockHouseholdRepository(logger, settings, new FakeTimeProvider(FixedSeedTime));
3838
}
3939

@@ -242,10 +242,12 @@ public async Task GetHouseholdByEmailAsync_ReturnsCopyOfHouseholdData()
242242
[Fact]
243243
public async Task GetHouseholdByEmailAsync_ReturnsAllSeededScenarios()
244244
{
245-
// Derive emails from the default catalog
245+
// Derive emails from the default catalog (no state set, so DC-only scenarios are excluded)
246246
var defaultSettings = new SeedingSettings();
247+
var expectedScenarios = SeedScenarios.AllScenarios
248+
.Where(s => !SeedScenarios.DcOnlyScenarios.Contains(s));
247249

248-
foreach (var scenario in SeedScenarios.AllScenarios)
250+
foreach (var scenario in expectedScenarios)
249251
{
250252
var email = defaultSettings.BuildEmail(scenario.Name);
251253
var result = await _repository.GetHouseholdByEmailAsync(email, FullPiiVisibility, UserIalLevel.IAL1plus);
@@ -510,8 +512,8 @@ public async Task GetHouseholdByEmailAsync_ExpiredScenario_HasExpiredBenefits()
510512
public async Task GetHouseholdByEmailAsync_WithDcEmailPattern_ReturnsAllSeededScenarios()
511513
{
512514
const string pattern = "sebt.dc+{0}@codeforamerica.org";
513-
var repo = CreateRepository(pattern);
514-
var settings = new SeedingSettings { EmailPattern = pattern };
515+
var repo = CreateRepository(pattern, state: "dc");
516+
var settings = new SeedingSettings { EmailPattern = pattern, State = "dc" };
515517

516518
foreach (var scenario in SeedScenarios.AllScenarios)
517519
{

0 commit comments

Comments
 (0)