Commit Graph

85 Commits

Author SHA1 Message Date
Joseph Doherty bff947d1e8 test: add AuthApiClientIntegrationTests
Add 5 integration tests for AuthApiClient:
- GetPublicKeyAsync_ReturnsValidPublicKey
- LoginAsync_WithValidCredentials_ReturnsSuccess
- GetCurrentUserAsync_AfterLogin_ReturnsUserInfo
- GetCurrentUserAsync_WithoutAuth_ReturnsUnauthorized
- LogoutAsync_AfterLogin_InvalidatesSession

Tests use RSA encryption pattern for login credentials and
verify auth cookie behavior across requests.
2026-01-06 11:39:09 -05:00
Joseph Doherty f7e683703d test: add SearchApiClientIntegrationTests for search endpoint validation
Add integration tests for SearchApiClient covering:
- GetUserSearchesAsync with authentication returns success
- GetUserSearchesAsync without authentication returns unauthorized
- GetSearchAsync with non-existent ID returns not found
2026-01-06 11:37:43 -05:00
Joseph Doherty 54de0ce1c3 test: add LookupApiClientIntegrationTests for lookup endpoint validation
Add 4 integration tests for LookupApiClient that verify lookup endpoints
work correctly through the actual HTTP pipeline without authentication.
2026-01-06 11:37:36 -05:00
Joseph Doherty 3ed2d7324d test: add ClientIntegrationTestBase with shared auth HttpClient 2026-01-06 11:36:13 -05:00
Joseph Doherty 7e5ac56525 build: add Client project reference to integration tests
Add JdeScoping.Client project reference to Api.IntegrationTests
to enable testing API client classes against the real API.
2026-01-06 11:34:23 -05:00
Joseph Doherty 6cb852c164 test: add FileApiClientTests with route, success, and error tests
Add comprehensive unit tests for FileApiClient covering:
- Route verification tests for all 4 download endpoints (POST method)
- Route verification tests for 2 upload endpoints (POST method)
- Success tests for downloads returning byte arrays
- Success tests verifying existing data can be passed to downloads
- Success tests for uploads returning IReadOnlyList<T>
- Multipart content-type and filename verification test
- Error tests (404 for download, 400 validation error for upload)
2026-01-06 11:33:31 -05:00
Joseph Doherty 55bfdb3532 test: add AuthApiClientTests with route and success tests
Add unit tests for AuthApiClient covering:
- Route verification tests for GetPublicKey, Login, Logout, GetCurrentUser
- Success tests for all 4 methods
- Proper handling of 204 NoContent for Logout (returns Unit)
2026-01-06 11:31:49 -05:00
Joseph Doherty d06d5f27e2 test: add LookupApiClientTests with route and encoding tests
- Route verification tests for all 4 methods (FindItems, FindProfitCenters,
  FindWorkCenters, FindOperators)
- Query string encoding tests verifying special characters (&, =) and spaces
  are properly URL-encoded
- Success tests for all lookup methods verifying deserialization
- Representative error test for 500 status code
2026-01-06 11:29:46 -05:00
Joseph Doherty 76ce35458c test: add SearchApiClientTests with route and success/error tests
Add comprehensive unit tests for SearchApiClient covering:
- Route verification tests for all 6 methods (GetUserSearches, GetQueuedSearches,
  GetSearch, CopySearch, CreateSearch, GetResults)
- Success tests verifying deserialization for all methods
- Representative error tests (404 for GetSearch, 401 for GetUserSearches)

Uses MockHttpMessageHandler to verify correct API routes are called
and ApiResult<T> pattern maps responses correctly.
2026-01-06 11:27:33 -05:00
Joseph Doherty 299099f716 test: add POST and bytes tests to ApiClientBaseTests
Added 11 new tests covering:
- POST method tests (200 success, 401 unauthorized, no-body variant)
- Bytes tests (GET 200, GET 404, POST 200)
- Non-GET status code tests (POST 400 validation, bytes 500, multipart 401/200)

All 23 ApiClientBaseTests now pass.
2026-01-06 11:25:49 -05:00
Joseph Doherty c626ffbd69 test: add edge case tests to ApiClientBaseTests
Add 7 edge case tests for ApiClientBase:
- GetAsync_Returns200_EmptyBody_MapsToApiError
- GetAsync_Returns200_InvalidJson_MapsToApiError
- GetAsync_Returns204_ForUnitType_MapsToSuccess
- GetAsync_Returns204_ForNonUnitType_MapsToApiError
- GetAsync_NetworkException_MapsToApiError
- GetAsync_Timeout_MapsToApiError
- GetAsync_Returns400_WithoutValidationFormat_MapsToApiError

Also fix bug in ApiClientBase where 204 NoContent for Unit type
failed due to incorrect type casting. The implicit conversion from
Unit to ApiResult<Unit> must be applied before the runtime cast.
2026-01-06 11:23:54 -05:00
Joseph Doherty 6af5a4f9d6 test: add all 6 status code mapping tests to ApiClientBaseTests
- Add GetAsync_Returns404_MapsToNotFound test
- Add GetAsync_Returns400_WithValidationErrors_MapsToValidationError test
- Add GetAsync_Returns401_MapsToUnauthorized test
- Add GetAsync_Returns403_MapsToForbidden test
- Add GetAsync_Returns500_MapsToApiError test
- Add FrameworkReference to Microsoft.AspNetCore.App for ValidationProblemDetails
2026-01-06 11:20:43 -05:00
Joseph Doherty e75ebe1ffb test: add ApiClientBaseTests with 200 OK mapping test 2026-01-06 11:17:19 -05:00
Joseph Doherty 626b7a63f2 test: add TestableApiClient helper for ApiClientBase unit tests 2026-01-06 11:15:10 -05:00
Joseph Doherty a8f79c26b2 refactor: add ApiRoutes import to FileControllerIntegrationTests
Added using statement for JdeScoping.Core.ApiContracts. The existing
routes (/api/file/...) are left unchanged as they test legacy download
by cache key endpoints which differ from the new FileIO routes.
2026-01-06 11:13:55 -05:00
Joseph Doherty 13976dea3b refactor: use ApiRoutes constants in AuthenticationTests
Replace hardcoded route strings with ApiRoutes.* constants:
- ApiRoutes.Auth.PublicKey, Login, Logout, Me
- ApiRoutes.Search.Base
- ApiRoutes.Lookup.Items, ProfitCenters, WorkCenters, Operators
2026-01-06 11:12:17 -05:00
Joseph Doherty 6bd6138b2a chore(client): add Extensions namespace to global imports
Add @using JdeScoping.Client.Extensions to _Imports.razor so that
extension methods (like ViewModelMappingExtensions) are available
globally in Razor components without explicit using statements.
2026-01-06 10:39:44 -05:00
Joseph Doherty 4e1cd2c221 chore(client): delete old service files replaced by API clients
Delete old service interfaces and implementations that have been
replaced by the new typed API clients:
- ISearchService/SearchService -> ISearchApiClient/SearchApiClient
- ILookupService/LookupService -> ILookupApiClient/LookupApiClient
- IFileService/FileService -> IFileApiClient/FileApiClient

Also remove unused IFileService injection from SearchEdit.razor
(download functionality now uses SearchApi.GetResultsAsync).
2026-01-06 10:38:41 -05:00
Joseph Doherty 6701da137d chore(client): remove old service registrations
Remove ISearchService, ILookupService, and IFileService registrations
from Program.cs as these are now replaced by the typed API clients
(ISearchApiClient, ILookupApiClient, IFileApiClient).
2026-01-06 10:37:15 -05:00
Joseph Doherty 828034d0e2 feat(client): migrate PartOperationFilterPanel to API clients 2026-01-06 10:35:33 -05:00
Joseph Doherty 251e2f910f feat(client): migrate ComponentLotFilterPanel to API clients 2026-01-06 10:34:33 -05:00
Joseph Doherty ead947bf57 feat(client): migrate WorkOrderFilterPanel to API clients 2026-01-06 10:33:36 -05:00
Joseph Doherty 8e05afb34f feat(client): migrate OperatorFilterPanel to API clients 2026-01-06 10:32:54 -05:00
Joseph Doherty ee6afc9e4e feat(client): migrate ProfitCenterFilterPanel to API clients 2026-01-06 10:32:25 -05:00
Joseph Doherty f49390ad01 feat(client): migrate WorkCenterFilterPanel to API clients 2026-01-06 10:31:58 -05:00
Joseph Doherty a6348c4268 feat(client): migrate ItemNumberFilterPanel to API clients
Update ItemNumberFilterPanel.razor to use ILookupApiClient and IFileApiClient
instead of legacy ILookupService and IFileService interfaces. All methods now
use the result.Switch() pattern for proper ApiResult error handling.
2026-01-06 10:30:20 -05:00
Joseph Doherty 20f9a1c683 feat(client): migrate MainLayout.razor to IAuthApiClient
- Replace IAuthService with IAuthApiClient for logout functionality
- Add @using JdeScoping.Core.ApiContracts
- LogoutAsync now calls AuthApi.LogoutAsync() and navigates to login
  regardless of API result
2026-01-06 10:27:24 -05:00
Joseph Doherty b555f57b72 feat(client): migrate Login.razor to IAuthApiClient
- Replace IAuthService injection with IAuthApiClient
- Keep ICryptoService for credential encryption
- Add AuthStateProvider injection to notify authentication state
- Use result.Switch() pattern for ApiResult<LoginResultModel> handling
- Properly handle ValidationError with FieldErrors dictionary
2026-01-06 10:25:54 -05:00
Joseph Doherty 6054412a77 refactor: move JSON ETL classes to DataSync.Dev
Move dev-only JSON reading infrastructure from DataSync to DataSync.Dev:
- JsonColumnSchema (Models/)
- JsonZstdFileSource (Sources/)
- JsonStreamingDataReader (Sources/)
- Utf8JsonStreamingDataReader (Sources/)

Update namespaces and using statements in all DevEtl files.
2026-01-06 10:25:45 -05:00
Joseph Doherty a77b71e53d feat(client): migrate SearchEdit.razor to ISearchApiClient
- Replace ISearchService with ISearchApiClient
- Add @using for JdeScoping.Core.ApiContracts and JdeScoping.Client.Extensions
- Update LoadSearchAsync to use result.Switch() pattern with ApiResult<T>
- Handle CopySearchId, Id, and new search cases with proper error handling
- Use ToClient() extension method to convert Core to Client SearchViewModel
- Add _errorMessage field and display error alert in UI
- Update SubmitSearchInternalAsync and DownloadResultsAsync for consistency
- Add FormatValidationErrors helper for ValidationError.FieldErrors
2026-01-06 10:23:36 -05:00
Joseph Doherty b86d48657e feat(client): migrate SearchQueue.razor to ISearchApiClient
- Replace ISearchService injection with ISearchApiClient
- Add @using for JdeScoping.Core.ApiContracts and JdeScoping.Client.Extensions
- Update LoadQueueAsync to use result.Switch() pattern with ApiResult<T>
- Add _errorMessage field for error display
- Add RadzenAlert for error message display in UI
2026-01-06 10:19:53 -05:00
Joseph Doherty b08f5418ec feat(client): migrate Searches.razor to ISearchApiClient
- Replace ISearchService injection with ISearchApiClient
- Add @using for JdeScoping.Core.ApiContracts and JdeScoping.Client.Extensions
- Update LoadSearchesAsync to use ApiResult<T>.Switch() pattern
- Add _errorMessage field for error state
- Display RadzenAlert for error conditions
- Use ToClientList() extension method to convert Core->Client view models
2026-01-06 10:18:11 -05:00
Joseph Doherty 81b07ce027 feat: extract DevEtl to JdeScoping.DataSync.Dev project
- Create JdeScoping.DataSync.Dev for sandbox testing ETL code
- Create JdeScoping.DataSync.Dev.Tests for associated tests
- Move 22 source files and 8 test files
- Update namespaces from DevEtl to Dev
- Add both projects to solution
2026-01-06 10:18:09 -05:00
Joseph Doherty 7ad4e3ec1c feat(client): configure HttpClient with AuthRedirectHandler
- Add using statement for JdeScoping.Client.Http namespace
- Register AuthRedirectHandler as a scoped service
- Replace simple HttpClient registration with handler pipeline
- AuthRedirectHandler intercepts 401 responses and redirects to login
- Keep all existing service registrations for backward compatibility
2026-01-06 10:15:48 -05:00
Joseph Doherty ba88450feb feat(client): add ViewModelMappingExtensions for Core<->Client mapping
Add extension methods to convert between Core and Client view models:
- SearchViewModel: Core (enum Status) <-> Client (string Status)
- SearchCriteria: Core (primitive lists) <-> Client (full ViewModels)
- JdeUserViewModel -> OperatorViewModel

Handles structural differences in criteria where Core uses primitive
lists (List<long>, List<string>) and Client uses full objects.
2026-01-06 10:14:09 -05:00
Joseph Doherty 0b50c03e44 feat(client): add AuthRedirectHandler for global 401 redirect
Add HTTP message handler that intercepts 401 Unauthorized responses
and redirects to the login page with return URL preserved.
2026-01-06 10:11:43 -05:00
Joseph Doherty 380ffb9a82 fix(test): correct connection string name and cache directory path 2026-01-03 16:42:11 -05:00
Joseph Doherty e04e81b178 test(datasync): add integration tests for BranchDevEtl
Add integration tests for the Branch development ETL pipeline:
- BranchDevEtlTests with tests for pipeline creation and execution
- Tests verify pipeline creates correctly and loads data from cache files
- Added appsettings.json with local connection string and cache directory
- Added necessary packages (Configuration.Json, SqlClient, Dapper)

Tests require local SQL Server and CACHED_DB_FILES directory with
branch.json.zstd to pass; tests silently skip if resources unavailable.
2026-01-03 16:38:11 -05:00
Joseph Doherty badc6a43f3 fix(datasync): throw on cancellation in DevEtlRegistry.RunAllAsync 2026-01-03 16:32:29 -05:00
Joseph Doherty 6bd2b3c285 feat(datasync): add DevEtlRegistry for managing development ETL pipelines 2026-01-03 16:28:35 -05:00
Joseph Doherty fd1e5454da feat(datasync): add BranchDevEtl pipeline for Branch table dev loading 2026-01-03 16:24:34 -05:00
Joseph Doherty 2629cb26e0 fix(datasync): add guards and exception safety to JsonZstdFileSource 2026-01-03 16:21:59 -05:00
Joseph Doherty 57a44e0f3a feat(datasync): add JsonZstdFileSource for reading zstd-compressed JSON files 2026-01-03 16:19:28 -05:00
Joseph Doherty 6d2d8134cb fix(datasync): dispose JsonDocument in JsonStreamingDataReader.Read() 2026-01-03 16:17:38 -05:00
Joseph Doherty bd1c2fd656 feat(datasync): add JsonStreamingDataReader for streaming JSON array parsing 2026-01-03 16:14:31 -05:00
Joseph Doherty bf7cfe9bf1 feat(datasync): add JsonColumnSchema record for ETL column metadata 2026-01-03 16:11:00 -05:00
Joseph Doherty 9ff21958bb feat(datasync): add ZstdSharp.Port package for zstd decompression 2026-01-03 16:08:13 -05:00
Joseph Doherty 7dcbacd5ca fix(etl): address Codex MCP review findings for Phase 2
- Filter MERGE SQL columns to only include columns that exist in destination
  (allColumns and updateColumns were using unfiltered source columns)
- Fix schema-qualified table names to use proper [schema].[table] format
  instead of wrapping entire name in single brackets
- Add empty column mapping validation to throw early if no columns intersect
- Add JdeDateTransformer output column collision detection in OnInitialize
- Add TODO comment for WithCommandTimeout (stored but not yet passed to
  destinations)
- Add tests for FormatQualifiedTableName and output column collision
2026-01-03 11:27:07 -05:00
Joseph Doherty fcd8b660fa feat(etl): add WithCommandTimeout to EtlPipelineBuilder with validation 2026-01-03 11:09:28 -05:00
Joseph Doherty 3145fca371 feat(etl): add column mapping to destinations (intersect with dest schema) 2026-01-03 11:06:38 -05:00