Skip to content

test(8.1.15): comprehensive test coverage — 50+ tests, Mvc.Tests project, CI coverage#13

Merged
cct08311github merged 7 commits intofeature/8.1.14-stabilizefrom
feature/8.1.15-testing
Mar 4, 2026
Merged

test(8.1.15): comprehensive test coverage — 50+ tests, Mvc.Tests project, CI coverage#13
cct08311github merged 7 commits intofeature/8.1.14-stabilizefrom
feature/8.1.15-testing

Conversation

@cct08311github
Copy link
Copy Markdown
Owner

Summary

  • INFRA-1: Reorganize Core.Tests into Unit/Integration/Security directories; add new WalkingTec.Mvvm.Mvc.Tests xUnit project; add coverlet.collector to all 3 test projects; create WtmTestHelper and TokenTestFixture fixtures
  • UNIT-1: Expand PasswordHashHelperTests (17 tests) and RefreshTokenEntityTests (8 tests) with unicode, long passwords, timing boundaries
  • AUTH-1 (P0): DoLoginAsyncTests (8 tests) covering PBKDF2, MD5 migration with DB persistence, disabled user, tenant mismatch; TokenServiceIntegrationTests (15 tests) covering issue/refresh/revoke lifecycle, reuse detection chain revocation, tenant isolation
  • ASYNC-VM-1 (P1): BaseCRUDVMAsyncTests (7 tests) for DoAddAsync/DoEditAsync/DoDeleteAsync with audit field verification and FC field-subset update
  • ADMIN-1 (P2): FrameworkGroupApiTest, FrameworkRoleApiTest, DataPrivilegeApiTest (13 MSTest tests) — Search/Create/Edit/Get/BatchDelete for each admin controller
  • SEC-1: PasswordMigrationFlowTests (7 tests), BruteForceResistanceTests (7 tests), TokenChainSecurityTests (7 tests) — security property verification including PBKDF2 work-factor timing, 100-hash salt uniqueness, 3-hop chain integrity
  • CI-COV: Add coverlet.runsettings, update CI to collect XPlat Code Coverage, install ReportGenerator, upload HTML/lcov/Cobertura coverage report artifact

Test plan

  • CI runs green on feature/8.1.15-testing branch
  • Coverage report artifact is generated in CI (check Actions → coverage-report)
  • All 50+ new tests pass (xUnit: Core.Tests + Mvc.Tests; MSTest: Admin.Test)
  • No regressions in existing tests

🤖 Generated with Claude Code

INFRA-1: Reorganize Core.Tests into Unit/Integration/Security directories.
Add WalkingTec.Mvvm.Mvc.Tests (new xUnit project). Add coverlet.collector
to both new projects and Admin.Test. Register WtmTestHelper and TokenTestFixture
fixtures. Update solution to include Mvc.Tests project.

UNIT-1: Expand PasswordHashHelperTests (17 tests) and RefreshTokenEntityTests
(8 tests) with edge cases — unicode, long passwords, timing, boundary expiry.

AUTH-1 (P0): DoLoginAsyncTests (8 tests) — PBKDF2 happy path, MD5 migration,
hash persistence to DB, disabled user, tenant mismatch. TokenServiceIntegrationTests
(15 tests) — issue, refresh/rotate, reuse detection chain revocation, revoke,
tenant isolation.

ASYNC-VM-1 (P1): BaseCRUDVMAsyncTests (7 tests) — DoAddAsync/DoEditAsync/
DoDeleteAsync with audit field verification and field-subset update via FC dict.

ADMIN-1 (P2): FrameworkGroupApiTest, FrameworkRoleApiTest, DataPrivilegeApiTest
— Search/Create/Edit/Get/BatchDelete for each admin controller, following
existing MSTest pattern.

SEC-1: PasswordMigrationFlowTests (7 tests) — post-migration hash properties,
salt uniqueness, cross-user isolation. BruteForceResistanceTests (7 tests) —
PBKDF2 work-factor timing, 100-hash salt diversity. TokenChainSecurityTests
(7 tests) — 3-hop chain, midpoint reuse, distinct tokens, cross-user revoke.

CI-COV: Update ci-build.yml to collect coverage (XPlat Code Coverage + coverlet
.runsettings), install ReportGenerator, generate HTML/lcov/Cobertura reports,
upload coverage-report artifact alongside existing test-results artifact.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f98c86ec5e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +124 to +125
mockHttpContext.Setup(x => x.User)
.Returns(new System.Security.Claims.ClaimsPrincipal());
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Seed mock user with a non-null identity

CreateLoginTestContext sets HttpContext.User to new ClaimsPrincipal() with no identities, and WTMContext.DoLoginAsync later reads HttpContext.User.Identity.IsAuthenticated when tenant is null (see src/WalkingTec.Mvvm.Core/WTMContext.cs). An empty principal has a null Identity, so the new login integration tests that pass tenant: null can throw NullReferenceException before authentication logic executes.

Useful? React with 👍 / 👎.

Comment on lines +112 to +113
refreshed.AccessToken.Should().NotBe(issued.AccessToken,
"access token must also be regenerated on rotation");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove flaky access-token inequality check

This assertion assumes refresh must always change the access-token string, but TokenService.GenerateAccessToken is deterministic for the same claims/signing key and uses second-level JWT timestamps; when issue+refresh happen within the same second (common in fast CI), issued.AccessToken and refreshed.AccessToken can be identical even though refresh-token rotation succeeded, making this test intermittently fail.

Useful? React with 👍 / 👎.

cct0831 and others added 6 commits March 4, 2026 14:06
Core.Tests: FrameworkUserBase is abstract; define concrete TestLoginUser
in Core.Tests fixtures to avoid demo project dependency. Replace all
FrameworkUser references with TestLoginUser throughout WtmTestHelper and
DoLoginAsyncTests. LoginTestDataContext now uses DbSet<TestLoginUser>.

Admin.Test/FrameworkGroupApiTest: FrameworkGroupController.Add() and Edit()
return sync IActionResult (not Task<IActionResult>); remove erroneous
.Result dereference. FrameworkGroup inherits TreePoco:TopBasePoco (no audit
fields); remove CreateBy/CreateTime/UpdateBy/UpdateTime assertions.

Admin.Test/FrameworkRoleApiTest: FrameworkRoleController.Add() and Edit()
also return sync IActionResult; remove .Result dereference. FrameworkRole
inherits BasePoco so audit field assertions are retained.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add `using WalkingTec.Mvvm.Core.Support.Json` for Token type
- Replace ReturnsAsync() with Returns(Task.FromResult()) to avoid
  nullable context ambiguity in projects with <Nullable>enable</>

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r conflict

- WtmTestHelper: use ClaimsPrincipal(ClaimsIdentity()) so HttpContext.User.Identity
  is never null (DoLoginAsync line 375 null-check)
- TokenTestFixture: replace AddDbContext<EmptyContext>(opt=>.UseInMemory()) with
  AddScoped<EmptyContext>(_ => new EmptyContext(DbName, DBTypeEnum.Memory)) to prevent
  OnConfiguring from adding SqlServer alongside InMemory in the same service provider

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… for TokenFixture

DoLoginAsync: LoginTestDataContext now extends EmptyContext instead of FrameworkContext
to avoid complex navigation relationships (FrameworkUserRoles, FrameworkUserGroups)
that EF Core InMemory cannot translate in LINQ projection expressions.

TokenTestFixture: use FrameworkContext (which has FrameworkRefreshTokens) instead of
EmptyContext so db.Set<RefreshTokenEntity>() can resolve in the EF model.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DoLoginAsyncTests: replace EF InMemory with SQLite shared in-memory database.
LoadBasicInfoAsync has correlated collection subqueries (FrameworkUserRole,
FrameworkUserGroup) that EF Core InMemory cannot translate. SQLite handles these
correctly. A keep-alive SqliteConnection ensures the named in-memory DB persists
across multiple LoginTestDataContext instances within one test.

LoginTestDataContext: back to FrameworkContext (all entities in model) + SQLite
via DataSource=seed?mode=memory&cache=shared connection string.

TokenService.GenerateAccessToken: add jti (JWT ID) claim so consecutive tokens
for the same user are always distinct strings even within the same second.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@cct08311github cct08311github merged commit 9580cdf into feature/8.1.14-stabilize Mar 4, 2026
2 checks passed
@cct08311github cct08311github deleted the feature/8.1.15-testing branch March 7, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant