---
phase: 05-distribution-and-hardening
plan: 01
subsystem: testing
tags: [xunit, unit-tests, throttle-retry, pagination, localization, internals-visible-to]

# Dependency graph
requires:
  - phase: 01-foundation
    provides: ExecuteQueryRetryHelper and SharePointPaginationHelper core helpers
  - phase: 04-bulk-operations-and-provisioning
    provides: FR locale strings for all Phase 4 tabs
provides:
  - Unit tests for throttle exception classification (IsThrottleException)
  - Unit tests for CAML RowLimit injection (BuildPagedViewXml)
  - Exhaustive FR locale key parity and diacritics coverage tests
affects: [05-02-localization-fixes, future-CI]

# Tech tracking
tech-stack:
  added: []
  patterns:
    - "Helper methods changed private->internal static to enable direct unit testing (InternalsVisibleTo established in Phase 2)"
    - "Theory+InlineData for parametrized throttle message tests"
    - "ResourceManager with InvariantCulture GetResourceSet for exhaustive key enumeration"

key-files:
  created:
    - SharepointToolbox.Tests/Helpers/ExecuteQueryRetryHelperTests.cs
    - SharepointToolbox.Tests/Helpers/SharePointPaginationHelperTests.cs
    - SharepointToolbox.Tests/Localization/LocaleCompletenessTests.cs
  modified:
    - SharepointToolbox/Core/Helpers/ExecuteQueryRetryHelper.cs
    - SharepointToolbox/Core/Helpers/SharePointPaginationHelper.cs

key-decisions:
  - "IsThrottleException only checks top-level Message (not InnerException) — documented via nested-throttle test asserting false"
  - "FR diacritics already present in Strings.fr.resx — FrStrings_ContainExpectedDiacritics test passes immediately (no diacritic repair needed in Plan 02)"
  - "LocaleCompleteness Test 2 uses CultureInfo(fr) neutral culture — matches satellite assembly naming in Strings.fr.resx"

patterns-established:
  - "Helpers test subdirectory created under SharepointToolbox.Tests/Helpers/ — consistent with existing Auth/, Services/, ViewModels/ grouping"
  - "ResourceManager(string baseName, Assembly) pattern for locale tests — avoids static Strings class coupling"

requirements-completed:
  - FOUND-11

# Metrics
duration: 2min
completed: 2026-04-03
---

# Phase 05 Plan 01: Helper Unit Tests and Locale Completeness Summary

**Unit test coverage for throttle retry (IsThrottleException), CAML pagination (BuildPagedViewXml), and exhaustive FR locale key parity via ResourceManager enumeration**

## Performance

- **Duration:** 2 min
- **Started:** 2026-04-03T14:34:06Z
- **Completed:** 2026-04-03T14:36:06Z
- **Tasks:** 2
- **Files modified:** 5

## Accomplishments

- Made `IsThrottleException` and `BuildPagedViewXml` internal static, enabling direct unit testing via the existing InternalsVisibleTo pattern
- Created 5 ExecuteQueryRetryHelperTests: 3 throttle-true, 1 non-throttle-false, 1 nested-throttle-false (documents top-level-only behavior)
- Created 5 SharePointPaginationHelperTests: null, empty string, whitespace-only, existing RowLimit replacement, and RowLimit append before closing tag
- Created LocaleCompletenessTests with exhaustive FR key enumeration and diacritics spot-check — both pass (FR resx has correct accents)
- Full test suite: 134 pass, 22 skip, 0 fail — no regressions

## Task Commits

Each task was committed atomically:

1. **Task 1: Make helper methods internal static and create retry + pagination tests** - `4d7e9ea` (feat)
2. **Task 2: Create exhaustive FR locale completeness test** - `8c65394` (feat)

## Files Created/Modified

- `SharepointToolbox/Core/Helpers/ExecuteQueryRetryHelper.cs` - IsThrottleException changed private->internal
- `SharepointToolbox/Core/Helpers/SharePointPaginationHelper.cs` - BuildPagedViewXml changed private->internal
- `SharepointToolbox.Tests/Helpers/ExecuteQueryRetryHelperTests.cs` - 5 unit tests for throttle classification
- `SharepointToolbox.Tests/Helpers/SharePointPaginationHelperTests.cs` - 5 unit tests for CAML RowLimit injection
- `SharepointToolbox.Tests/Localization/LocaleCompletenessTests.cs` - 2 tests: key parity + diacritics spot-check

## Decisions Made

- `IsThrottleException` only checks `ex.Message` (not `ex.InnerException`) — the nested-throttle test documents this behavior by asserting false for `new Exception("outer", new Exception("429"))`. This is correct defensive documentation behavior.
- FR resx file (`Strings.fr.resx`) already contains proper diacritics (`Déplacer`, `Créer`, `Modèles`, `Terminé`, `Bibliothèque`) — the Read tool displayed them as ASCII due to rendering, but the actual UTF-8 bytes are correct. Plan 02's diacritic repair scope is narrower or already complete.
- Used `CultureInfo("fr")` neutral culture for ResourceManager lookups — matches the satellite assembly culture key used in the resx file.

## Deviations from Plan

None - plan executed exactly as written. The only discovery was that FR diacritics were already present (Plan 02 may have less work than anticipated), but this does not affect Plan 01 objectives.

## Issues Encountered

None.

## User Setup Required

None - no external service configuration required.

## Next Phase Readiness

- All three test files compile and run against the current codebase
- Helper visibility changes are backward-compatible (internal is accessible via InternalsVisibleTo, not publicly exposed)
- LocaleCompletenessTests provide an ongoing regression guard for FR locale completeness
- Plan 02 (diacritics repair) can proceed — though the test shows the main diacritics are already correct; Plan 02 may target other strings or confirm the file is already complete

---
*Phase: 05-distribution-and-hardening*
*Completed: 2026-04-03*
