Skip to content

Fix API test authentication in BCApps - #10085

Open
Prangshuman Das (t-prda) wants to merge 117 commits into
mainfrom
prdas/646383-api-test-auth
Open

Fix API test authentication in BCApps#10085
Prangshuman Das (t-prda) wants to merge 117 commits into
mainfrom
prdas/646383-api-test-auth

Conversation

@t-prda

@t-prda Prangshuman Das (t-prda) commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • authenticate Library - Graph Mgt API tests in UserPassword containers
  • preserve Windows-auth uptake and local NAV Key Vault fallback
  • migrate Expense Agent tests and re-enable affected API suites

Testing

  • local API tests passed

AB#646383

@t-prda
Prangshuman Das (t-prda) requested review from a team August 10, 2026 11:01
@github-actions github-actions Bot added Build: scripts & configs Build scripts and configuration files AL: Apps (W1) Add-on apps for W1 Team: Integrations GitHub request for Integrations area labels Aug 10, 2026
@github-actions github-actions Bot added this to the Version 29.0 milestone Aug 10, 2026
Comment thread build/scripts/NewBcContainer.ps1 Fixed
Comment thread build/scripts/NewBcContainer.ps1 Fixed
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al
@t-prda
Prangshuman Das (t-prda) marked this pull request as draft August 10, 2026 11:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR centralizes Basic authentication injection for Library - Graph Mgt-based API tests so they can run in NavUserPassword (UserPassword) containers, and then re-enables several previously disabled API/E2E test suites. It replaces an app-specific Expense Agent auth helper with a shared TestLibraries subscriber and adds a container-side “credential bridge” file so the test runner can obtain the password without requiring Azure Key Vault.

Changes:

  • Added Library - Graph Auth Mgt. as an event subscriber to inject Basic auth for non-Windows test users, sourcing the password from a container file or (fallback) Azure Key Vault.
  • Removed the Expense Agent test-only auth helper + manual subscription binding; tests now rely on the shared subscriber.
  • Re-enabled multiple API/E2E test suites by removing entries from various *.DisabledTest.json files (and deleting the APIV1/APIV2 exclusion lists), and updated container provisioning to create the API-test password bridge file.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al New shared subscriber that injects Basic auth into Library - Graph Mgt requests for NavUserPassword scenarios.
build/scripts/NewBcContainer.ps1 Writes the container password bridge file and sets ACLs so server-side AL can read it.
src/Apps/W1/ExpenseAgent/test/src/Helper/ExpenseAPITestAuthHelper.Codeunit.al Removes app-specific auth injection helper in favor of shared TestLibraries implementation.
src/Apps/W1/ExpenseAgent/test/src/API/ExpenseUsersAPITest.Codeunit.al Drops manual subscription binding to the removed helper.
src/Apps/W1/ExpenseAgent/test/src/API/ExpenseProjectsAPITest.Codeunit.al Drops manual subscription binding to the removed helper.
src/Apps/W1/ExpenseAgent/test/src/API/ExpensePerDiemLocationsTest.Codeunit.al Drops manual subscription binding to the removed helper.
src/Apps/W1/ExpenseAgent/test/src/API/ExpenseCapabilitiesAPITest.Codeunit.al Drops manual subscription binding to the removed helper.
src/DisabledTests/Tests-Integration/Tests-Integration.DisabledTest.json Re-enables specific integration API tests by removing disable entries.
src/DisabledTests/Tests-Graph/Tests-Graph.DisabledTest.json Re-enables specific Graph E2E tests by removing disable entries.
src/DisabledTests/Sustainability_Tests/Sustainability_Tests.DisabledTest.json Re-enables Sustainability API tests by removing disable entries.
src/DisabledTests/Quality_Management-Tests/Quality_Management-Tests.DisabledTest.json Re-enables Quality Management API tests by removing disable entry.
src/DisabledTests/IRS_Forms_Tests/IRS_Forms_Tests.DisabledTest.json Re-enables IRS 1099 API test by removing disable entry.
src/DisabledTests/E-Document_Core_Tests/E-Document Core Tests.DisabledTest.json Re-enables E-Document API tests by removing disable entry.
src/DisabledTests/_Exclude_APIV2__Tests/_Exclude_APIV2__Tests.DisabledTest.json Deletes the APIV2 exclusion list (re-enables APIV2 suite).
src/DisabledTests/_Exclude_APIV1__Tests/_Exclude_APIV1__Tests.DisabledTest.json Deletes the APIV1 exclusion list (re-enables APIV1 suite).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread build/scripts/NewBcContainer.ps1 Outdated
Comment thread build/scripts/NewBcContainer.ps1 Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al
Comment thread build/scripts/NewBcContainer.ps1 Outdated
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al
Comment thread src/Layers/W1/Tests/TestLibraries/LibraryGraphAuthMgt.Codeunit.al Outdated
@t-prda

Copy link
Copy Markdown
Contributor Author

Agentic PR Review - Round 1

Recommendation: Accept

What this PR does

This PR adds an explicit authentication bridge for API tests that use Library - Graph Mgt. in BCApps UserPassword containers. The subscriber is manual, each affected API test codeunit opts in, Windows-authenticated NAV gates keep their existing behavior, and local NAV UserPassword runs can use the existing Key Vault secret.

The change addresses the gate difference directly. It does not change application API behavior, and it avoids making partner test code automatically depend on the BCApps credential bridge.

Suggestions

None.

Risk assessment and necessity

Risk: The change touches shared test infrastructure and re-enables many existing suites, so CI isolation and concurrency failures may still need separate gate work. The authentication subscriber itself is manually scoped and internal.

Necessity: The change is required because BCApps runs these tests with UserPassword while NAV's normal uptake gates use Windows authentication. Without the bridge, the API suites fail with 401 responses and remain disabled.


[AI-PR-REVIEW] version=1 promptVersion=1 system=github pr=10085 round=1 by=t-prda at=2026-08-12T09:27:33Z lastSha=6fe7981474d813fcafab57bc6e6fa0c429df80a5 reviewKey=e0d301ad1af589367637a08b287af9af4fb26402df7532abc2876a0a48dbabc7 suggestions=none

@github-actions github-actions Bot added the Build: Automation Workflows and other setup in .github folder label Aug 13, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
@github-actions github-actions Bot modified the milestones: Version 29.0, Version 30.0 Aug 26, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
@t-prda
Prangshuman Das (t-prda) marked this pull request as ready for review August 26, 2026 15:14
@t-prda
Prangshuman Das (t-prda) requested review from a team August 26, 2026 15:14
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
if not User.Get(UserSecurityId()) then
Error(CurrentUserNotFoundErr);

if ContainerPasswordFileExists() then begin

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Error\ Handling}$

GetAuthenticationPassword (new codeunit 131022 'Library - Graph Auth Mgt.') now hard-errors whenever the on-prem container password file is absent and the current user has no Windows Security ID: it falls through to TryGetNavEnlistmentPassword() and raises KeyVaultPasswordReadErr if the 'NavServerUserPassword' Key Vault secret cannot be retrieved. The deleted predecessor (Expense API Test Auth Helper) explicitly gated this whole path behind EnvironmentInfo.IsSaaSInfrastructure(), skipping Basic-Auth injection entirely on SaaS. That environment guard was dropped in the consolidation, and EnsureAuthenticationAvailable()/AddAuthentication() are now invoked unconditionally from trigger OnRun (or InitializeWebRequestWithURL) in ~146 API/E2E test codeunits across APIV1, APIV2, ExpenseAgent, Sustainability, Quality Management and IRS1099. In any environment without the container password file, without Windows-integrated auth, and without access to the NavServerUserPassword Key Vault secret (e.g. a SaaS test tenant, or a local/dev sandbox), these tests will now hard-fail during setup instead of silently skipping auth injection as before. Reinstate an explicit unsupported-environment guard (e.g. skip when running on SaaS, mirroring the removed ShouldInjectBasicAuth check) or make the Key Vault lookup best-effort when neither a container password file nor Windows auth is present.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

@github-actions

Copy link
Copy Markdown
Contributor

$\textbf{🟡\ Medium\ Severity\ —\ Style}$

The file name src/Apps/W1/APIV2/test/src/APIV2itemLedgEntriesE2E.Codeunit.al does not mirror the declared object name 'APIV2 - Item Ledg. Entries E2E' in PascalCase. Rename it to APIV2ItemLedgEntriesE2E.Codeunit.al so file listings and code-search tools keep a stable file-system-to-object mapping.

Knowledge:

Line mapping was unavailable, so this was posted as an issue comment.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

@github-actions

Copy link
Copy Markdown
Contributor

$\textbf{🟡\ Medium\ Severity\ —\ Style}$

The file name src/Layers/W1/Tests/Integration/ApiRoutesE2E.Codeunit.al does not mirror the declared object name 'API Routes E2E' in PascalCase. Rename it to APIRoutesE2E.Codeunit.al so file listings and code-search tools keep a stable file-system-to-object mapping.

Knowledge:

Line mapping was unavailable, so this was posted as an issue comment.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

CODEUNIT.Run(CODEUNIT::"Correct Posted Sales Invoice", SalesInvoiceHeader);
end;

local procedure EnsureReasonCode()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Testing}$

The new EnsureReasonCode() helper hand-rolls a 'Reason Code' record via Init/Insert with a hard-coded primary key ('API-TEST') instead of using the existing LibraryERM fixture API. This makes these API tests depend on an ad-hoc, non-maintained record shape rather than a maintained test-library fixture, and duplicates the same pattern across four codeunits: src/Apps/W1/APIV1/test/src/SalesInvoicesE2E.Codeunit.al, src/Apps/W1/APIV2/test/src/APIV2SalesInvoicesE2E.Codeunit.al, src/Apps/W1/APIV1/test/src/APIV1SalesCreditMemosE2E.Codeunit.al, and src/Apps/W1/APIV2/test/src/APIV2SalesCreditMemosE2E.Codeunit.al.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

PurchaseLineGLAccount, PurchaseHeader, PurchaseLineGLAccount.Type::"G/L Account", GLAccount."No.", 1);
end;

procedure EnsureVATPostingSetupExists(VATBusPostingGroup: Code[20]; VATProdPostingGroup: Code[20])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Testing}$

EnsureVATPostingSetupExists now creates 'VAT Posting Setup' records directly via Init/Insert instead of the existing LibraryERM.CreateVATPostingSetup helper. This bypasses the maintained test-library setup for a prerequisite record and can leave API test fixtures with a VAT posting setup shape that drifts from what the application actually requires as posting logic evolves.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

procedure EnsureVATPostingSetupExists(VATBusPostingGroup: Code[20]; VATProdPostingGroup: Code[20])
var
    VATPostingSetup: Record "VAT Posting Setup";
    LibraryERM: Codeunit "Library - ERM";
begin
    if (VATBusPostingGroup = '') and (VATProdPostingGroup = '') then
        exit;
    if VATPostingSetup.Get(VATBusPostingGroup, VATProdPostingGroup) then
        exit;

    LibraryERM.CreateVATPostingSetup(VATPostingSetup, VATBusPostingGroup, VATProdPostingGroup);
end;

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

procedure InitializeWebRequestWithURL(var HttpWebRequestMgt: Codeunit "Http Web Request Mgt."; TargetURL: Text)
begin
HttpWebRequestMgt.Initialize(TargetURL);
LibraryGraphAuthMgt.AddAuthentication(HttpWebRequestMgt);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Web\ Services}$

InitializeWebRequestWithURL now unconditionally injects Basic authentication (via LibraryGraphAuthMgt.AddAuthentication) for essentially every Graph/API E2E test request, and the helper both sets HttpWebRequest.Credentials and manually adds an explicit 'Authorization: Basic ' header. In this repo's container/dev test setup, BC endpoints are commonly exposed over plain http://, so these credentials (including the raw password embedded in the manually-built header) can be transmitted without TLS. Guard the Basic-auth injection so it only fires for HTTPS endpoints, or ensure the container/test endpoints this helper targets are TLS-only.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

@alexei-dobriansky

Copy link
Copy Markdown
Contributor

AI Review — Round 1

Scope: 163 changed files (153 .al, 4 .ps1, 1 .psm1, 5 .json), +2296/-5477. Reviewed the full diff: the new centralized test-auth codeunit, the ~150 mechanical OnRun edits across API E2E test codeunits, the build/test-infra changes (NewBcContainer.ps1, ParallelTestExecution.psm1, RunTestsInBcContainer.ps1, the new Pester coverage), the DisabledTest.json re-enablements, and every non-test-codeunit file individually.

What this PR does

Centralizes API-test HTTP authentication into a new Library - Graph Auth Mgt. codeunit (container password file → Azure KV mock fallback → real NAV KV secret, in that priority order), wires it into Library - Graph Mgt.InitializeWebRequestWithURL so every graph/API test request gets Basic auth proactively, adds a fail-fast EnsureAuthenticationAvailable() call to ~146 test codeunits' OnRun triggers, removes the old per-app auth event-subscriber workaround (Expense API Test Auth Helper), and re-enables a batch of previously-disabled API test suites. It also builds substantial new "clean tenant" test-execution infrastructure (database-template clone + reset per RequiredTestIsolation=Disabled codeunit) so the newly re-enabled tests can run safely in parallel CI, backed by solid new Pester tests, including a nice guardrail spec asserting every enabled APIV1/APIV2 test codeunit consistently has the right isolation/auth/work-date properties.

Overall this is a well-executed, mechanically consistent piece of test-infra work with strong new test coverage for the build-side changes. No correctness issues found in the core auth logic itself (secret handling is properly [NonDebuggable]/SecretText throughout).

Findings

🔴 S1 — Undisclosed production behavior change bundled into a test-only PR (src/Layers/W1/BaseApp/Purchases/eServices/EDocument/ReturnShptPDFDocHandler.Codeunit.al)

- ReportUsage := "Report Selection Usage"::"P.Return";
+ ReportUsage := "Report Selection Usage"::"P.Ret.Shpt.";

This is a real bug fix — "Return Shpt. PDF Doc.Handler" was pulling the Purchase Return Order report (P.Return) instead of Purchase - Return Shipment (P.Ret.Shpt.), inconsistent with how ReturnShipmentHeader.Table.al prints the same document elsewhere. But it's a production BaseApp behavior change, not test code, it's not mentioned anywhere in the PR description ("Summary" only talks about test auth), and there's no dedicated assertion covering it (the re-enabled EDocAPITest doesn't exercise return-shipment PDF attachment). Buried among 163 files this is exactly the kind of change that gets rubber-stamped. Please call it out explicitly in the PR description (or split it into its own PR/commit referencing its own work item) and add a regression test asserting the correct report usage for return-shipment PDF attachments.

🟠 S2 — Mock Key Vault provider is fully reinitialized on every single HTTP request
AddAuthenticationGetAuthenticationPasswordTryGetContainerPassword runs LibraryAzureKVMockMgmt.InitMockAzureKeyvaultSecretProvider() + AddMockAzureKeyvaultSecretProviderMappingFromFile(...) + UseAzureKeyvaultSecretProvider() on every outgoing graph/API call (since InitializeWebRequestWithURL calls AddAuthentication each time, and none of the resolved password/provider state is cached). Besides the redundant file I/O per request, InitMockAzureKeyvaultSecretProvider() discards any previously-registered mock secret mappings, so any test that also mocks an unrelated KeyVault secret (AddMockAzureKeyvaultSecretProviderMapping, used elsewhere e.g. in LibraryMakingTaxDigital/LPPredictionTest) while touching a graph endpoint would silently lose that mapping. No current API E2E test combines the two, so this isn't failing today, but it's a latent trap for whoever reuses this shared library next. Recommend memoizing the resolved password/provider-init once per test run instead of recomputing on every request.

🟡 S3 — Regression-test precision loosened, likely as a rebase workaround
build/scripts/tests/BuildOptimization.Test.ps1: $affected.Count | Should -Be 51Should -BeGreaterOrEqual 56 with comment "Keep the branch baseline while allowing unrelated E-Document apps added on main." This permanently weakens the test (a future accidental drop in fan-out would no longer be caught, only growth). Since it appears to just be papering over this branch being behind current main's E-Document app count, please rebase and restore an exact assertion before merge rather than leaving the loosened bound in permanently.

🟡 S4 — Confusing near-duplicate variable naming (EDocAPITest.Codeunit.al)
A new global LibraryGraphMgtForAuthentication: Codeunit "Library - Graph Mgt" was added solely because GetEDocument() already declares a local LibraryGraphMgt of the same type (also fixing a pre-existing casing typo, LibrarygraphMgtLibraryGraphMgt, in the same hunk). It works, but two same-typed variables with near-identical names in one codeunit (one global for OnRun, one local for the test method) is an easy source of future copy-paste mistakes. Consider renaming the local one instead (e.g. LocalLibraryGraphMgt) for clarity.

🟡 S5 — Container-side password file is never cleaned up
NewBcContainer.ps1 writes the API test password to C:\Run\my\ApiTestPassword inside the container (ACL-restricted to SYSTEM/NETWORK SERVICE/Administrators) but only removes the host-side temp copy in its finally block; the in-container file persists for the container's whole lifetime. Given ACLs are already tight this is low risk, but for defense-in-depth consider removing it during container teardown too.

CI status (informational, not this PR's fault)

Every "Build Apps *" check is currently failing on AS0072: The Obsolete Tag 29.0 ... is not allowed. Expected tag for this branch: 30.0. This is a known, currently in-flight, repo-wide main breakage from the v30 app-version bump (see PR #10675 "Temporarily suppress AS0072 ... for v30 prep" / ADO Bug 647877), affecting all open PRs' clean builds right now — not something introduced by this diff (the diff touches zero ObsoleteTag/version content). No action needed here beyond the normal rebase onto main once that lands.

Recommendation

Accept with Suggestions. The core auth-centralization work is sound, consistent, and well-tested; please address S1 (disclose/split/test the return-shipment report-usage fix) before merging, and consider S2–S5 as follow-ups.


[AI-PR-REVIEW] by=alexei-dobriansky round=1 promptVersion=1 reviewKey=713070e44f42b4f5 headSha=fdfb2e1c2537651d2c59de1d573eb426f79674e3 suggestions=S1@b79ed4f7,S2@373f05d4,S3@daa56c26,S4@7d6c760a,S5@227b86e9

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91
local procedure CreateCancelledSalesInvoice(var SalesInvoiceHeader: Record "Sales Invoice Header")
begin
CreatePostedSalesInvoice(SalesInvoiceHeader);
EnsureReasonCode();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Performance}$

LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup() is a localized hook that writes setup data in layers such as AU, so this code can open a write transaction immediately before CODEUNIT.Run(...). The runtime rejects Codeunit.Run inside an open write transaction, so this helper needs a Commit() before the run or a read-only caller.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        EnsureReasonCode();
        LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup();
        Commit();
        CODEUNIT.Run(CODEUNIT::"Correct Posted Sales Invoice", SalesInvoiceHeader);

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

local procedure CreateCancelledSalesInvoice(var SalesInvoiceHeader: Record "Sales Invoice Header")
begin
CreatePostedSalesInvoice(SalesInvoiceHeader);
EnsureReasonCode();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Performance}$

LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup() is a localized hook that writes setup data in layers such as AU, so this code can open a write transaction immediately before CODEUNIT.Run(...). The runtime rejects Codeunit.Run inside an open write transaction, so this helper needs a Commit() before the run or a read-only caller.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        EnsureReasonCode();
        LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup();
        Commit();
        CODEUNIT.Run(CODEUNIT::"Correct Posted Sales Invoice", SalesInvoiceHeader);

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

procedure InitializeWebRequestWithURL(var HttpWebRequestMgt: Codeunit "Http Web Request Mgt."; TargetURL: Text)
begin
HttpWebRequestMgt.Initialize(TargetURL);
LibraryGraphAuthMgt.AddAuthentication(HttpWebRequestMgt);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Security}$

LibraryGraphMgt.InitializeWebRequestWithURL is public and accepts a caller-supplied URL, but it now unconditionally invokes the internal auth helper to fetch the current user's password and attach Basic authentication. Access = Internal on the helper is not an authorization boundary, so any dependent extension that can call this public test-library surface can reuse it to send those credentials to an arbitrary endpoint.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

var
ReasonCode: Record "Reason Code";
begin
if not ReasonCode.IsEmpty() then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Testing}$

This test helper hand-rolls a "Reason Code" fixture with Init/assignment/Insert even though the test library already provides LibraryERM.CreateReasonCode. Bypassing the library skips its Validate/Insert(true) path and hard-codes a record shape that can drift from the platform setup the correction flow expects, making the test depend on invalid or incomplete fixture data.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        if not ReasonCode.IsEmpty() then
            exit;

        LibraryERM.CreateReasonCode(ReasonCode);

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

var
ReasonCode: Record "Reason Code";
begin
if not ReasonCode.IsEmpty() then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Testing}$

This test helper hand-rolls a "Reason Code" fixture with Init/assignment/Insert even though the test library already provides LibraryERM.CreateReasonCode. Bypassing the library skips its Validate/Insert(true) path and hard-codes a record shape that can drift from the platform setup the correction flow expects, making the test depend on invalid or incomplete fixture data.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        if not ReasonCode.IsEmpty() then
            exit;

        LibraryERM.CreateReasonCode(ReasonCode);

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

var
ReasonCode: Record "Reason Code";
begin
if not ReasonCode.IsEmpty() then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Testing}$

This test helper hand-rolls a "Reason Code" fixture with Init/assignment/Insert even though the test library already provides LibraryERM.CreateReasonCode. Bypassing the library skips its Validate/Insert(true) path and hard-codes a record shape that can drift from the platform setup the correction flow expects, making the test depend on invalid or incomplete fixture data.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        if not ReasonCode.IsEmpty() then
            exit;

        LibraryERM.CreateReasonCode(ReasonCode);

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

var
ReasonCode: Record "Reason Code";
begin
if not ReasonCode.IsEmpty() then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Testing}$

This test helper hand-rolls a "Reason Code" fixture with Init/assignment/Insert even though the test library already provides LibraryERM.CreateReasonCode. Bypassing the library skips its Validate/Insert(true) path and hard-codes a record shape that can drift from the platform setup the correction flow expects, making the test depend on invalid or incomplete fixture data.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        if not ReasonCode.IsEmpty() then
            exit;

        LibraryERM.CreateReasonCode(ReasonCode);

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

var
VATPostingSetup: Record "VAT Posting Setup";
begin
if (VATBusPostingGroup = '') and (VATProdPostingGroup = '') then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Testing}$

This test library now hand-rolls a "VAT Posting Setup" fixture with Init/field assignment/Insert instead of using LibraryERM.CreateVATPostingSetup. That bypasses the library's validated setup path and can leave future tests creating partially initialized posting data, especially when table validation or localization-specific setup changes.

Suggested fix (apply manually — could not be anchored as a one-click suggestion):

        if (VATBusPostingGroup = '') and (VATProdPostingGroup = '') then
            exit;
        if VATPostingSetup.Get(VATBusPostingGroup, VATProdPostingGroup) then
            exit;

        LibraryERM.CreateVATPostingSetup(VATPostingSetup, VATBusPostingGroup, VATProdPostingGroup);

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AL: Apps (W1) Add-on apps for W1 Build: scripts & configs Build scripts and configuration files ExpenseManagement Team: Integrations GitHub request for Integrations area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants