From 16d1eea32fb0ab6ef48796d23614bbc4059c39fe Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Fri, 9 Oct 2026 13:06:21 +0200 Subject: [PATCH 1/9] Default API tests to web-service-key authentication Consolidate reviewed API re-enablement and fixture fixes on latest main. Prepare test-user keys in the runner transaction without committing fixtures. Bound the draft branch validation independently of the platform SQL fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91 --- .github/AL-Go-Settings.json | 23 + .github/workflows/CICD.yaml | 2 + .github/workflows/PullRequestHandler.yaml | 2 +- LOCAL_DEV_ENV.md | 52 + .../Test Apps AT/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps AU/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps BE/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps CA/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps CH/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps CZ/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps DE/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps DK/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps ES/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps FI/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps FR/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps GB/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps IN/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps IS/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps IT/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps MX/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps NL/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps NO/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps NZ/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps RU/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps SE/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps US/.AL-Go/PipelineFinalize.ps1 | 1 - .../Test Apps W1/.AL-Go/PipelineFinalize.ps1 | 1 - build/scripts/ApiTestCredential.psm1 | 117 - build/scripts/NewBcContainer.ps1 | 9 - build/scripts/PipelineFinalize.ps1 | 13 - build/scripts/Remove-ApiTestPassword.ps1 | 34 - .../scripts/tests/ApiTestCredential.Test.ps1 | 346 +- .../tests/Remove-ApiTestPassword.Test.ps1 | 223 - .../test/src/IRS1099APITests.Codeunit.al | 2 + .../test/src/APIV1AccountsE2E.Codeunit.al | 2 + .../APIV1/test/src/APIV1AgedAPE2E.Codeunit.al | 2 + .../APIV1/test/src/APIV1AgedARE2E.Codeunit.al | 2 + .../test/src/APIV1AttachmentsE2E.Codeunit.al | 76 + .../src/APIV1AutomationRSPackage.Codeunit.al | 18 +- .../test/src/APIV1BalanceSheetE2E.Codeunit.al | 1 + .../src/APIV1CashFlowStatementE2E.Codeunit.al | 1 + .../test/src/APIV1CompanyInfoE2E.Codeunit.al | 2 + .../test/src/APIV1CurrenciesE2E.Codeunit.al | 1 + .../src/APIV1CustomerPaymentsE2E.Codeunit.al | 5 +- .../test/src/APIV1CustomersE2E.Codeunit.al | 1 + .../src/APIV1DefaultDimensionsE2E.Codeunit.al | 71 + .../src/APIV1DimensionLinesE2E.Codeunit.al | 12 +- .../test/src/APIV1DimensionsE2E.Codeunit.al | 2 + .../test/src/APIV1EmployeesE2E.Codeunit.al | 1 + .../test/src/APIV1GLEntriesE2E.Codeunit.al | 10 +- .../src/APIV1IncomeStatementE2E.Codeunit.al | 1 + .../src/APIV1ItemCategoriesE2E.Codeunit.al | 1 + .../test/src/APIV1ItemVariantsE2E.Codeunit.al | 34 + .../APIV1/test/src/APIV1ItemsE2E.Codeunit.al | 1 + .../test/src/APIV1JournalLinesE2E.Codeunit.al | 3 + .../test/src/APIV1JournalsE2E.Codeunit.al | 4 + .../test/src/APIV1PDFDocumentE2E.Codeunit.al | 4 +- .../test/src/APIV1PaymentTermsE2E.Codeunit.al | 2 + .../test/src/APIV1PicturesE2E.Codeunit.al | 57 + .../src/APIV1PurchaseInvLinesE2E.Codeunit.al | 18 +- .../src/APIV1PurchaseInvoicesE2E.Codeunit.al | 42 +- .../test/src/APIV1RetEarningsE2E.Codeunit.al | 1 + .../src/APIV1SalesCrMemoLinesE2E.Codeunit.al | 18 +- .../src/APIV1SalesCreditMemosE2E.Codeunit.al | 64 +- .../src/APIV1SalesInvLinesE2E.Codeunit.al | 14 +- .../src/APIV1SalesOrderLinesE2E.Codeunit.al | 22 +- .../test/src/APIV1SalesOrdersE2E.Codeunit.al | 36 + .../src/APIV1SalesQuoteLinesE2E.Codeunit.al | 18 +- .../test/src/APIV1SalesQuotesE2E.Codeunit.al | 44 + .../src/APIV1ShipmentMethodsE2E.Codeunit.al | 2 + .../test/src/APIV1TaxAreasE2E.Codeunit.al | 1 + .../test/src/APIV1TrialBalanceE2E.Codeunit.al | 2 + .../APIV1/test/src/APIV1UofME2E.Codeunit.al | 13 + .../test/src/APIV1VendorsE2E.Codeunit.al | 1 + .../test/src/CountriesRegionsE2E.Codeunit.al | 1 + .../test/src/PaymentMethodsE2E.Codeunit.al | 1 + .../test/src/SalesInvoicesE2E.Codeunit.al | 75 + .../APIV1/test/src/TaxGroupsE2E.Codeunit.al | 1 + .../src/APIV2AccountingPeriodsE2E.Codeunit.al | 7 + .../test/src/APIV2AccountsE2E.Codeunit.al | 4 +- .../APIV2/test/src/APIV2AgedAPE2E.Codeunit.al | 4 +- .../APIV2/test/src/APIV2AgedARE2E.Codeunit.al | 4 +- .../src/APIV2ApplyVendorEntE2E.Codeunit.al | 6 +- .../src/APIV2ApprovalEntriesE2E.Codeunit.al | 7 +- .../src/APIV2ApprovalUserSetupE2E.Codeunit.al | 7 +- .../src/APIV2AssemblyOrdersE2E.Codeunit.al | 19 + .../test/src/APIV2AttachmentsE2E.Codeunit.al | 98 + .../src/APIV2AutomationRSPackage.Codeunit.al | 4 +- .../test/src/APIV2BalanceSheetE2E.Codeunit.al | 3 +- .../src/APIV2BlPurchOrdersE2E.Codeunit.al | 18 + .../src/APIV2BlSalesOrdersE2E.Codeunit.al | 18 + .../src/APIV2CashFlowStatementE2E.Codeunit.al | 3 +- .../test/src/APIV2CompanyInfoE2E.Codeunit.al | 2 + .../test/src/APIV2ContactsE2E.Codeunit.al | 3 + .../test/src/APIV2ContactsInfE2E.Codeunit.al | 14 + .../src/APIV2CountriesRegionsE2E.Codeunit.al | 3 +- .../test/src/APIV2CurrenciesE2E.Codeunit.al | 3 +- .../src/APIV2CurrencyExchRateE2E.Codeunit.al | 2 + .../src/APIV2CustRetReasonsE2E.Codeunit.al | 2 + .../src/APIV2CustomerPaymentsE2E.Codeunit.al | 6 +- .../test/src/APIV2CustomersE2E.Codeunit.al | 2 + .../src/APIV2DefaultDimensionsE2E.Codeunit.al | 65 + .../test/src/APIV2DimSetLinesE2E.Codeunit.al | 64 + .../test/src/APIV2DimensionsE2E.Codeunit.al | 4 +- .../src/APIV2DocumentAttachE2E.Codeunit.al | 84 + .../test/src/APIV2EmployeesE2E.Codeunit.al | 3 +- .../test/src/APIV2FALocationsE2E.Codeunit.al | 2 + .../test/src/APIV2FixedAssetsE2E.Codeunit.al | 2 + .../test/src/APIV2GLEntriesE2E.Codeunit.al | 5 +- .../test/src/APIV2GLSetupE2E.Codeunit.al | 8 + .../src/APIV2GenProdPostGroupE2E.Codeunit.al | 12 +- .../src/APIV2IncomeStatementE2E.Codeunit.al | 3 +- .../APIV2InventoryPostGroupE2E.Codeunit.al | 12 +- .../src/APIV2ItemCategoriesE2E.Codeunit.al | 3 +- .../test/src/APIV2ItemVariantsE2E.Codeunit.al | 35 + .../APIV2/test/src/APIV2ItemsE2E.Codeunit.al | 5 +- .../src/APIV2JobQueueEntriesE2E.Codeunit.al | 13 + .../APIV2JobQueueLogEntriesE2E.Codeunit.al | 7 + .../test/src/APIV2JournalsE2E.Codeunit.al | 6 +- .../test/src/APIV2LocationsE2E.Codeunit.al | 3 + .../src/APIV2OpportunitiesE2E.Codeunit.al | 24 + .../test/src/APIV2PDFDocumentE2E.Codeunit.al | 3 +- .../src/APIV2PaymentMethodsE2E.Codeunit.al | 3 +- .../test/src/APIV2PaymentTermsE2E.Codeunit.al | 4 +- .../test/src/APIV2PicturesE2E.Codeunit.al | 74 +- .../APIV2PstdApprovalEntriesE2E.Codeunit.al | 6 + .../src/APIV2PurchCrMLinesE2E.Codeunit.al | 46 + .../test/src/APIV2PurchCrMemosE2E.Codeunit.al | 39 +- .../src/APIV2PurchOrderLinesE2E.Codeunit.al | 5 + .../test/src/APIV2PurchQuotesE2E.Codeunit.al | 18 + .../src/APIV2PurchRcptLinesE2E.Codeunit.al | 14 + .../src/APIV2PurchRetOrdersE2E.Codeunit.al | 18 + .../src/APIV2PurchRetShptsE2E.Codeunit.al | 12 + .../src/APIV2PurchaseInvLinesE2E.Codeunit.al | 4 +- .../src/APIV2PurchaseInvoicesE2E.Codeunit.al | 6 + .../src/APIV2PurchaseOrdersE2E.Codeunit.al | 26 +- .../src/APIV2PurchaseReceiptsE2E.Codeunit.al | 10 + .../test/src/APIV2RetEarningsE2E.Codeunit.al | 3 +- .../src/APIV2SalesCrMemoLinesE2E.Codeunit.al | 5 +- .../src/APIV2SalesCreditMemosE2E.Codeunit.al | 66 +- .../src/APIV2SalesInvLinesE2E.Codeunit.al | 5 + .../src/APIV2SalesInvoicesE2E.Codeunit.al | 82 + .../test/src/APIV2SalesOrdArchE2E.Codeunit.al | 12 + .../src/APIV2SalesOrderLinesE2E.Codeunit.al | 8 +- .../test/src/APIV2SalesOrdersE2E.Codeunit.al | 39 + .../src/APIV2SalesQuoteLinesE2E.Codeunit.al | 4 +- .../test/src/APIV2SalesQuotesE2E.Codeunit.al | 47 + .../src/APIV2SalesRetOrdersE2E.Codeunit.al | 18 + .../src/APIV2SalesShipLinesE2E.Codeunit.al | 14 + .../src/APIV2SalesShipmentsE2E.Codeunit.al | 10 + .../src/APIV2SalespersonPurchE2E.Codeunit.al | 2 + .../src/APIV2ShipmentMethodsE2E.Codeunit.al | 3 + .../test/src/APIV2TaxAreasE2E.Codeunit.al | 3 +- .../test/src/APIV2TaxGroupsE2E.Codeunit.al | 3 +- .../src/APIV2TransferOrdersE2E.Codeunit.al | 18 + .../test/src/APIV2TrialBalanceE2E.Codeunit.al | 4 +- .../APIV2/test/src/APIV2UofME2E.Codeunit.al | 15 +- .../src/APIV2VendorPaymentsE2E.Codeunit.al | 5 +- .../test/src/APIV2VendorsE2E.Codeunit.al | 2 + .../src/APIV2WorkflowApproversE2E.Codeunit.al | 7 +- .../test/src/APIV2WorkflowsE2E.Codeunit.al | 7 +- .../src/APIV2itemLedgEntriesE2E.Codeunit.al | 4 +- .../src/Processing/EDocAPITest.Codeunit.al | 14 +- .../TravelRequestApproval.Codeunit.al | 29 +- .../API/ExpenseActivityLogAPITest.Codeunit.al | 18 +- .../ExpenseCapabilitiesAPITest.Codeunit.al | 4 - .../ExpensePerDiemLocationsTest.Codeunit.al | 3 +- .../API/ExpenseProjectsAPITest.Codeunit.al | 2 - .../src/API/ExpenseUsersAPITest.Codeunit.al | 2 - .../src/API/ExpenseVATSpecAPITest.Codeunit.al | 3 +- .../API/PoliciesToEvaluateAPITest.Codeunit.al | 2 - .../API/PolicyEvaluationsAPITest.Codeunit.al | 2 - .../src/API/TravelRequestsAPITest.Codeunit.al | 8 - .../src/ExpensePermissionsTest.Codeunit.al | 141 +- .../ExpenseAPITestAuthHelper.Codeunit.al | 61 - .../ExpDetailTest.PermissionSet.al | 20 + .../test/src/SpendRequestTest.Codeunit.al | 180 +- .../Test/E2EPowerBIFinanceTest.Codeunit.al | 22 + .../Test/E2EPowerBIInventoryTest.Codeunit.al | 64 + .../E2EPowerBIManufacturingTest.Codeunit.al | 37 + .../Test/E2EPowerBIProjectTest.Codeunit.al | 18 + .../Test/E2EPowerBIPurchasesTest.Codeunit.al | 26 + .../src/PowerBISustainabilityTest.Codeunit.al | 10 + .../E-Document Core Tests.DisabledTest.json | 7 +- .../Expense_Agent_Tests.DisabledTest.json | 255 -- .../_Exclude_APIV1__Tests.DisabledTest.json | 1458 +------ .../_Exclude_APIV2__Tests.DisabledTest.json | 3580 ----------------- .../ERMGeneralJournalUT.Codeunit.al | 1 - .../Prepayment/ERMPrepaymentII.Codeunit.al | 1 - .../ERMGeneralJournalUT.Codeunit.al | 1 - .../ERMGeneralJournalUT.Codeunit.al | 1 - .../ERMGeneralJournalUT.Codeunit.al | 1 - .../ERMGeneralJournalUT.Codeunit.al | 1 - .../Prepayment/ERMPrepaymentII.Codeunit.al | 1 - .../ReturnShptPDFDocHandler.Codeunit.al | 2 +- .../Tests/ERM/SpendRequestTests.Codeunit.al | 48 + .../ERMGeneralJournalUT.Codeunit.al | 1 - .../IRS1099CodeEntityE2ETest.Codeunit.al | 1 - .../WFWHSubscriptionE2ETests.Codeunit.al | 2 +- .../Integration/ApiRoutesE2E.Codeunit.al | 15 +- .../Integration/WebhookLogsE2E.Codeunit.al | 1 - .../Misc/APITestAuthProviderTests.Codeunit.al | 183 +- .../Prepayment/ERMPrepaymentII.Codeunit.al | 2 - .../LibraryGraphDocumentTools.Codeunit.al | 33 +- .../LibraryGraphJournalLines.Codeunit.al | 10 +- .../TestLibraries/LibraryGraphMgt.Codeunit.al | 24 + .../MicrosoftTestAuthProvider.Codeunit.al | 151 +- src/Layers/W1/Tests/TestLibraries/app.json | 6 + 208 files changed, 2960 insertions(+), 6299 deletions(-) delete mode 100644 build/projects/Test Apps AT/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps AU/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps BE/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps CA/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps CH/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps CZ/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps DE/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps DK/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps ES/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps FI/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps FR/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps GB/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps IN/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps IS/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps IT/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps MX/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps NL/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps NO/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps NZ/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps RU/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps SE/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps US/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/projects/Test Apps W1/.AL-Go/PipelineFinalize.ps1 delete mode 100644 build/scripts/ApiTestCredential.psm1 delete mode 100644 build/scripts/PipelineFinalize.ps1 delete mode 100644 build/scripts/Remove-ApiTestPassword.ps1 delete mode 100644 build/scripts/tests/Remove-ApiTestPassword.Test.ps1 delete mode 100644 src/Apps/W1/ExpenseAgent/test/src/Helper/ExpenseAPITestAuthHelper.Codeunit.al create mode 100644 src/Apps/W1/ExpenseAgent/test/src/Permissions/ExpDetailTest.PermissionSet.al diff --git a/.github/AL-Go-Settings.json b/.github/AL-Go-Settings.json index 10252f246f2..be27f285838 100644 --- a/.github/AL-Go-Settings.json +++ b/.github/AL-Go-Settings.json @@ -22,6 +22,29 @@ "parallelism": -1 }, "conditionalSettings": [ + { + "branches": [ + "features/646383-api-webkey-default-single-pr" + ], + "triggers": [ + "workflow_dispatch" + ], + "settings": { + "projects": [ + "build/projects/Apps W1", + "build/projects/Apps DE", + "build/projects/Apps CA", + "build/projects/Apps US", + "build/projects/Apps IT", + "build/projects/Test Apps W1", + "build/projects/Test Apps DE", + "build/projects/Test Apps CA", + "build/projects/Test Apps US", + "build/projects/Test Apps IT" + ], + "maxTestAppReruns": 0 + } + }, { "buildModes": [ "Clean" diff --git a/.github/workflows/CICD.yaml b/.github/workflows/CICD.yaml index d7ea8f5a657..93053059ef7 100644 --- a/.github/workflows/CICD.yaml +++ b/.github/workflows/CICD.yaml @@ -185,6 +185,7 @@ jobs: needs: [ Initialization ] if: (!failure()) && (!cancelled()) && fromJson(needs.Initialization.outputs.buildOrderJson)[0].projectsCount > 0 strategy: + max-parallel: ${{ github.ref_name == 'features/646383-api-webkey-default-single-pr' && 6 || 256 }} matrix: include: ${{ fromJson(needs.Initialization.outputs.buildOrderJson)[0].buildDimensions }} fail-fast: false @@ -210,6 +211,7 @@ jobs: needs: [ Initialization, Build1 ] if: (!failure()) && (!cancelled()) && (needs.Build1.result == 'success' || needs.Build1.result == 'skipped') && fromJson(needs.Initialization.outputs.buildOrderJson)[1].projectsCount > 0 strategy: + max-parallel: ${{ github.ref_name == 'features/646383-api-webkey-default-single-pr' && 6 || 256 }} matrix: include: ${{ fromJson(needs.Initialization.outputs.buildOrderJson)[1].buildDimensions }} fail-fast: false diff --git a/.github/workflows/PullRequestHandler.yaml b/.github/workflows/PullRequestHandler.yaml index 9c83acaff89..287dbea19ec 100644 --- a/.github/workflows/PullRequestHandler.yaml +++ b/.github/workflows/PullRequestHandler.yaml @@ -35,7 +35,7 @@ jobs: Initialization: needs: [ PregateCheck ] - if: (!failure() && !cancelled()) + if: (!failure() && !cancelled()) && github.head_ref != 'features/646383-api-webkey-default-single-pr' runs-on: [ windows-latest ] outputs: projects: ${{ steps.determineProjectsToBuild.outputs.ProjectsJson }} diff --git a/LOCAL_DEV_ENV.md b/LOCAL_DEV_ENV.md index cb724a60b93..488186dbaa6 100644 --- a/LOCAL_DEV_ENV.md +++ b/LOCAL_DEV_ENV.md @@ -41,6 +41,58 @@ Running the above will * Set up launch.jsons and settings.jsons in your VSCode * Compile and publish all AL apps that match `.\src\System Application\` +## API test authentication + +`Library - Graph Mgt` uses the Microsoft test authentication provider by default. +API tests do not need a `SetAuthenticationProvider` call, a password file, or a +Key Vault password lookup. Container and test-session credentials are still +required to provision and connect to the NST; they are not handed to API requests. + +On-premises **NavUserPassword** requests use the current user's web service key. +The standard AL test runner prepares a missing key in `OnBeforeTestRun`, whose +transaction finishes before the test method starts. This also supports read-only +API tests using `AutoCommit` or `AutoRollback`, which start a write transaction +even without fixture writes. Preparation applies to the current test user when +`Tests-TestLibraries` is installed, including non-API tests; it does not select +credentials for individual requests or rotate an existing key. No key is +provisioned by the pipeline or extension installation. + +An existing valid key is read on each request without a credential cache. If no +key exists, a read-only caller raises an internal isolated event. Its subscriber +locks and rechecks the current user, then creates a key with a 24-hour expiry. +The platform commits this separate key transaction before returning; the provider +then rereads the key rather than trusting an event output that could survive a +rollback. The lock and recheck prevent competing test sessions for the same +tenant/user from replacing each other's newly created key. + +If the key is missing and the caller has uncommitted writes, authentication fails +explicitly **without committing fixture data**. Initialize authentication before +fixture writes or use the test's existing committed fixture boundary; do not add +a request-side commit to hide an incomplete fixture. Existing valid keys remain +read-only even when the caller has writes. Expired keys fail explicitly rather +than silently rotating credentials used by other clients. + +Isolated events have different semantics during extension install/upgrade; API +test requests belong in normal test execution, not installation/upgrade triggers. +First-use visibility to the separate HTTP session, rollback, and concurrent first +use still require target-server validation; source-contract tests alone do not +establish those runtime results. + +Windows, SaaS, and other authentication modes retain ambient authentication. +Custom enum providers and `SetAuthenticationProvider` remain supported. Explicit +`Enum::"API Test Authentication"::None` still opts out, including on the first +request. The final `OnAfterInitializeWebRequestWithURL` event still runs after the +provider. Event-only custom authentication that must avoid default key acquisition +should explicitly select `None` before creating the request. +This request-level opt-out does not undo the standard runner's test-user key +preparation. Custom runners can prepare the key before starting test transactions, +or use the read-only first-request path. + +API fixture initializers reapply the existing test-license-compatible work date +(November 15 of the current year) before creating date-sensitive data, including +after an initialization guard has previously been set. This controls fixture +dates, not license enforcement or the authentication key's real-time expiry. + ## GDL development (layers and views) Anything that ships in multiple localizations (the **Base Application** and the application layers) lives under `src/Layers`, organized by country/region. Each country's app is composed by overlapping multiple **layers** in order: a `W1` ("worldwide") base, optional regional layers, and the country layer. For example, the `US` app is composed of `W1` + `NA` + `US`, where each layer either introduces new objects or replaces objects from a base layer. diff --git a/build/projects/Test Apps AT/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps AT/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps AT/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps AU/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps AU/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps AU/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps BE/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps BE/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps BE/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps CA/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps CA/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps CA/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps CH/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps CH/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps CH/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps CZ/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps CZ/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps CZ/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps DE/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps DE/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps DE/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps DK/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps DK/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps DK/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps ES/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps ES/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps ES/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps FI/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps FI/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps FI/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps FR/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps FR/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps FR/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps GB/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps GB/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps GB/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps IN/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps IN/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps IN/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps IS/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps IS/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps IS/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps IT/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps IT/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps IT/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps MX/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps MX/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps MX/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps NL/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps NL/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps NL/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps NO/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps NO/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps NO/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps NZ/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps NZ/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps NZ/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps RU/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps RU/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps RU/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps SE/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps SE/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps SE/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps US/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps US/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps US/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/projects/Test Apps W1/.AL-Go/PipelineFinalize.ps1 b/build/projects/Test Apps W1/.AL-Go/PipelineFinalize.ps1 deleted file mode 100644 index a726947778c..00000000000 --- a/build/projects/Test Apps W1/.AL-Go/PipelineFinalize.ps1 +++ /dev/null @@ -1 +0,0 @@ -. (Join-Path $PSScriptRoot '../../../scripts/PipelineFinalize.ps1' -Resolve) diff --git a/build/scripts/ApiTestCredential.psm1 b/build/scripts/ApiTestCredential.psm1 deleted file mode 100644 index 5983d23d783..00000000000 --- a/build/scripts/ApiTestCredential.psm1 +++ /dev/null @@ -1,117 +0,0 @@ -function New-ApiTestPasswordFileStream { - param([Parameter(Mandatory = $true)][string]$FilePath) - - $ErrorActionPreference = 'Stop' - $security = [System.Security.AccessControl.FileSecurity]::new() - $security.SetAccessRuleProtection($true, $false) - $writerSid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value - $entries = @( - @{ Sid = 'S-1-5-18'; Rights = [System.Security.AccessControl.FileSystemRights]::FullControl } - @{ Sid = 'S-1-5-20'; Rights = [System.Security.AccessControl.FileSystemRights]::Read } - @{ Sid = 'S-1-5-32-544'; Rights = [System.Security.AccessControl.FileSystemRights]::FullControl } - ) - if ($writerSid -notin @('S-1-5-18', 'S-1-5-32-544')) { - # The host identity writes the credential and deletes it during cleanup; it needs - # neither ReadData nor FullControl. Container service identities retain their access. - $entries += @{ - Sid = $writerSid - Rights = [System.Security.AccessControl.FileSystemRights]'Write, Delete' - } - } - foreach ($entry in $entries) { - $security.AddAccessRule([System.Security.AccessControl.FileSystemAccessRule]::new( - [System.Security.Principal.SecurityIdentifier]::new($entry.Sid), - $entry.Rights, - [System.Security.AccessControl.AccessControlType]::Allow)) - } - - # Supply the protected DACL to CreateFile itself, not Set-Acl after creation. - # CreateNew also refuses to follow or overwrite a pre-existing credential file. - if ($PSVersionTable.PSEdition -eq 'Core') { - return [System.IO.FileSystemAclExtensions]::Create( - [System.IO.FileInfo]::new($FilePath), [System.IO.FileMode]::CreateNew, - [System.Security.AccessControl.FileSystemRights]::Write, [System.IO.FileShare]::None, - 4096, [System.IO.FileOptions]::None, $security) - } - return [System.IO.FileStream]::new( - $FilePath, [System.IO.FileMode]::CreateNew, - [System.Security.AccessControl.FileSystemRights]::Write, [System.IO.FileShare]::None, - 4096, [System.IO.FileOptions]::None, $security) -} - -<# -.SYNOPSIS - Creates the API test credential directly in the container's shared my mount. -.DESCRIPTION - Records cleanup identity before atomically creating a new file with a protected - DACL. No plaintext staging copies are made. SYSTEM and Administrators retain full - access, NetworkService can read, and the host writer can write and delete. - An existing file or unresolved mount is an error, including outside CI. Successful - pipelines finalize cleanup; failed/cancelled pipelines rely on container teardown. -#> -function Write-ApiTestPassword { - param( - [Parameter(Mandatory = $true)] - [ValidatePattern('^[a-zA-Z0-9][a-zA-Z0-9_.-]*$')] - [string]$ContainerName, - [Parameter(Mandatory = $true)] - [PSCredential]$Credential - ) - - $ErrorActionPreference = 'Stop' - $myFolders = @((Get-BcContainerSharedFolders -containerName $ContainerName).GetEnumerator() | - Where-Object { $_.Value.TrimEnd('\') -eq 'C:\Run\my' }) - if ($myFolders.Count -ne 1) { - throw "Cannot resolve the API test credential's container mount." - } - $filePath = Join-Path $myFolders[0].Key 'ApiTestPassword' - # PipelineFinalize runs in this process; GITHUB_ENV only affects later steps. - $env:BCAppsApiTestPasswordPath = $filePath - $env:BCAppsApiTestPasswordContainer = $ContainerName - if ($env:GITHUB_ENV) { - Add-Content -LiteralPath $env:GITHUB_ENV -Encoding UTF8 -Value @( - "BCAppsApiTestPasswordPath=$filePath" - "BCAppsApiTestPasswordContainer=$ContainerName" - ) -ErrorAction Stop - } - - $created = $false - $bytes = $null - $characters = $null - $passwordBuffer = [IntPtr]::Zero - try { - # Write directly to the shared mount. Copy-FileToBcContainer would introduce - # another host staging copy with inherited permissions. - $stream = New-ApiTestPasswordFileStream -FilePath $filePath - $created = $true - try { - $passwordBuffer = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password) - $characters = [char[]]::new($Credential.Password.Length) - [System.Runtime.InteropServices.Marshal]::Copy($passwordBuffer, $characters, 0, $characters.Length) - $bytes = [System.Text.UTF8Encoding]::new($false).GetBytes($characters) - $stream.Write($bytes, 0, $bytes.Length) - } - finally { - if ($null -ne $bytes) { [Array]::Clear($bytes, 0, $bytes.Length) } - if ($null -ne $characters) { [Array]::Clear($characters, 0, $characters.Length) } - if ($passwordBuffer -ne [IntPtr]::Zero) { - [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($passwordBuffer) - } - $stream.Dispose() - } - } - catch { - $originalError = $_ - if ($created) { - try { - & (Join-Path $PSScriptRoot 'Remove-ApiTestPassword.ps1') -ContainerName $ContainerName -FilePath $filePath - } - catch { - Write-Warning 'Could not clean up the API test credential after setup failed; container teardown is still required.' - } - } - throw $originalError - } -} - -Export-ModuleMember -Function Write-ApiTestPassword diff --git a/build/scripts/NewBcContainer.ps1 b/build/scripts/NewBcContainer.ps1 index 78871ab947b..d6e98d84794 100644 --- a/build/scripts/NewBcContainer.ps1 +++ b/build/scripts/NewBcContainer.ps1 @@ -24,15 +24,6 @@ if ($platformVersion) { New-BcContainer @parameters -if ($parameters.auth -in @('UserPassword', 'NavUserPassword')) { - if (-not $parameters.credential) { - throw "The BCApps UserPassword test container requires a credential." - } - - Import-Module (Join-Path $PSScriptRoot 'ApiTestCredential.psm1') -Force - Write-ApiTestPassword -ContainerName $parameters.ContainerName -Credential $parameters.credential -} - Set-BcContainerServerConfiguration -containerName $parameters.ContainerName -keyName "EnforceUserPathForAlFileOperations" -keyValue "false" Set-BcContainerServerConfiguration -containerName $parameters.ContainerName -keyName "UsePermissionSetsFromExtensions" -keyValue "true" Restart-BcContainer -containerName $parameters.ContainerName diff --git a/build/scripts/PipelineFinalize.ps1 b/build/scripts/PipelineFinalize.ps1 deleted file mode 100644 index 006bdc54b80..00000000000 --- a/build/scripts/PipelineFinalize.ps1 +++ /dev/null @@ -1,13 +0,0 @@ -$ErrorActionPreference = 'Stop' - -# This hook is success-only. Failures/cancellation rely on normal container teardown, -# not guaranteed after runner loss. CI credentials are per-run; other callers may differ. -if (-not $env:BCAppsApiTestPasswordPath) { - return -} - -Write-Host 'API test credential cleanup (PipelineFinalize).' -& (Join-Path $PSScriptRoot 'Remove-ApiTestPassword.ps1') ` - -ContainerName $env:BCAppsApiTestPasswordContainer -FilePath $env:BCAppsApiTestPasswordPath -$env:BCAppsApiTestPasswordPath = $null -$env:BCAppsApiTestPasswordContainer = $null diff --git a/build/scripts/Remove-ApiTestPassword.ps1 b/build/scripts/Remove-ApiTestPassword.ps1 deleted file mode 100644 index 4c49720fe99..00000000000 --- a/build/scripts/Remove-ApiTestPassword.ps1 +++ /dev/null @@ -1,34 +0,0 @@ -Param( - [Parameter(Mandatory = $true)] - [ValidatePattern('^[a-zA-Z0-9][a-zA-Z0-9_.-]*$')] - [string]$ContainerName, - [Parameter(Mandatory = $true)] - [string]$FilePath -) - -$ErrorActionPreference = 'Stop' - -if ((Split-Path -Path $FilePath -Leaf) -ne 'ApiTestPassword') { - throw 'API test credential cleanup requires the exact ApiTestPassword file.' -} -if (-not (Test-Path -LiteralPath $FilePath -PathType Leaf)) { - return -} - -# End any remaining test workers before deleting their shared credential. -$containerIds = @(docker container ls --all --filter "name=^/$([regex]::Escape($ContainerName))$" --format '{{.ID}}') -if ($LASTEXITCODE -ne 0) { - throw 'Could not determine whether the API test container still exists.' -} -if ($containerIds.Count -gt 1) { - throw 'API test credential cleanup matched more than one container.' -} -if ($containerIds.Count -eq 1) { - docker stop --time 30 $containerIds[0] | Out-Null - if ($LASTEXITCODE -ne 0) { - throw 'Could not stop API test consumers; leaving credential removal to container teardown.' - } -} - -# The recorded mount path remains usable for stopped or already-removed containers. -Remove-Item -LiteralPath $FilePath -Force -ErrorAction Stop diff --git a/build/scripts/tests/ApiTestCredential.Test.ps1 b/build/scripts/tests/ApiTestCredential.Test.ps1 index f47051ac4e3..42fee402d84 100644 --- a/build/scripts/tests/ApiTestCredential.Test.ps1 +++ b/build/scripts/tests/ApiTestCredential.Test.ps1 @@ -1,249 +1,117 @@ -Describe 'API test credential materialization' { +Describe 'API test authentication source contracts' { BeforeAll { - Import-Module (Join-Path $PSScriptRoot '..\ApiTestCredential.psm1') -Force - $script:previousGitHubEnv = $env:GITHUB_ENV - $script:previousPasswordPath = $env:BCAppsApiTestPasswordPath - $script:previousPasswordContainer = $env:BCAppsApiTestPasswordContainer - $script:previousExitCode = Get-Variable LASTEXITCODE -Scope Global -ValueOnly -ErrorAction SilentlyContinue - $script:createdMountStub = -not (Get-Command Get-BcContainerSharedFolders -ListImported -ErrorAction SilentlyContinue) - if ($script:createdMountStub) { - function global:Get-BcContainerSharedFolders { - param([string]$containerName) - $null = $containerName - throw 'Container mount lookup must be mocked.' - } - } - $script:createdDockerStub = -not (Get-Command docker -ErrorAction SilentlyContinue) - if ($script:createdDockerStub) { - function global:docker { - param([Parameter(ValueFromRemainingArguments = $true)][string[]]$Arguments) - $null = $Arguments - throw 'Docker must be mocked.' - } - } - $script:fixturePassword = [System.Security.SecureString]::new() - foreach ($character in 'synthetic-fixture-only'.ToCharArray()) { - $script:fixturePassword.AppendChar($character) - } - $script:fixturePassword.MakeReadOnly() - $script:credential = [PSCredential]::new('unit-test', $script:fixturePassword) - $script:mount = Join-Path $PSScriptRoot 'unused-mount' - } - - AfterAll { - $script:fixturePassword.Dispose() - $env:GITHUB_ENV = $script:previousGitHubEnv - $env:BCAppsApiTestPasswordPath = $script:previousPasswordPath - $env:BCAppsApiTestPasswordContainer = $script:previousPasswordContainer - $global:LASTEXITCODE = $script:previousExitCode - if ($script:createdMountStub) { Remove-Item function:global:Get-BcContainerSharedFolders } - if ($script:createdDockerStub) { Remove-Item function:global:docker } - } - - BeforeEach { - $env:GITHUB_ENV = Join-Path $PSScriptRoot 'unused-github-env' - $env:BCAppsApiTestPasswordPath = $null - $env:BCAppsApiTestPasswordContainer = $null - $script:events = [System.Collections.Generic.List[string]]::new() - $script:stream = [PSCustomObject]@{ - Events = $script:events - Buffer = $null - Written = $null - FailWrite = $false - FailDispose = $false - } - $script:stream | Add-Member ScriptMethod Write { - param($buffer, $offset, $count) - $this.Events.Add('write') - $this.Buffer = $buffer - $this.Written = [System.Text.Encoding]::UTF8.GetString($buffer, $offset, $count) - if ($this.FailWrite) { throw 'Synthetic write failure' } - } - $script:stream | Add-Member ScriptMethod Dispose { - $this.Events.Add('dispose') - if ($this.FailDispose) { throw 'Synthetic flush failure' } - } - Mock -ModuleName ApiTestCredential Get-BcContainerSharedFolders { @{ $script:mount = 'c:\run\my\' } } - Mock -ModuleName ApiTestCredential Add-Content { $script:events.Add('register') } - Mock -ModuleName ApiTestCredential New-ApiTestPasswordFileStream { - $env:BCAppsApiTestPasswordPath | Should -Be (Join-Path $script:mount 'ApiTestPassword') - $env:BCAppsApiTestPasswordContainer | Should -Be 'unit-test' - $script:events.Add('create') - $script:stream - } - Mock -ModuleName ApiTestCredential Test-Path { $true } - Mock -ModuleName ApiTestCredential docker { - $global:LASTEXITCODE = 0 - if ($args[0] -eq 'container') { 'synthetic-container-id' } - else { $script:events.Add('stop') } - } - Mock -ModuleName ApiTestCredential Remove-Item { $script:events.Add('delete') } - } - - It 'registers cleanup and creates the secured backing file before the first secret write' { - Write-ApiTestPassword -ContainerName 'unit-test' -Credential $script:credential - - ($script:events -join ',') | Should -Be 'register,create,write,dispose' - $script:stream.Written | Should -Be 'synthetic-fixture-only' - @($script:stream.Buffer | Where-Object { $_ -ne 0 }).Count | Should -Be 0 - Should -Invoke -ModuleName ApiTestCredential New-ApiTestPasswordFileStream -Times 1 -Exactly -ParameterFilter { - $FilePath -eq (Join-Path $script:mount 'ApiTestPassword') - } - Should -Invoke -ModuleName ApiTestCredential Add-Content -Times 1 -Exactly -ParameterFilter { - $LiteralPath -eq $env:GITHUB_ENV -and $ErrorAction -eq 'Stop' -and - $Value.Count -eq 2 -and - $Value -contains "BCAppsApiTestPasswordPath=$(Join-Path $script:mount 'ApiTestPassword')" -and - $Value -contains 'BCAppsApiTestPasswordContainer=unit-test' - } - Should -Invoke -ModuleName ApiTestCredential docker -Times 0 - } - - It 'uses the same secured mount locally without workflow registration' { - $env:GITHUB_ENV = '' - Write-ApiTestPassword -ContainerName 'unit-test' -Credential $script:credential - - ($script:events -join ',') | Should -Be 'create,write,dispose' - Should -Invoke -ModuleName ApiTestCredential Get-BcContainerSharedFolders -Times 1 -Exactly - Should -Invoke -ModuleName ApiTestCredential Add-Content -Times 0 - } - - It 'preserves Unicode passwords while clearing the written byte buffer' { - $characters = [char[]]@(0x0061, 0x00E9, 0xD83D, 0xDD10) - $password = [System.Security.SecureString]::new() - try { - foreach ($character in $characters) { $password.AppendChar($character) } - $password.MakeReadOnly() - $credential = [PSCredential]::new('unit-test', $password) - - Write-ApiTestPassword -ContainerName 'unit-test' -Credential $credential - - $script:stream.Written | Should -Be (-join $characters) - @($script:stream.Buffer | Where-Object { $_ -ne 0 }).Count | Should -Be 0 - } - finally { - $password.Dispose() - } - } - - It 'does not materialize an immutable plaintext password string in the writer' { - $source = Get-Content (Join-Path $PSScriptRoot '..\ApiTestCredential.psm1') -Raw - $source | Should -Not -Match 'GetNetworkCredential|PtrToString' - $source | Should -Match 'SecureStringToBSTR' - $source | Should -Match 'ZeroFreeBSTR' - } - - It 'fails closed on an unresolved mount in CI and locally' { - Mock -ModuleName ApiTestCredential Get-BcContainerSharedFolders { @{} } - foreach ($environmentPath in @('unused-github-env', '')) { - $env:GITHUB_ENV = $environmentPath - { Write-ApiTestPassword -ContainerName 'unit-test' -Credential $script:credential } | Should -Throw '*Cannot resolve*' - } - Should -Invoke -ModuleName ApiTestCredential New-ApiTestPasswordFileStream -Times 0 - Should -Invoke -ModuleName ApiTestCredential Add-Content -Times 0 - } - - It 'fails closed on ambiguous mounts' { - Mock -ModuleName ApiTestCredential Get-BcContainerSharedFolders { @{ 'C:\first' = 'C:\Run\my'; 'C:\second' = 'c:\run\my' } } - { Write-ApiTestPassword -ContainerName 'unit-test' -Credential $script:credential } | Should -Throw '*Cannot resolve*' - Should -Invoke -ModuleName ApiTestCredential New-ApiTestPasswordFileStream -Times 0 - } - - It 'does not materialize credentials if workflow cleanup registration fails' { - Mock -ModuleName ApiTestCredential Add-Content { throw 'Synthetic registration failure' } - { Write-ApiTestPassword -ContainerName 'unit-test' -Credential $script:credential } | Should -Throw '*Synthetic registration failure*' - Should -Invoke -ModuleName ApiTestCredential New-ApiTestPasswordFileStream -Times 0 - } - - It 'does not write or delete an existing file when secured creation fails' { - Mock -ModuleName ApiTestCredential New-ApiTestPasswordFileStream { throw 'Synthetic ACL or create failure' } - { Write-ApiTestPassword -ContainerName 'unit-test' -Credential $script:credential } | Should -Throw '*Synthetic ACL or create failure*' - ($script:events -join ',') | Should -Be 'register' - Should -Invoke -ModuleName ApiTestCredential Remove-Item -Times 0 - } - - It 'closes the failed writer and stops consumers before deleting a partial file' { - $script:stream.FailWrite = $true - { Write-ApiTestPassword -ContainerName 'unit-test' -Credential $script:credential } | Should -Throw '*Synthetic write failure*' - - ($script:events -join ',') | Should -Be 'register,create,write,dispose,stop,delete' - @($script:stream.Buffer | Where-Object { $_ -ne 0 }).Count | Should -Be 0 + $script:root = (Resolve-Path (Join-Path $PSScriptRoot '..\..\..')).Path + $libraryRoot = Join-Path $script:root 'src\Layers\W1\Tests\TestLibraries' + $script:provider = Get-Content (Join-Path $libraryRoot 'MicrosoftTestAuthProvider.Codeunit.al') -Raw + $script:graph = Get-Content (Join-Path $libraryRoot 'LibraryGraphMgt.Codeunit.al') -Raw + $script:authentication = Get-Content (Join-Path $libraryRoot 'APITestAuthentication.Enum.al') -Raw + $script:context = Get-Content (Join-Path $libraryRoot 'APITestAuthContext.Codeunit.al') -Raw + $script:container = Get-Content (Join-Path $script:root 'build\scripts\NewBcContainer.ps1') -Raw } - It 'also cleans up after a flush failure without reporting success' { - $script:stream.FailDispose = $true - { Write-ApiTestPassword -ContainerName 'unit-test' -Credential $script:credential } | Should -Throw '*Synthetic flush failure*' - ($script:events -join ',') | Should -Be 'register,create,write,dispose,stop,delete' + It 'defaults only unresolved library instances to Microsoft authentication' { + $script:graph | Should -Match '(?s)local procedure GetAuthenticationProvider\(\).*?if not AuthenticationProviderResolved then begin\s+Authentication := Authentication::"Microsoft Test Environment";' + $script:graph | Should -Match '(?s)procedure SetAuthenticationProvider\(.*?Authentication := NewAuthentication;\s+AuthenticationProvider := Authentication;\s+AuthenticationProviderResolved := true;' } - It 'preserves the setup error and credential when consumers cannot be stopped' { - $script:stream.FailWrite = $true - Mock -ModuleName ApiTestCredential docker { $global:LASTEXITCODE = 1 } -ParameterFilter { $args[0] -eq 'stop' } - Mock -ModuleName ApiTestCredential Write-Warning {} + It 'preserves explicit None and unknown enum fallback semantics' { + $script:authentication | Should -Match '(?s)value\(0; None\).*?Implementation = "API Test Auth Provider" = "No API Test Auth Provider";' + $script:authentication | Should -Match 'DefaultImplementation = "API Test Auth Provider" = "No API Test Auth Provider";' + $script:authentication | Should -Match 'Extensible = true;' + } - { Write-ApiTestPassword -ContainerName 'unit-test' -Credential $script:credential } | Should -Throw '*Synthetic write failure*' - Should -Invoke -ModuleName ApiTestCredential Remove-Item -Times 0 - Should -Invoke -ModuleName ApiTestCredential Write-Warning -Times 1 -Exactly + It 'preserves custom provider instance state on repeated selection' { + $script:graph | Should -Match '(?s)if AuthenticationProviderResolved and \(Authentication = NewAuthentication\) then\s+exit;' } -} -Describe 'API test credential atomic Windows ACL' { - BeforeAll { - Import-Module (Join-Path $PSScriptRoot '..\ApiTestCredential.psm1') -Force - $script:aclRoot = Join-Path $PSScriptRoot ("acl-fixture-" + [guid]::NewGuid().ToString('N')) - New-Item -ItemType Directory -Path $script:aclRoot | Out-Null - } - - AfterAll { - Remove-Item -LiteralPath $script:aclRoot -Recurse -Force - } - - It 'has only required explicit SIDs on an empty file before writing synthetic bytes' { - $path = Join-Path $script:aclRoot 'ApiTestPassword' - $stream = $null - try { - $stream = & (Get-Module ApiTestCredential) { param($path) New-ApiTestPasswordFileStream -FilePath $path } $path - $stream.Length | Should -Be 0 - $acl = Get-Acl -LiteralPath $path - $acl.AreAccessRulesProtected | Should -BeTrue - $rules = @($acl.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier])) - @($rules | Where-Object IsInherited).Count | Should -Be 0 - $writerSid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value - $expectedSids = @('S-1-5-18', 'S-1-5-20', 'S-1-5-32-544', $writerSid) | Select-Object -Unique - ($rules.IdentityReference.Value | Sort-Object) | Should -Be ($expectedSids | Sort-Object) - foreach ($sid in @('S-1-5-18', 'S-1-5-32-544')) { - ($rules | Where-Object { $_.IdentityReference.Value -eq $sid }).FileSystemRights | - Should -Be ([System.Security.AccessControl.FileSystemRights]::FullControl) - } - $networkServiceRights = [System.Security.AccessControl.FileSystemRights]'Read, Synchronize' - if ($writerSid -eq 'S-1-5-20') { - $networkServiceRights = $networkServiceRights -bor [System.Security.AccessControl.FileSystemRights]'Write, Delete' - } - ($rules | Where-Object { $_.IdentityReference.Value -eq 'S-1-5-20' }).FileSystemRights | - Should -Be $networkServiceRights - if ($writerSid -notin @('S-1-5-18', 'S-1-5-20', 'S-1-5-32-544')) { - ($rules | Where-Object { $_.IdentityReference.Value -eq $writerSid }).FileSystemRights | - Should -Be ([System.Security.AccessControl.FileSystemRights]'Write, Delete, Synchronize') - } - $stream.WriteByte(65) - $stream.Length | Should -Be 1 - } - finally { - if ($stream) { $stream.Dispose() } - Remove-Item -LiteralPath $path -Force -ErrorAction SilentlyContinue - } - } - - It 'refuses to overwrite an existing file or change its ACL' { - $path = Join-Path $script:aclRoot 'ApiTestPassword' - [System.IO.File]::WriteAllText($path, 'synthetic-existing-fixture') - $before = (Get-Acl -LiteralPath $path).Sddl - try { - { & (Get-Module ApiTestCredential) { param($path) New-ApiTestPasswordFileStream -FilePath $path } $path } | Should -Throw - [System.IO.File]::ReadAllText($path) | Should -Be 'synthetic-existing-fixture' - (Get-Acl -LiteralPath $path).Sddl | Should -Be $before - } - finally { - Remove-Item -LiteralPath $path -Force - } + It 'retains ambient credentials and the final customization event after authentication' { + $script:graph | Should -Match '(?s)SetUseDefaultCredentials\(true\);\s+ApplyAuthentication\(HttpWebRequestMgt\);\s+OnAfterInitializeWebRequestWithURL\(HttpWebRequestMgt\);' + } + + It 'configures keys only on premises with exact username-password authentication' { + $script:provider | Should -Match '(?s)if EnvironmentInfo.IsSaaSInfrastructure\(\) then\s+exit;\s+if not IdentityManagement.IsUserNamePasswordAuthentication\(\) then\s+exit;\s+Authentication.SetBasicAuthentication\(UserId\(\), GetWebServiceKey\(\)\);' + } + + It 'reuses current-user keys and serializes missing-key creation with a recheck' { + $script:provider | Should -Match '(?s)local procedure EnsureWebServiceKey.*?CurrentUser.LockTable\(\);\s+CurrentUser.Get\(UserSecurityId\(\)\);\s+WebServiceKey := ReadWebServiceKey\(ExpiryDate\);\s+if WebServiceKey.IsEmpty\(\) then begin' + $script:provider | Should -Match 'CreateWebServicesKey\(UserSecurityId\(\), ExpiryDate\)' + $script:provider | Should -Not -Match 'CreateWebServicesKeyNoExpiry|ClearWebServicesKey' + } + + It 'prepares the current test user in the independent runner transaction before fixtures' { + $script:provider | Should -Match '\[EventSubscriber\(ObjectType::Codeunit, Codeunit::"Test Runner - Mgt", ''OnBeforeTestMethodRun''' + $script:provider | Should -Match '(?s)local procedure PrepareTestUserWebServiceKey.*?if Skip or EnvironmentInfo.IsSaaSInfrastructure\(\) then\s+exit;.*?if not IdentityManagement.IsUserNamePasswordAuthentication\(\) then\s+exit;.*?EnsureWebServiceKey\(\);' + $script:provider | Should -Match 'using System.TestTools.TestRunner;' + $manifest = Get-Content (Join-Path $script:root 'src\Layers\W1\Tests\TestLibraries\app.json') -Raw | ConvertFrom-Json + @($manifest.dependencies | Where-Object id -eq '23de40a6-dfe8-4f80-80db-d70f83ce8caf').Count | Should -Be 1 + } + + It 'rejects missing-key creation during caller writes before entering isolation' { + $script:provider | Should -Match '(?s)WebServiceKey := ReadWebServiceKey\(ExpiryDate\);\s+if WebServiceKey.IsEmpty\(\) then begin\s+if Database.IsInWriteTransaction\(\) then\s+Error\(KeyCreationInWriteTransactionErr\);.*?OnCreateWebServiceKey\(KeyCreationSucceeded\);' + $requestPath = [regex]::Match($script:provider, '(?s)local procedure GetWebServiceKey\(\).*?(?=\s+\[InternalEvent)').Value + $requestPath | Should -Not -Match 'LockTable|CreateWebServicesKey\(' + } + + It 'uses a platform-owned isolated subscriber transaction without explicit commits' { + $script:provider | Should -Match '(?s)\[InternalEvent\(false, true\)\]\s+local procedure OnCreateWebServiceKey' + $script:provider | Should -Match '\[EventSubscriber\(ObjectType::Codeunit, Codeunit::"Microsoft Test Auth Provider", ''OnCreateWebServiceKey''' + $script:provider | Should -Match '(?s)\[CommitBehavior\(CommitBehavior::Error\)\]\s+local procedure CreateWebServiceKeyIsolated' + } + + It 'rereads persisted credentials after isolation instead of trusting rollback-surviving event output' { + $script:provider | Should -Match '(?s)OnCreateWebServiceKey\(KeyCreationSucceeded\);\s+if not KeyCreationSucceeded then\s+Error\(KeyCreationFailedErr\);.*?WebServiceKey := ReadWebServiceKey\(ExpiryDate\);' + $script:provider | Should -Match 'local procedure OnCreateWebServiceKey\(var Succeeded: Boolean\)' + $script:provider | Should -Not -Match 'OnCreateWebServiceKey\([^)]*SecretText' + } + + It 'creates bounded keys and rejects expired or empty credentials' { + $script:provider | Should -Match 'ExpiryDate := CurrentDateTime\(\) \+ 24 \* 60 \* 60 \* 1000;' + $script:provider | Should -Match '(?s)if WebServiceKey.IsEmpty\(\) then\s+Error\(EmptyKeyErr\);' + $script:provider | Should -Match '(?s)if \(ExpiryDate <> 0DT\) and \(ExpiryDate <= CurrentDateTime\(\)\) then\s+Error\(ExpiredKeyErr\);' + } + + It 'checks fresh error state for both value-returning identity getters' { + $script:provider | Should -Match '(?s)ClearLastError\(\);\s+WebServiceKey := IdentityManagement.GetWebServicesKey\(UserSecurityId\(\)\);\s+if GetLastErrorText\(\) <>' + $script:provider | Should -Match '(?s)ClearLastError\(\);\s+ExpiryDate := IdentityManagement.GetWebServiceExpiryDate\(UserSecurityId\(\)\);\s+if GetLastErrorText\(\) <>' + } + + It 'does not cache, log, or hand off plaintext credentials' { + $script:provider | Should -Not -Match 'Cached|ApiTestPassword|KeyVault|PasswordFile|Message\(|LogMessage\(|Session.Log' + $script:provider | Should -Match '(?s)\[NonDebuggable\]\s+local procedure ReadWebServiceKey' + $script:provider | Should -Match 'SecretWebServiceKey: SecretText;' + $script:provider | Should -Match 'Clear\(WebServiceKey\);' + $script:context | Should -Match 'BasicPassword: SecretText;' + } + + It 'does not commit the caller transaction while configuring a request' { + $script:provider | Should -Not -Match '(?i)\bCommit\s*\(' + $requestPath = [regex]::Match($script:graph, '(?s)procedure InitializeWebRequestWithURL\(.*?(?= procedure PatchToWebServiceAndCheckResponseCode)').Value + $requestPath | Should -Not -BeNullOrEmpty + $requestPath | Should -Not -Match '(?i)\bCommit\s*\(' + } + + It 'retains container credentials for NST provisioning without an API password file' { + $script:container | Should -Match 'New-BcContainer @parameters' + $script:container | Should -Not -Match 'ApiTestCredential|ApiTestPassword' + Test-Path (Join-Path $script:root 'build\scripts\ApiTestCredential.psm1') | Should -BeFalse + Test-Path (Join-Path $script:root 'build\scripts\Remove-ApiTestPassword.ps1') | Should -BeFalse + Test-Path (Join-Path $script:root 'build\scripts\PipelineFinalize.ps1') | Should -BeFalse + @(Get-ChildItem (Join-Path $script:root 'build\projects') -Filter PipelineFinalize.ps1 -Recurse).Count | Should -Be 0 + } + + It 'keeps HTTP regression coverage on the default and instance-reset paths without explicit uptake' { + $tests = Get-Content (Join-Path $script:root 'src\Layers\W1\Tests\Misc\APITestAuthProviderTests.Codeunit.al') -Raw + $tests | Should -Match 'procedure DefaultAuthenticationRespectsServerAuthMode' + $tests | Should -Match '(?s)\[TransactionModel\(TransactionModel::None\)\]\s+procedure DefaultAuthenticationRespectsServerAuthMode' + $tests | Should -Match 'Clear\(LibraryGraphMgt\);' + $tests | Should -Not -Match '"Microsoft Test Environment"' + $tests | Should -Match 'SetAuthenticationProvider\(Enum::"API Test Authentication"::None\)' + $tests | Should -Match 'RequiredTestIsolation = Disabled;' + Test-Path (Join-Path $script:root 'src\Layers\W1\Tests\Misc\APITestAuthHTTPTests.Codeunit.al') | Should -BeFalse + } + + It 'retains a per-test license-safe date helper independent of authentication' { + $script:graph | Should -Match '(?s)procedure SetLicenseSafeWorkDate\(\)\s+begin\s+WorkDate := DMY2Date\(15, 11, Date2DMY\(Today, 3\)\);' + $script:provider | Should -Not -Match 'WorkDate|SetLicenseSafeWorkDate' } } diff --git a/build/scripts/tests/Remove-ApiTestPassword.Test.ps1 b/build/scripts/tests/Remove-ApiTestPassword.Test.ps1 deleted file mode 100644 index 72eab0f130c..00000000000 --- a/build/scripts/tests/Remove-ApiTestPassword.Test.ps1 +++ /dev/null @@ -1,223 +0,0 @@ -Describe 'API test credential cleanup' { - BeforeAll { - $script:cleanupScript = Join-Path $PSScriptRoot '..\Remove-ApiTestPassword.ps1' - $script:passwordPath = Join-Path $PSScriptRoot 'unused\ApiTestPassword' - $script:previousExitCode = Get-Variable -Name LASTEXITCODE -Scope Global -ValueOnly -ErrorAction SilentlyContinue - function docker { - param([Parameter(ValueFromRemainingArguments = $true)][string[]]$Arguments) - $null = $Arguments - throw 'Docker must be mocked; these tests never contact a container.' - } - } - - AfterAll { - $global:LASTEXITCODE = $script:previousExitCode - } - - BeforeEach { - $script:events = [System.Collections.Generic.List[string]]::new() - Mock Test-Path { $true } - Mock docker { - $global:LASTEXITCODE = 0 - if ($Arguments[0] -eq 'container') { - 'test-container-id' - } - else { - $script:events.Add('stop') - } - } - Mock Remove-Item { $script:events.Add('delete') } - } - - It 'stops all consumers before deleting the exact backing file' { - . $script:cleanupScript -ContainerName 'test-container' -FilePath $script:passwordPath - - ($script:events -join ',') | Should -Be 'stop,delete' - Should -Invoke docker -Times 1 -Exactly -ParameterFilter { - $Arguments[0] -eq 'container' -and $Arguments -contains '--all' -and - $Arguments -contains 'name=^/test-container$' - } - Should -Invoke Remove-Item -Times 1 -Exactly -ParameterFilter { - $LiteralPath -eq $script:passwordPath -and $Force -and $ErrorAction -eq 'Stop' - } - } - - It 'does nothing when the password file is missing' { - Mock Test-Path { $false } - - . $script:cleanupScript -ContainerName 'test-container' -FilePath $script:passwordPath - - Should -Invoke docker -Times 0 - Should -Invoke Remove-Item -Times 0 - } - - It 'removes a leftover backing file when the container is already absent' { - Mock docker { $global:LASTEXITCODE = 0 } - - . $script:cleanupScript -ContainerName 'test-container' -FilePath $script:passwordPath - - ($script:events -join ',') | Should -Be 'delete' - Should -Invoke docker -Times 0 -ParameterFilter { $Arguments[0] -eq 'stop' } - } - - It 'also stops an already-stopped container idempotently before deletion' { - . $script:cleanupScript -ContainerName 'test-container' -FilePath $script:passwordPath - - Should -Invoke docker -Times 1 -Exactly -ParameterFilter { - ($Arguments -join ' ') -eq 'stop --time 30 test-container-id' - } - Should -Invoke Remove-Item -Times 1 -Exactly - } - - It 'fails without deleting when Docker cannot enumerate containers' { - Mock docker { $global:LASTEXITCODE = 1 } - - { . $script:cleanupScript -ContainerName 'test-container' -FilePath $script:passwordPath } | - Should -Throw '*Could not determine*' - Should -Invoke Remove-Item -Times 0 - } - - It 'fails without deleting while consumers cannot be stopped' { - Mock docker { $global:LASTEXITCODE = 1 } -ParameterFilter { $Arguments[0] -eq 'stop' } - - { . $script:cleanupScript -ContainerName 'test-container' -FilePath $script:passwordPath } | - Should -Throw '*Could not stop API test consumers*' - Should -Invoke Remove-Item -Times 0 - } - - It 'fails without stopping or deleting if container identity is ambiguous' { - Mock docker { - $global:LASTEXITCODE = 0 - 'first-id', 'second-id' - } - - { . $script:cleanupScript -ContainerName 'test-container' -FilePath $script:passwordPath } | - Should -Throw '*more than one container*' - Should -Invoke docker -Times 0 -ParameterFilter { $Arguments[0] -eq 'stop' } - Should -Invoke Remove-Item -Times 0 - } - - It 'surfaces deletion failure rather than reporting successful cleanup' { - Mock Remove-Item { throw 'Access denied' } - - { . $script:cleanupScript -ContainerName 'test-container' -FilePath $script:passwordPath } | - Should -Throw '*Access denied*' - } - - It 'rejects a path that does not name the credential file' { - { . $script:cleanupScript -ContainerName 'test-container' -FilePath (Join-Path $TestDrive 'other-file') } | - Should -Throw '*exact ApiTestPassword file*' - Should -Invoke docker -Times 0 - Should -Invoke Remove-Item -Times 0 - } -} - -Describe 'API test credential workflow lifetime' { - BeforeAll { - $script:workflow = Get-Content -LiteralPath (Join-Path $PSScriptRoot '..\..\..\.github\workflows\_BuildALGoProject.yaml') -Raw - $script:setup = Get-Content -LiteralPath (Join-Path $PSScriptRoot '..\NewBcContainer.ps1') -Raw - } - - It 'delegates credential materialization without host or container staging copies' { - $script:setup | Should -Match "Import-Module .*'ApiTestCredential.psm1'" - $script:setup | Should -Match 'Write-ApiTestPassword -ContainerName \$parameters.ContainerName -Credential \$parameters.credential' - $script:setup | Should -Not -Match 'Copy-FileToBcContainer|WriteAllText|GetNetworkCredential|GetTempPath' - } - - It 'leaves generated workflow cleanup unmodified' { - $script:workflow | Should -Not -Match '- name: Remove API test credential|Remove-ApiTestPassword.ps1' - $script:workflow | Should -Match '(?s)- name: Cleanup\r?\n\s+if: always\(\).*?uses: microsoft/AL-Go/Actions/PipelineCleanup@' - } -} - -Describe 'API test credential pipeline finalizer' { - BeforeAll { - $script:finalizer = Join-Path $PSScriptRoot '..\PipelineFinalize.ps1' - $script:previousPasswordPath = $env:BCAppsApiTestPasswordPath - $script:previousPasswordContainer = $env:BCAppsApiTestPasswordContainer - $script:previousExitCode = Get-Variable LASTEXITCODE -Scope Global -ValueOnly -ErrorAction SilentlyContinue - function docker { - param([Parameter(ValueFromRemainingArguments = $true)][string[]]$Arguments) - $null = $Arguments - throw 'Docker must be mocked.' - } - } - - BeforeEach { - $env:BCAppsApiTestPasswordPath = Join-Path $TestDrive 'ApiTestPassword' - $env:BCAppsApiTestPasswordContainer = 'recorded-container' - Mock Test-Path { $true } - Mock docker { - $global:LASTEXITCODE = 0 - if ($Arguments[0] -eq 'container') { 'recorded-container-id' } - } - Mock Remove-Item { - Should -Invoke docker -Times 1 -ParameterFilter { $Arguments[0] -eq 'stop' } - } - Mock Write-Host {} - } - - AfterAll { - $env:BCAppsApiTestPasswordPath = $script:previousPasswordPath - $env:BCAppsApiTestPasswordContainer = $script:previousPasswordContainer - $global:LASTEXITCODE = $script:previousExitCode - } - - It 'accepts no arguments and stops the recorded consumers before deleting the backing file' { - $path = $env:BCAppsApiTestPasswordPath - . $script:finalizer - Should -Invoke docker -Times 1 -Exactly -ParameterFilter { - $Arguments -contains 'name=^/recorded-container$' - } - Should -Invoke Remove-Item -Times 1 -Exactly -ParameterFilter { $LiteralPath -eq $path } - $env:BCAppsApiTestPasswordPath | Should -BeNullOrEmpty - $env:BCAppsApiTestPasswordContainer | Should -BeNullOrEmpty - } - - It 'does nothing when no credential was provisioned' { - $env:BCAppsApiTestPasswordPath = $null - . $script:finalizer - Should -Invoke docker -Times 0 - Should -Invoke Remove-Item -Times 0 - } - - It 'is idempotent when standard teardown already removed the credential' { - Mock Test-Path { $false } - . $script:finalizer - . $script:finalizer - Should -Invoke docker -Times 0 - Should -Invoke Remove-Item -Times 0 - $env:BCAppsApiTestPasswordPath | Should -BeNullOrEmpty - } - - It 'preserves cleanup identity and propagates a failure without deleting while consumers remain' { - Mock docker { $global:LASTEXITCODE = 1 } -ParameterFilter { $Arguments[0] -eq 'stop' } - { . $script:finalizer } | Should -Throw '*Could not stop API test consumers*' - Should -Invoke Remove-Item -Times 0 - $env:BCAppsApiTestPasswordContainer | Should -Be 'recorded-container' - $env:BCAppsApiTestPasswordPath | Should -Be (Join-Path $TestDrive 'ApiTestPassword') - } - - It 'propagates deletion failure without forgetting the recorded path' { - Mock Remove-Item { throw 'Synthetic deletion failure' } - { . $script:finalizer } | Should -Throw '*Synthetic deletion failure*' - $env:BCAppsApiTestPasswordPath | Should -Be (Join-Path $TestDrive 'ApiTestPassword') - } - - It 'runs every registered project wrapper through the AL-Go scriptblock invocation contract' { - $projects = Join-Path $PSScriptRoot '..\..\projects' - $wrappers = @(Get-ChildItem -LiteralPath $projects -Directory | ForEach-Object { - $setup = Join-Path $_.FullName '.AL-Go\NewBcContainer.ps1' - if ([IO.File]::Exists($setup)) { - Get-Item -LiteralPath (Join-Path $_.FullName '.AL-Go\PipelineFinalize.ps1') - } - }) - $wrappers.Count | Should -BeGreaterThan 0 - foreach ($wrapper in $wrappers) { - $env:BCAppsApiTestPasswordPath = Join-Path $TestDrive 'ApiTestPassword' - $env:BCAppsApiTestPasswordContainer = 'recorded-container' - Invoke-Command -ScriptBlock (Get-Command $wrapper.FullName).ScriptBlock - } - Should -Invoke Remove-Item -Times $wrappers.Count -Exactly - } -} diff --git a/src/Apps/US/IRSForms/test/src/IRS1099APITests.Codeunit.al b/src/Apps/US/IRSForms/test/src/IRS1099APITests.Codeunit.al index 7495ec2d793..8ef0722b292 100644 --- a/src/Apps/US/IRSForms/test/src/IRS1099APITests.Codeunit.al +++ b/src/Apps/US/IRSForms/test/src/IRS1099APITests.Codeunit.al @@ -52,11 +52,13 @@ codeunit 148018 "IRS 1099 API Tests" IRS1099FormDocHeader: Record "IRS 1099 Form Doc. Header"; IRSReportingPeriod: Record "IRS Reporting Period"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IRS1099FormDocHeader.DeleteAll(true); IRSReportingPeriod.DeleteAll(true); LibraryTestInitialize.OnTestInitialize(Codeunit::"IRS 1099 API Tests"); if IsInitialized then exit; + LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"IRS 1099 API Tests"); IsInitialized := true; diff --git a/src/Apps/W1/APIV1/test/src/APIV1AccountsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1AccountsE2E.Codeunit.al index 9e3ef6f5e64..be7c454da6c 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1AccountsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1AccountsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139701 "APIV1 - Accounts E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -19,6 +20,7 @@ codeunit 139701 "APIV1 - Accounts E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1AgedAPE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1AgedAPE2E.Codeunit.al index 9c057dab240..973aeaaaf12 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1AgedAPE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1AgedAPE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139719 "APIV1 - Aged AP E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -60,6 +61,7 @@ codeunit 139719 "APIV1 - Aged AP E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1AgedARE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1AgedARE2E.Codeunit.al index afdb729791c..ce212da59c5 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1AgedARE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1AgedARE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139720 "APIV1 - Aged AR E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -60,6 +61,7 @@ codeunit 139720 "APIV1 - Aged AR E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1AttachmentsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1AttachmentsE2E.Codeunit.al index 5e03d6caccc..f4464adcbc6 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1AttachmentsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1AttachmentsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139733 "APIV1 - Attachments E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -43,6 +44,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve all records from the Attachments API. + Initialize(); + // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateGenJournalLine(DocumentRecordRef); CreateAttachments(DocumentRecordRef, AttachmentId); @@ -65,6 +68,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve all records from the Attachments API. + Initialize(); + // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateGLEntry(DocumentRecordRef); CreateAttachments(DocumentRecordRef, AttachmentId); @@ -88,6 +93,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve all records from the Attachments API. + Initialize(); + // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); CreateAttachments(DocumentRecordRef, AttachmentId); @@ -110,6 +117,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve all records from the Attachments API. + Initialize(); + // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateDraftSalesInvoice(DocumentRecordRef); CreateAttachments(DocumentRecordRef, AttachmentId); @@ -133,6 +142,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve all records from the Attachments API. + Initialize(); + // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreatePostedPurchaseInvoice(DocumentRecordRef, DocumentId); CreateAttachments(DocumentRecordRef, AttachmentId); @@ -155,6 +166,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve all records from the Attachments API. + Initialize(); + // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateDraftPurchaseInvoice(DocumentRecordRef); CreateAttachments(DocumentRecordRef, AttachmentId); @@ -177,6 +190,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve all records from the Attachments API. + Initialize(); + // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateSalesQuote(DocumentRecordRef); CreateAttachments(DocumentRecordRef, AttachmentId); @@ -199,6 +214,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve the Attachment record from the Attachment API. + Initialize(); + // [GIVEN] Attachment exists in the Incoming Document Attachment table CreateGenJournalLine(DocumentRecordRef); AttachmentId := CreateAttachment(DocumentRecordRef); @@ -224,6 +241,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve the Attachment record from the Attachment API. + Initialize(); + // [GIVEN] Attachment exists in the Incoming Document Attachment table JournalName := LibraryUtility.GenerateRandomCode(GenJournalBatch.FieldNo(Name), Database::"Gen. Journal Batch"); LibraryAPIGeneralJournal.EnsureGenJnlBatchExists(GraphMgtJournal.GetDefaultJournalLinesTemplateName(), JournalName); @@ -249,6 +268,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve the Attachment record from the Attachment API. + Initialize(); + // [GIVEN] Attachment exists in the Incoming Document Attachment table CreateGLEntry(DocumentRecordRef); AttachmentId := CreateAttachment(DocumentRecordRef); @@ -273,6 +294,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve the Attachment record from the Attachment API. + Initialize(); + // [GIVEN] Attachment exists in the Incoming Document Attachment table CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); AttachmentId := CreateAttachment(DocumentRecordRef); @@ -296,6 +319,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve the Attachment record from the Attachment API. + Initialize(); + // [GIVEN] Attachment exists in the Incoming Document Attachment table CreateDraftSalesInvoice(DocumentRecordRef); AttachmentId := CreateAttachment(DocumentRecordRef); @@ -319,6 +344,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] User can retrieve the Attachment record from the Attachment API. + Initialize(); + // [GIVEN] Attachment exists in the Incoming Document Attachment table CreateSalesQuote(DocumentRecordRef); AttachmentId := CreateAttachment(DocumentRecordRef); @@ -346,6 +373,8 @@ codeunit 139733 "APIV1 - Attachments E2E" ActualBase64Content: Text; begin // [SCENARIO] User can update linked attachment binary content through the Attachment API. + Initialize(); + // [GIVEN] A linked attachment exists CreateGenJournalLine(DocumentRecordRef); AttachmentId := CreateAttachment(DocumentRecordRef); @@ -380,6 +409,8 @@ codeunit 139733 "APIV1 - Attachments E2E" ActualBase64Content: Text; begin // [SCENARIO] User can update linked attachment binary content through the Attachment API. + Initialize(); + // [GIVEN] A linked attachment exists CreateGLEntry(DocumentRecordRef); AttachmentId := CreateAttachment(DocumentRecordRef); @@ -407,6 +438,8 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateGenJournalLine(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -416,6 +449,8 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateGLEntry(DocumentRecordRef); TestCreateGLEAttachment(DocumentRecordRef); end; @@ -426,6 +461,8 @@ codeunit 139733 "APIV1 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); TestCreateAttachment(DocumentRecordRef, DocumentId); end; @@ -435,6 +472,8 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftSalesInvoice(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -445,6 +484,8 @@ codeunit 139733 "APIV1 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedPurchaseInvoice(DocumentRecordRef, DocumentId); TestCreateAttachment(DocumentRecordRef, DocumentId); end; @@ -454,10 +495,17 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseInvoice(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; + local procedure TestCreateAttachment(var DocumentRecordRef: RecordRef) var DocumentId: Guid; @@ -555,6 +603,8 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateSalesQuote(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -564,6 +614,8 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateGenJournalLine(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -573,6 +625,8 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateGLEntry(DocumentRecordRef); TestDeleteGLEAttachment(DocumentRecordRef); end; @@ -583,6 +637,8 @@ codeunit 139733 "APIV1 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); TestDeleteAttachment(DocumentRecordRef, DocumentId); end; @@ -592,6 +648,8 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftSalesInvoice(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -602,6 +660,8 @@ codeunit 139733 "APIV1 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedPurchaseInvoice(DocumentRecordRef, DocumentId); TestDeleteAttachment(DocumentRecordRef, DocumentId); end; @@ -611,6 +671,8 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseInvoice(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -620,6 +682,8 @@ codeunit 139733 "APIV1 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateSalesQuote(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -697,6 +761,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] The Attachment is transferred from a Draft Invoice the to Posted Invoice after posting. + Initialize(); + // [GIVEN] A draft sales invoice exists. CreateDraftSalesInvoice(DocumentRecordRef); DocumentId := GetDocumentId(DocumentRecordRef); @@ -737,6 +803,8 @@ codeunit 139733 "APIV1 - Attachments E2E" TargetURL: Text; begin // [SCENARIO] The Attachment is transferred from a Draft Invoice the to Posted Invoice after posting. + Initialize(); + // [GIVEN] A draft sales invoice exists. CreateDraftPurchaseInvoice(DocumentRecordRef); DocumentId := GetDocumentId(DocumentRecordRef); @@ -779,6 +847,8 @@ codeunit 139733 "APIV1 - Attachments E2E" NewBase64Content: Text; begin // [SCENARIO] Changing an attachment file name keeps other fields unchanged + Initialize(); + // [GIVEN] A sales quote exists. CreateSalesQuote(DocumentRecordRef); DocumentId := GetDocumentId(DocumentRecordRef); @@ -824,6 +894,8 @@ codeunit 139733 "APIV1 - Attachments E2E" NewFileName: Text; begin // [SCENARIO] Changing an attachment content keeps other fields unchanged + Initialize(); + // [GIVEN] A draft sales invoice exists. CreateDraftSalesInvoice(DocumentRecordRef); DocumentId := GetDocumentId(DocumentRecordRef); @@ -862,6 +934,8 @@ codeunit 139733 "APIV1 - Attachments E2E" JSONBody: Text; begin // [SCENARIO] User cannot change the linked attachment ID by making a PATCH request to the Attachments API + Initialize(); + // [GIVEN] A sales quote exists. CreateSalesQuote(DocumentRecordRef); @@ -891,6 +965,8 @@ codeunit 139733 "APIV1 - Attachments E2E" JSONBody: Text; begin // [SCENARIO] User cannot change the attachment ID by making a PATCH request to the Attachments API + Initialize(); + // [GIVEN] Two documents exist. CreateSalesQuote(DocumentRecordRef[1]); CreateDraftSalesInvoice(DocumentRecordRef[2]); diff --git a/src/Apps/W1/APIV1/test/src/APIV1AutomationRSPackage.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1AutomationRSPackage.Codeunit.al index fba368ca1dc..f6154834cc2 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1AutomationRSPackage.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1AutomationRSPackage.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139731 "APIV1 - Automation RS Package" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -16,7 +17,6 @@ codeunit 139731 "APIV1 - Automation RS Package" LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryUtility: Codeunit "Library - Utility"; Assert: Codeunit "Assert"; - IsInitialized: Boolean; SamplePackageFile: Text; PackageCodeTxt: Label 'code', Locked = true; ActionImportTxt: Label 'Microsoft.NAV.import'; @@ -29,13 +29,10 @@ codeunit 139731 "APIV1 - Automation RS Package" var TenantConfigPackageFile: Record "Tenant Config. Package File"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); TenantConfigPackageFile.DELETEALL(TRUE); - IF IsInitialized THEN - EXIT; - SamplePackageFile := GenerateSamplePackageFile(); - IsInitialized := TRUE; end; [Test] @@ -142,11 +139,12 @@ codeunit 139731 "APIV1 - Automation RS Package" StartTime := CURRENTDATETIME(); REPEAT + SelectLatestVersion(); ConfigPackage.FIND(); UNTIL (NOT IsImportPending(ConfigPackage)) OR (CURRENTDATETIME() - StartTime > 180000); - Assert.AreEqual(ConfigPackage."Import Status", ConfigPackage."Import Status"::Completed, 'Import Status should be completed.'); + Assert.AreEqual(ConfigPackage."Import Status"::Completed, ConfigPackage."Import Status", 'Import Status should be completed.'); // clean up after the test LibraryRapidStart.CleanUp(ConfigPackage.Code); @@ -190,11 +188,12 @@ codeunit 139731 "APIV1 - Automation RS Package" StartTime := CURRENTDATETIME(); REPEAT + SelectLatestVersion(); ConfigPackage.FIND(); UNTIL (NOT IsImportPending(ConfigPackage)) OR (CURRENTDATETIME() - StartTime > 180000); - Assert.AreEqual(ConfigPackage."Import Status", ConfigPackage."Import Status"::Error, 'Import Status should be error.'); + Assert.AreEqual(ConfigPackage."Import Status"::Error, ConfigPackage."Import Status", 'Import Status should be error.'); // clean up after the test LibraryRapidStart.CleanUp(ConfigPackage.Code); @@ -240,11 +239,12 @@ codeunit 139731 "APIV1 - Automation RS Package" StartTime := CURRENTDATETIME(); REPEAT + SelectLatestVersion(); ConfigPackage.FIND(); UNTIL (NOT IsApplyPending(ConfigPackage)) OR (CURRENTDATETIME() - StartTime > 180000); - Assert.AreEqual(ConfigPackage."Apply Status", ConfigPackage."Apply Status"::Completed, 'Apply Status should be completed.'); + Assert.AreEqual(ConfigPackage."Apply Status"::Completed, ConfigPackage."Apply Status", 'Apply Status should be completed.'); Assert.AreEqual(0, ConfigPackage."No. of Errors", 'There should be no errors.'); // clean up after the test @@ -328,7 +328,7 @@ codeunit 139731 "APIV1 - Automation RS Package" local procedure IsApplyPending(var ConfigPackage: Record "Config. Package"): Boolean begin - EXIT(ConfigPackage."Apply Status" IN [ConfigPackage."Import Status"::Scheduled, ConfigPackage."Apply Status"::InProgress]); + EXIT(ConfigPackage."Apply Status" IN [ConfigPackage."Apply Status"::Scheduled, ConfigPackage."Apply Status"::InProgress]); end; local procedure CreateTestPackage(var ConfigPackage: Record "Config. Package") diff --git a/src/Apps/W1/APIV1/test/src/APIV1BalanceSheetE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1BalanceSheetE2E.Codeunit.al index 9f700458c0e..ed78e39bcb8 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1BalanceSheetE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1BalanceSheetE2E.Codeunit.al @@ -62,6 +62,7 @@ codeunit 139715 "APIV1 - Balance Sheet E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1CashFlowStatementE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1CashFlowStatementE2E.Codeunit.al index 2478bfb256f..b1abc96bb41 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1CashFlowStatementE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1CashFlowStatementE2E.Codeunit.al @@ -62,6 +62,7 @@ codeunit 139717 "APIV1 - CashFlow Statement E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1CompanyInfoE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1CompanyInfoE2E.Codeunit.al index 6b3b4e66322..867b0763f84 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1CompanyInfoE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1CompanyInfoE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139706 "APIV1 - Company Info. E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = IntegrationTest; TestPermissions = Disabled; @@ -22,6 +23,7 @@ codeunit 139706 "APIV1 - Company Info. E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1CurrenciesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1CurrenciesE2E.Codeunit.al index 5105b4c44bb..f69f74fee65 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1CurrenciesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1CurrenciesE2E.Codeunit.al @@ -155,6 +155,7 @@ codeunit 139713 "APIV1 - Currencies E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1CustomerPaymentsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1CustomerPaymentsE2E.Codeunit.al index 13e55ac2bb6..79d8b3eb1f6 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1CustomerPaymentsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1CustomerPaymentsE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139743 "APIV1 - Customer Payments E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -769,10 +770,12 @@ codeunit 139743 "APIV1 - Customer Payments E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryTestInitialize.OnTestInitialize(Codeunit::"APIV1 - Customer Payments E2E"); - if not isInitialized then + if not isInitialized then begin isInitialized := true; + end; LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"APIV1 - Customer Payments E2E"); end; diff --git a/src/Apps/W1/APIV1/test/src/APIV1CustomersE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1CustomersE2E.Codeunit.al index be1fe579b35..55cf565b43d 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1CustomersE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1CustomersE2E.Codeunit.al @@ -34,6 +34,7 @@ codeunit 139702 "APIV1 - Customers E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1DefaultDimensionsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1DefaultDimensionsE2E.Codeunit.al index 96621497106..491b8ea5b8a 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1DefaultDimensionsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1DefaultDimensionsE2E.Codeunit.al @@ -37,6 +37,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the customer // [THEN] The default dimension has been added to the customer @@ -50,6 +52,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the vendor // [THEN] The default dimension has been added to the vendor @@ -63,6 +67,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Item // [THEN] The default dimension has been added to the Item @@ -89,6 +95,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the customer // [THEN] The default dimension has been added to the customer @@ -102,6 +110,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a Vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Vendor // [THEN] The default dimension has been added to the Vendor @@ -115,6 +125,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Item // [THEN] The default dimension has been added to the Item @@ -141,6 +153,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer, a dimension and a dimension value // [WHEN] a user issues a http request to create a default dimension without dimension id // [THEN] You get an error @@ -154,6 +168,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a Vendor, a dimension and a dimension value // [WHEN] a user issues a http request to create a default dimension without dimension id // [THEN] You get an error @@ -167,6 +183,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item, a dimension and a dimension value // [WHEN] a user issues a http request to create a default dimension without dimension id // [THEN] You get an error @@ -193,6 +211,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the customer, with mismatching dimesnion and dimension value // [THEN] You get an error @@ -206,6 +226,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a Vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Vendor, with mismatching dimesnion and dimension value // [THEN] You get an error @@ -219,6 +241,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Item, with mismatching dimesnion and dimension value // [THEN] You get an error @@ -245,6 +269,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension on the customer // [THEN] You get an error @@ -258,6 +284,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a Vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension on the Vendor // [THEN] You get an error @@ -271,6 +299,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension on the Item // [THEN] You get an error @@ -297,6 +327,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension value on the customer // [THEN] You get an error @@ -310,6 +342,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a Vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension value on the Vendor // [THEN] You get an error @@ -323,6 +357,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension value on the Item // [THEN] You get an error @@ -349,6 +385,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to delete the default dimension on the customer // [THEN] The default dimension has been deleted from the customer's default dimensions @@ -362,6 +400,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a Vendor with a default dimension // [WHEN] The user posts a http request to delete a default dimension on the Vendor // [THEN] The default dimension has been deleted from the vendor's default dimensions @@ -375,6 +415,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item with a default dimension // [WHEN] The user posts a http request to delete a default dimension on the Item // [THEN] The default dimension has been deleted from the item's default dimensions @@ -401,6 +443,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to get the default dimension on the customer // [THEN] The response contains the default dimension that has been added to the customer @@ -414,6 +458,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a Vendor with a default dimension // [WHEN] The user posts a http request to get a default dimension on the Vendor // [THEN] The response contains the default dimension that has been added to the Vendor @@ -427,6 +473,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item with a default dimension // [WHEN] The user posts a http request to get a default dimension on the Item // [THEN] The response contains the default dimension that has been added to the Item @@ -453,6 +501,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to patch the default dimension on the customer // [THEN] The default dimension has been updated for the customer @@ -466,6 +516,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a Vendor with a default dimension // [WHEN] The user posts a http request to patch a default dimension on the Vendor // [THEN] The default dimension has been updated for the vendor @@ -479,6 +531,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item with a default dimension // [WHEN] The user posts a http request to patch a default dimension on the Item // [THEN] The default dimension has been updated for the item @@ -505,6 +559,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to patch the default dimension with a blocked dimension value on the customer // [THEN] You get an error @@ -518,6 +574,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a Vendor with a default dimension // [WHEN] The user posts a http request to patch a default dimension with a blocked dimension value on the Vendor // [THEN] You get an error @@ -531,6 +589,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a Item with a default dimension // [WHEN] The user posts a http request to patch a default dimension with a blocked dimension value on the Item // [THEN] You get an error @@ -557,6 +617,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Customer: Record "Customer"; begin // [FEATURE] [Customer] + Initialize(); + // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to patch the default dimension with a blocked dimension value on the customer // [THEN] You get an error @@ -570,6 +632,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Vendor: Record "Vendor"; begin // [FEATURE] [Vendor] + Initialize(); + // [GIVEN] a vendor with a default dimension // [WHEN] The user posts a http request to patch the default dimension with a blocked dimension value on the vendor // [THEN] You get an error @@ -583,6 +647,8 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" Item: Record "Item"; begin // [FEATURE] [Item] + Initialize(); + // [GIVEN] a item with a default dimension // [WHEN] The user posts a http request to patch the default dimension with a blocked dimension value on the item // [THEN] You get an error @@ -603,6 +669,11 @@ codeunit 139732 "APIV1 - Default Dimensions E2E" TestPatchDefaultDimensionFailsWhenChangingDimensionCode(DATABASE::Employee, Employee."No.", Employee.SystemId); end; + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; + local procedure TestCreateDefaultDimensionWithDimensionCode(TableNo: Integer; ParentNo: Code[20]; ParentId: Guid) var Dimension: Record "Dimension"; diff --git a/src/Apps/W1/APIV1/test/src/APIV1DimensionLinesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1DimensionLinesE2E.Codeunit.al index a0f0993cf2a..a4a72c5bcde 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1DimensionLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1DimensionLinesE2E.Codeunit.al @@ -28,6 +28,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); end; [Test] @@ -44,6 +45,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" ResponseText: Text; begin // [SCENARIO] Create a dimension line in a customer payment through a POST method and check if it was created + Initialize(); LibraryGraphJournalLines.Initialize(); // [GIVEN] a journal @@ -88,6 +90,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" ResponseText: Text; begin // [SCENARIO] Creating a dimension line through a POST method without specifying a parent Id fails + Initialize(); LibraryGraphJournalLines.Initialize(); // [GIVEN] a dimension with a value @@ -119,6 +122,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" TargetURL: Text; begin // [SCENARIO] Try to create a dimension line with an already existing code + Initialize(); LibraryGraphJournalLines.Initialize(); // [GIVEN] a journal @@ -171,6 +175,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" TargetURL: Text; begin // [SCENARIO] Create dimension lines in a journal line and use a GET method to retrieve them + Initialize(); LibraryGraphJournalLines.Initialize(); // [GIVEN] a journal @@ -227,6 +232,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" TargetURL: Text; begin // [SCENARIO] Create dimension lines in a journal line and use a GET method to retrieve them + Initialize(); // [GIVEN] a customer payment in the General Journal Table LibraryGraphJournalLines.Initialize(); @@ -276,6 +282,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" TargetURL: Text; begin // [SCENARIO] Using a GET request to retrieve dimension lines without a filter fails + Initialize(); LibraryGraphJournalLines.Initialize(); AccountNo := LibraryGraphJournalLines.CreateAccount(); @@ -296,6 +303,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" TargetURL: Text; begin // [SCENARIO] Using a GET request to retrieve dimension lines with a random entity fails + Initialize(); LibraryGraphJournalLines.Initialize(); // [GIVEN] a Target URL without filters @@ -323,6 +331,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" TargetURL: Text; begin // [SCENARIO] Create a dimension line, use a PATCH method to change it and then verify the changes + Initialize(); LibraryGraphJournalLines.Initialize(); // [GIVEN] a journal @@ -386,6 +395,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" TargetURL: Text; begin // [SCENARIO] Try to change the code of an existing dimension line + Initialize(); LibraryGraphJournalLines.Initialize(); // [GIVEN] a journal @@ -444,6 +454,7 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" TargetURL: Text; begin // [SCENARIO] Create a dimension line, use a DELETE method to remove it and then verify the deletion + Initialize(); LibraryGraphJournalLines.Initialize(); // [GIVEN] a journal @@ -602,6 +613,5 @@ codeunit 139725 "APIV1 - Dimension Lines E2E" - diff --git a/src/Apps/W1/APIV1/test/src/APIV1DimensionsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1DimensionsE2E.Codeunit.al index f1aafb40161..78a25bb1b80 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1DimensionsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1DimensionsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139724 "APIV1 - Dimensions E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -20,6 +21,7 @@ codeunit 139724 "APIV1 - Dimensions E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1EmployeesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1EmployeesE2E.Codeunit.al index c2d3a8700fb..5da3e1d4573 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1EmployeesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1EmployeesE2E.Codeunit.al @@ -25,6 +25,7 @@ codeunit 139722 "APIV1 - Employees E2E" var LibraryApplicationArea: Codeunit "Library - Application Area"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryApplicationArea.EnableBasicHRSetup(); // Lazy Setup. diff --git a/src/Apps/W1/APIV1/test/src/APIV1GLEntriesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1GLEntriesE2E.Codeunit.al index f405f7a3ad5..a57191b4562 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1GLEntriesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1GLEntriesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139730 "APIV1 - GLEntries E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -14,9 +15,9 @@ codeunit 139730 "APIV1 - GLEntries E2E" var Assert: Codeunit "Assert"; LibraryERM: Codeunit "Library - ERM"; - LibraryVariableStorage: Codeunit "Library - Variable Storage"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; IsInitialized: Boolean; + JournalTemplateName: Code[10]; ServiceNameTxt: Label 'generalLedgerEntries'; local procedure Initialize() @@ -24,6 +25,7 @@ codeunit 139730 "APIV1 - GLEntries E2E" LibraryERMCountryData: Codeunit "Library - ERM Country Data"; LibraryApplicationArea: Codeunit "Library - Application Area"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryApplicationArea.EnableFoundationSetup(); IF IsInitialized THEN EXIT; @@ -89,7 +91,7 @@ codeunit 139730 "APIV1 - GLEntries E2E" CreateGeneralJournalBatch(GenJournalBatch); // Create General Journal Line. - LibraryVariableStorage.Enqueue(GenJournalBatch."Journal Template Name"); + JournalTemplateName := GenJournalBatch."Journal Template Name"; GeneralJournal.TRAP(); GeneralJournal.OPENEDIT(); GeneralJournal."Account Type".SETVALUE(GenJournalLine."Account Type"::"G/L Account"); @@ -119,7 +121,6 @@ codeunit 139730 "APIV1 - GLEntries E2E" local procedure UpdateAmountOnGenJournalLine(GenJournalBatch: Record "Gen. Journal Batch"; var GeneralJournal: TestPage "General Journal") begin - LibraryVariableStorage.Enqueue(GenJournalBatch."Journal Template Name"); LibraryERM.UpdateAmountOnGenJournalLine(GenJournalBatch, GeneralJournal); end; @@ -145,7 +146,7 @@ codeunit 139730 "APIV1 - GLEntries E2E" [ModalPageHandler] procedure GeneralJournalTemplateHandler(var GeneralJournalTemplateList: TestPage 250) begin - GeneralJournalTemplateList.FILTER.SETFILTER(Name, LibraryVariableStorage.DequeueText()); + GeneralJournalTemplateList.FILTER.SETFILTER(Name, JournalTemplateName); GeneralJournalTemplateList.OK().INVOKE(); end; } @@ -163,4 +164,3 @@ codeunit 139730 "APIV1 - GLEntries E2E" - diff --git a/src/Apps/W1/APIV1/test/src/APIV1IncomeStatementE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1IncomeStatementE2E.Codeunit.al index a49c2db7b8b..8063d4e2e8f 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1IncomeStatementE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1IncomeStatementE2E.Codeunit.al @@ -62,6 +62,7 @@ codeunit 139716 "APIV1 - Income Statement E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1ItemCategoriesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1ItemCategoriesE2E.Codeunit.al index 9035d86b098..ca8aed25a9a 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1ItemCategoriesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1ItemCategoriesE2E.Codeunit.al @@ -155,6 +155,7 @@ codeunit 139707 "APIV1 - Item Categories E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1ItemVariantsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1ItemVariantsE2E.Codeunit.al index 7d404f44ee1..18dd7ce22f2 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1ItemVariantsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1ItemVariantsE2E.Codeunit.al @@ -22,6 +22,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Create an item variant through a POST method and check if it was created + Initialize(); + // [GIVEN] a JSON text with an item variant with itemId CreateItem(Item); Commit(); @@ -46,6 +48,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Cannot create an Item Variant with non-existing itemId + Initialize(); + // [GIVEN] a JSON text with an item variant with non-existing itemId ItemId := CreateGuid(); ItemVariantJSON := CreateItemVariantJsonWithItemId(ItemId, ItemVariantCode); @@ -67,6 +71,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Create an item variant through a POST method and check if it was created + Initialize(); + // [GIVEN] a JSON text with an item variant with itemNumber CreateItem(Item); Commit(); @@ -92,6 +98,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Cannot create an Item Variant with non-existing itemNumber + Initialize(); + // [GIVEN] a JSON text with an item variant with non-existing itemNumber ItemNo := LibraryUtility.GenerateRandomCode(ItemVariant.FieldNo(Code), Database::"Item Variant"); ItemVariantJSON := CreateItemVariantJsonWithItemNo(ItemNo, ItemVariantCode); @@ -113,6 +121,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Create an item variant through a POST method and check if it was created + Initialize(); + // [GIVEN] a JSON text with an item variant with itemNumber and itemId CreateItem(Item); Commit(); @@ -138,6 +148,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Cannot create an Item Variant with mismatching itemNumber and itemId + Initialize(); + // [GIVEN] a JSON text with an item variant with mismatching itemNumber and itemId CreateItem(Item1); CreateItem(Item2); @@ -161,6 +173,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Cannot create an Item Variant if there is an item variant with same itemNumber and code + Initialize(); + // [GIVEN] a JSON text with an item variant with same itemNumber and code CreateItem(Item); LibraryInventory.CreateItemVariant(ItemVariant, Item."No."); @@ -183,6 +197,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Get a simple customer with a GET request to the service. + Initialize(); + // [GIVEN] An item variant exists in the system CreateItem(Item); LibraryInventory.CreateItemVariant(ItemVariant, Item."No."); @@ -208,6 +224,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Create an item variant, use a PATCH method to change it and then verify the changes + Initialize(); + // [GIVEN] an item variant exists in the system CreateItem(Item); LibraryInventory.CreateItemVariant(ItemVariant, Item."No."); @@ -240,6 +258,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Create an item variant, use a PATCH method to change it and then verify the changes + Initialize(); + // [GIVEN] an item variant exists in the system CreateItem(Item1); CreateItem(Item2); @@ -273,6 +293,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Create an item variant, use a PATCH method to change it and then verify the changes + Initialize(); + // [GIVEN] an item variant exists in the system CreateItem(Item1); CreateItem(Item2); @@ -302,6 +324,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Create an item variant, use a DELETE method to remove it and then verify the deletion + Initialize(); + // [GIVEN] an item variant in the system CreateItem(Item); LibraryInventory.CreateItemVariant(ItemVariant, Item."No."); @@ -328,6 +352,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" TargetURL: Text; begin // [SCENARIO] Cannot delete an item variant in use + Initialize(); + // [GIVEN] an item variant in the system and used in a sales order line LibraryInventory.CreateItem(Item); LibraryInventory.CreateItemVariant(ItemVariant, Item."No."); @@ -343,6 +369,7 @@ codeunit 139739 "APIV1 - Item Variants E2E" var LibraryGraphMgt: Codeunit "Library - Graph Mgt"; + LibraryGraphDocumentTools: Codeunit "Library - Graph Document Tools"; LibraryUtility: Codeunit "Library - Utility"; LibraryRandom: Codeunit "Library - Random"; LibraryInventory: Codeunit "Library - Inventory"; @@ -350,6 +377,11 @@ codeunit 139739 "APIV1 - Item Variants E2E" ServiceNameTxt: Label 'itemVariants'; + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; + local procedure CreateItem(var Item: Record Item) begin Item.Init(); @@ -426,6 +458,8 @@ codeunit 139739 "APIV1 - Item Variants E2E" LibrarySales: Codeunit "Library - Sales"; begin LibrarySales.CreateSalesOrder(SalesHeader); + LibraryGraphDocumentTools.EnsureVATPostingSetupExists( + SalesHeader."VAT Bus. Posting Group", Item."VAT Prod. Posting Group"); LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item."No.", 2); SalesLine."Variant Code" := ItemVariant.Code; SalesLine.Modify(); diff --git a/src/Apps/W1/APIV1/test/src/APIV1ItemsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1ItemsE2E.Codeunit.al index 4cddfa7b2ec..f392568fb65 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1ItemsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1ItemsE2E.Codeunit.al @@ -33,6 +33,7 @@ codeunit 139700 "APIV1 - Items E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1JournalLinesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1JournalLinesE2E.Codeunit.al index c528b4c662a..0a4b199ce18 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1JournalLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1JournalLinesE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139745 "APIV1 - Journal Lines E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestType = IntegrationTest; TestPermissions = Disabled; @@ -14,8 +15,10 @@ codeunit 139745 "APIV1 - Journal Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); if IsInitialized then exit; + IsInitialized := true; Commit(); end; diff --git a/src/Apps/W1/APIV1/test/src/APIV1JournalsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1JournalsE2E.Codeunit.al index 6aab2759557..a27175641b4 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1JournalsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1JournalsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139727 "APIV1 - Journals E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -32,6 +33,7 @@ codeunit 139727 "APIV1 - Journals E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; @@ -190,6 +192,8 @@ codeunit 139727 "APIV1 - Journals E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [GIVEN] A general journal batch with a general journal line BalAccountNo := LibraryERM.CreateGLAccountNoWithDirectPosting(); BalAccountType := GenJournalLine."Bal. Account Type"::"G/L Account"; diff --git a/src/Apps/W1/APIV1/test/src/APIV1PDFDocumentE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1PDFDocumentE2E.Codeunit.al index 3f795d60e48..e7f4de5ce03 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1PDFDocumentE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1PDFDocumentE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139744 "APIV1 - PDF Document E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -24,7 +25,7 @@ codeunit 139744 "APIV1 - PDF Document E2E" var CompanyInformation: Record "Company Information"; begin - WorkDate := Today; + LibraryGraphMgt.SetLicenseSafeWorkDate(); CompanyInformation.Get(); if CompanyInformation."Giro No." = '' then @@ -279,4 +280,3 @@ codeunit 139744 "APIV1 - PDF Document E2E" Commit(); end; } - diff --git a/src/Apps/W1/APIV1/test/src/APIV1PaymentTermsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1PaymentTermsE2E.Codeunit.al index 5c39f3bd02a..5acfb554143 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1PaymentTermsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1PaymentTermsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139704 "APIV1 - Payment Terms E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -19,6 +20,7 @@ codeunit 139704 "APIV1 - Payment Terms E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1PicturesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1PicturesE2E.Codeunit.al index 3913b1537e6..7952bbda924 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1PicturesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1PicturesE2E.Codeunit.al @@ -28,6 +28,7 @@ codeunit 139742 "APIV1 - Pictures E2E" [Scope('OnPrem')] procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); if IsInitialized then exit; @@ -46,6 +47,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Customer] // [SCENARIO] Get value picture from Customer Record + Initialize(); + // [GIVEN] a customer with image attached CreateTestCustomerWithImage(Customer, TempBlobExpected); Commit(); @@ -70,6 +73,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Customer] // [SCENARIO] Get a picture metadata from Customer Record + Initialize(); + // [GIVEN] a customer with image attached CreateTestCustomerWithImage(Customer, TempBlobExpected); Commit(); @@ -93,6 +98,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Customer] // [SCENARIO] Get value picture from Customer Record when no image exist + Initialize(); + // [GIVEN] a customer without image LibrarySales.CreateCustomer(Customer); Commit(); @@ -114,6 +121,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Customer] // [SCENARIO] Get a picture metadata from Customer Record when no image is present + Initialize(); + // [GIVEN] a customer with image attached LibrarySales.CreateCustomer(Customer); Commit(); @@ -139,6 +148,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Customer] // [SCENARIO] Set Picture on a customer without picture + Initialize(); + // [GIVEN] a customer with image attached LibrarySales.CreateCustomer(Customer); GetRedImageTempBlob(TempBlobExpected); @@ -171,6 +182,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Customer] // [SCENARIO] Replace the Picture on a customer + Initialize(); + // [GIVEN] a customer with image attached CreateTestCustomerWithImage(Customer, TempBlobOriginal); GetBlueImageTempBlob(TempBlobExpected); @@ -202,6 +215,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Customer] // [SCENARIO] Replace the Picture on a customer + Initialize(); + // [GIVEN] a customer with image attached CreateTestCustomerWithImage(Customer, TempBlobOriginal); GetBlueImageTempBlob(TempBlobExpected); @@ -229,6 +244,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Vendor] // [SCENARIO] Get value picture from Vendor Record + Initialize(); + // [GIVEN] a Vendor with image attached CreateTestVendorWithImage(Vendor, TempBlobExpected); Commit(); @@ -253,6 +270,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Vendor] // [SCENARIO] Get a picture metadata from Vendor Record + Initialize(); + // [GIVEN] a Vendor with image attached CreateTestVendorWithImage(Vendor, TempBlobExpected); Commit(); @@ -276,6 +295,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Vendor] // [SCENARIO] Get value picture from Vendor Record when no image exist + Initialize(); + // [GIVEN] a Vendor without image LibraryPurchase.CreateVendor(Vendor); Commit(); @@ -297,6 +318,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Vendor] // [SCENARIO] Get a picture metadata from Vendor Record when no image is present + Initialize(); + // [GIVEN] a Vendor with image attached LibraryPurchase.CreateVendor(Vendor); Commit(); @@ -322,6 +345,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Vendor] // [SCENARIO] Set Picture on a Vendor without picture + Initialize(); + // [GIVEN] a Vendor with image attached LibraryPurchase.CreateVendor(Vendor); GetRedImageTempBlob(TempBlobExpected); @@ -354,6 +379,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Vendor] // [SCENARIO] Replace the Picture on a Vendor + Initialize(); + // [GIVEN] a Vendor with image attached CreateTestVendorWithImage(Vendor, TempBlobOriginal); GetBlueImageTempBlob(TempBlobExpected); @@ -385,6 +412,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Vendor] // [SCENARIO] Replace the Picture on a Vendor + Initialize(); + // [GIVEN] a Vendor with image attached CreateTestVendorWithImage(Vendor, TempBlobOriginal); GetBlueImageTempBlob(TempBlobExpected); @@ -412,6 +441,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Employee] // [SCENARIO] Get value picture from Employee Record + Initialize(); + // [GIVEN] an Employee with image attached CreateTestEmployeeWithImage(Employee, TempBlobExpected); Commit(); @@ -436,6 +467,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Employee] // [SCENARIO] Get a picture metadata from Employee Record + Initialize(); + // [GIVEN] a Employee with image attached CreateTestEmployeeWithImage(Employee, TempBlobExpected); Commit(); @@ -459,6 +492,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Employee] // [SCENARIO] Get value picture from Employee Record when no image exist + Initialize(); + // [GIVEN] a Employee without image LibraryHumanResource.CreateEmployee(Employee); Commit(); @@ -480,6 +515,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Employee] // [SCENARIO] Get a picture metadata from Employee Record when no image is present + Initialize(); + // [GIVEN] a Employee with image attached LibraryHumanResource.CreateEmployee(Employee); Commit(); @@ -505,6 +542,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Employee] // [SCENARIO] Set Picture on a Employee without picture + Initialize(); + // [GIVEN] a Employee with image attached LibraryHumanResource.CreateEmployee(Employee); GetRedImageTempBlob(TempBlobExpected); @@ -537,6 +576,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Employee] // [SCENARIO] Replace the Picture on a Employee + Initialize(); + // [GIVEN] a Employee with image attached CreateTestEmployeeWithImage(Employee, TempBlobOriginal); GetBlueImageTempBlob(TempBlobExpected); @@ -568,6 +609,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Employee] // [SCENARIO] Replace the Picture on a Employee + Initialize(); + // [GIVEN] a Employee with image attached CreateTestEmployeeWithImage(Employee, TempBlobOriginal); GetBlueImageTempBlob(TempBlobExpected); @@ -595,6 +638,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Item] // [SCENARIO] Get value picture from Item Record + Initialize(); + // [GIVEN] a Item with image attached CreateTestItemWithImage(Item, TempBlobExpected); Commit(); @@ -619,6 +664,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Item] // [SCENARIO] Get a picture metadata from Item Record + Initialize(); + // [GIVEN] a Item with image attached CreateTestItemWithImage(Item, TempBlobExpected); Commit(); @@ -642,6 +689,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Item] // [SCENARIO] Get value picture from Item Record when no image exist + Initialize(); + // [GIVEN] a Item without image LibraryInventory.CreateItem(Item); Commit(); @@ -663,6 +712,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Item] // [SCENARIO] Get a picture metadata from Item Record when no image is present + Initialize(); + // [GIVEN] a Item with image attached LibraryInventory.CreateItem(Item); Commit(); @@ -688,6 +739,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Item] // [SCENARIO] Set Picture on a Item without picture + Initialize(); + // [GIVEN] a Item with image attached LibraryInventory.CreateItem(Item); GetRedImageTempBlob(TempBlobExpected); @@ -720,6 +773,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Item] // [SCENARIO] Replace the Picture on a Item + Initialize(); + // [GIVEN] a Item with image attached CreateTestItemWithImage(Item, TempBlobOriginal); GetBlueImageTempBlob(TempBlobExpected); @@ -751,6 +806,8 @@ codeunit 139742 "APIV1 - Pictures E2E" // [FEATURE] [Item] // [SCENARIO] Replace the Picture on a Item + Initialize(); + // [GIVEN] a Item with image attached CreateTestItemWithImage(Item, TempBlobOriginal); GetBlueImageTempBlob(TempBlobExpected); diff --git a/src/Apps/W1/APIV1/test/src/APIV1PurchaseInvLinesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1PurchaseInvLinesE2E.Codeunit.al index d3b95c6f61c..1a87081c1a2 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1PurchaseInvLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1PurchaseInvLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139738 "APIV1 - Purchase Inv Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -31,6 +32,7 @@ codeunit 139738 "APIV1 - Purchase Inv Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; @@ -711,6 +713,7 @@ codeunit 139738 "APIV1 - Purchase Inv Lines E2E" TargetURL: Text; ResponseText: Text; InvoiceLineJSON: Text; + LineDescription: Text; begin // [SCENARIO] Posting a line with description only will get a type item // [GIVEN] A post request with description only @@ -719,7 +722,8 @@ codeunit 139738 "APIV1 - Purchase Inv Lines E2E" COMMIT(); - InvoiceLineJSON := '{"description":"test"}'; + LineDescription := Format(CreateGuid()); + InvoiceLineJSON := LibraryGraphMgt.AddPropertytoJSON('', 'description', LineDescription); // [WHEN] we just POST a blank line TargetURL := LibraryGraphMgt @@ -731,8 +735,10 @@ codeunit 139738 "APIV1 - Purchase Inv Lines E2E" LibraryGraphMgt.PostToWebService(TargetURL, InvoiceLineJSON, ResponseText); // [THEN] Line of type Item is created - FindFirstPurchaseLine(PurchaseHeader, PurchaseLine); - PurchaseLine.FINDLAST(); + PurchaseLine.SETRANGE("Document Type", PurchaseHeader."Document Type"); + PurchaseLine.SETRANGE("Document No.", PurchaseHeader."No."); + PurchaseLine.SETRANGE(Description, LineDescription); + Assert.IsTrue(PurchaseLine.FINDFIRST(), 'Could not find the created purchase invoice line'); Assert.AreEqual('', PurchaseLine."No.", 'No should be blank'); Assert.AreEqual(PurchaseLine.Type, PurchaseLine.Type::Item, 'Wrong type is set'); @@ -1149,12 +1155,6 @@ codeunit 139738 "APIV1 - Purchase Inv Lines E2E" - - - - - - diff --git a/src/Apps/W1/APIV1/test/src/APIV1PurchaseInvoicesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1PurchaseInvoicesE2E.Codeunit.al index 8060fbf4d23..dd698a728b4 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1PurchaseInvoicesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1PurchaseInvoicesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139729 "APIV1 - Purchase Invoices E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -34,6 +35,7 @@ codeunit 139729 "APIV1 - Purchase Invoices E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); end; [Test] @@ -423,8 +425,9 @@ codeunit 139729 "APIV1 - Purchase Invoices E2E" Vendor.Validate("Payment Terms Code", PaymentTerms.Code); Vendor.Modify(true); - // [GIVEN] Create Invoice Json with Vendor No and Invoice Date - InvoiceJSON := CreateInvoiceJSON('vendorNumber', VendorNo, 'invoiceDate', WorkDate()); + // [GIVEN] Create Invoice Json with dates before the vendor defaults are applied + InvoiceJSON := CreateInvoiceJSON('invoiceDate', WorkDate(), 'postingDate', WorkDate()); + InvoiceJSON := LibraryGraphMgt.AddPropertytoJSON(InvoiceJSON, 'vendorNumber', VendorNo); COMMIT(); // [WHEN] We POST the JSON to the Web Service @@ -441,7 +444,30 @@ codeunit 139729 "APIV1 - Purchase Invoices E2E" PurchaseHeader.SETRANGE("No.", InvoiceNumber); PurchaseHeader.SETRANGE("Buy-from Vendor No.", VendorNo); Assert.IsTrue(PurchaseHeader.FINDFIRST(), UnpostedInvoiceExistErr); - Assert.IsTrue(PurchaseHeader."Payment Discount %" <> 0, PaymentDiscountErr); + if PurchaseHeader."Payment Discount %" = 0 then + Assert.IsTrue(HasLocalizedPaymentDiscount(PurchaseHeader."No."), PaymentDiscountErr); + end; + + local procedure HasLocalizedPaymentDiscount(DocumentNo: Code[20]): Boolean + var + RecordField: Record Field; + PaymentLineRecordRef: RecordRef; + PaymentLineFieldRef: FieldRef; + begin + RecordField.SetRange(TableNo, 12170); + if RecordField.IsEmpty() then + exit(false); + + PaymentLineRecordRef.Open(12170); + PaymentLineFieldRef := PaymentLineRecordRef.Field(10); + PaymentLineFieldRef.SetRange(2); + PaymentLineFieldRef := PaymentLineRecordRef.Field(1); + PaymentLineFieldRef.SetRange(2); + PaymentLineFieldRef := PaymentLineRecordRef.Field(2); + PaymentLineFieldRef.SetRange(DocumentNo); + PaymentLineFieldRef := PaymentLineRecordRef.Field(7); + PaymentLineFieldRef.SetFilter('>%1', 0); + exit(not PaymentLineRecordRef.IsEmpty()); end; local procedure CreatePurchaseInvoices(var InvoiceID1: Text; var InvoiceID2: Text) @@ -542,15 +568,7 @@ codeunit 139729 "APIV1 - Purchase Invoices E2E" end; local procedure CreatePaymentTermsWithDiscount(var PaymentTerms: Record "Payment Terms") - var - DateCalculation: DateFormula; begin - LibraryERM.CreatePaymentTerms(PaymentTerms); - Evaluate(DateCalculation, '1M'); - PaymentTerms.Validate("Due Date Calculation", DateCalculation); - Evaluate(DateCalculation, '8D'); - PaymentTerms.Validate("Discount Date Calculation", DateCalculation); - PaymentTerms.Validate("Discount %", 2); - PaymentTerms.Modify(true); + LibraryERM.CreatePaymentTermsDiscount(PaymentTerms, true); end; } diff --git a/src/Apps/W1/APIV1/test/src/APIV1RetEarningsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1RetEarningsE2E.Codeunit.al index 2bc76f8cb32..ec6e7e8f2ae 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1RetEarningsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1RetEarningsE2E.Codeunit.al @@ -62,6 +62,7 @@ codeunit 139721 "APIV1 - Ret. Earnings E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1SalesCrMemoLinesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1SalesCrMemoLinesE2E.Codeunit.al index 1d5fc4dabe1..355019ea0e6 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1SalesCrMemoLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1SalesCrMemoLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139737 "APIV1 - Sales CrMemo Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -30,6 +31,7 @@ codeunit 139737 "APIV1 - Sales CrMemo Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; @@ -698,6 +700,7 @@ codeunit 139737 "APIV1 - Sales CrMemo Lines E2E" TargetURL: Text; ResponseText: Text; CreditMemoLineJSON: Text; + LineDescription: Text; begin // [SCENARIO] Posting a line with description only will get a type item // [GIVEN] A post request with description only @@ -706,7 +709,8 @@ codeunit 139737 "APIV1 - Sales CrMemo Lines E2E" COMMIT(); - CreditMemoLineJSON := '{"description":"test"}'; + LineDescription := Format(CreateGuid()); + CreditMemoLineJSON := LibraryGraphMgt.AddPropertytoJSON('', 'description', LineDescription); // [WHEN] we just POST a blank line TargetURL := LibraryGraphMgt @@ -718,8 +722,10 @@ codeunit 139737 "APIV1 - Sales CrMemo Lines E2E" LibraryGraphMgt.PostToWebService(TargetURL, CreditMemoLineJSON, ResponseText); // [THEN] Line of type Item is created - FindFirstSalesLine(SalesHeader, SalesLine); - SalesLine.FINDLAST(); + SalesLine.SETRANGE("Document Type", SalesHeader."Document Type"); + SalesLine.SETRANGE("Document No.", SalesHeader."No."); + SalesLine.SETRANGE(Description, LineDescription); + Assert.IsTrue(SalesLine.FINDFIRST(), 'Could not find the created credit memo line'); Assert.AreEqual('', SalesLine."No.", 'No should be blank'); Assert.AreEqual(SalesLine.Type, SalesLine.Type::Item, 'Wrong type is set'); @@ -1392,12 +1398,6 @@ codeunit 139737 "APIV1 - Sales CrMemo Lines E2E" - - - - - - diff --git a/src/Apps/W1/APIV1/test/src/APIV1SalesCreditMemosE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1SalesCreditMemosE2E.Codeunit.al index 8ab2dff2dbb..e8cb5a6b78f 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1SalesCreditMemosE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1SalesCreditMemosE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -35,6 +36,11 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" CreditMemoStatusErr: Label 'The credit memo status is incorrect.'; MailingJobErr: Label 'The mailing job is not created.', Locked = true; + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; + local procedure InitializeForSending() var TempEmailAccount: Record "Email Account"; @@ -60,6 +66,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO] Create posted and unposted sales credit memos and use a GET method to retrieve them + Initialize(); + // [GIVEN] 2 credit memos, one posted and one unposted CreateSalesCreditMemos(CreditMemoNo1, CreditMemoNo2); COMMIT(); @@ -93,6 +101,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO] Create posted and unposted Sales credit memos and use HTTP POST to delete them + Initialize(); + // [GIVEN] 2 credit memos, one posted and one unposted LibrarySales.CreateCustomerWithAddress(SellToCustomer); LibrarySales.CreateCustomerWithAddress(BillToCustomer); @@ -138,6 +148,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO] Create posted and unposted with specific currency set and use HTTP POST to create them + Initialize(); + // [GIVEN] an CreditMemo with a non-LCY currencyCode set LibrarySales.CreateCustomer(Customer); CustomerNo := Customer."No."; @@ -168,18 +180,24 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" [Test] procedure TestModifyCreditMemos() begin + Initialize(); + TestMultipleModifyCreditMemos(FALSE, FALSE); end; [Test] procedure TestEmptyModifyCreditMemos() begin + Initialize(); + TestMultipleModifyCreditMemos(TRUE, FALSE); end; [Test] procedure TestPartialModifyCreditMemos() begin + Initialize(); + TestMultipleModifyCreditMemos(FALSE, TRUE); end; @@ -263,6 +281,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO] Create unposted sales credit memo and use HTTP DELETE to delete it + Initialize(); + // [GIVEN] An unposted credit memo CreateDraftSalesCreditMemo(SalesHeader); CreditMemoNo := SalesHeader."No."; @@ -296,6 +316,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" // [SCENARIO] Create an credit memo both through the client UI and through the API // [SCENARIO] and compare them. They should be the same and have the same fields autocompleted wherever needed. + Initialize(); + // [GIVEN] An unposted credit memo LibraryGraphDocumentTools.InitializeUIPage(); @@ -329,6 +351,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO] When an credit memo is created,the GET Method should update the credit memo and assign a total + Initialize(); + // [GIVEN] 2 credit memos, one posted and one unposted without totals assigned LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending( SalesHeader, DiscountPct, SalesHeader."Document Type"::"Credit Memo"); @@ -362,6 +386,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO] When an credit memo is created, the GET Method should update the credit memo and assign a total + Initialize(); + // [GIVEN] 2 credit memos, one posted and one unposted with discount amount that should be redistributed LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending( SalesHeader, DiscountPct, SalesHeader."Document Type"::"Credit Memo"); @@ -401,6 +427,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" CreditMemoID: Text; begin // [SCENARIO 184721] Create Credit Memo, use a PATCH method to change it and then verify the changes + Initialize(); + LibrarySales.CreateCustomerWithAddress(Customer); // [GIVEN] an item with unit price and unit cost @@ -448,6 +476,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO 184721] Clearing manually set discount + Initialize(); + // [GIVEN] an item with unit price and unit cost LibraryInventory.CreateItemWithUnitPriceAndUnitCost( Item, LibraryRandom.RandDecInRange(1, 100, 2), LibraryRandom.RandDecInRange(1, 100, 2)); @@ -503,6 +533,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO] User can post a sales credit memo through the API. + Initialize(); + // [GIVEN] Draft sales credit memo exists CreateDraftSalesCreditMemo(SalesHeader); SetCustomerEmail(SalesHeader."Sell-to Customer No."); @@ -549,6 +581,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" TargetURL: Text; begin // [SCENARIO] User can post and send a sales credit memo through the API. + Initialize(); + InitializeForSending(); // [GIVEN] Draft sales credit memos exists @@ -588,6 +622,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO] User can cancel a posted sales credit memo through API. + Initialize(); + // [GIVEN] Non-corrective sales credit memo exists CreatePostedSalesCreditMemo(SalesCrMemoHeader); SetCustomerEmail(SalesCrMemoHeader."Sell-to Customer No."); @@ -617,6 +653,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" begin // [SCENARIO] User can cancel a posted sales credit memo through API. + Initialize(); + // [GIVEN] Corrective sales credit memo exists CreateCorrectiveSalesCreditMemo(SalesCrMemoHeader); SetCustomerEmail(SalesCrMemoHeader."Sell-to Customer No."); @@ -649,6 +687,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" TargetURL: Text; begin // [SCENARIO] User can cancel a posted sales credit memo through API. + Initialize(); + InitializeForSending(); // [GIVEN] Corrective sales credit memo exists @@ -685,6 +725,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" TargetURL: Text; begin // [SCENARIO] User can send a posted sales credit memo through the API. + Initialize(); + InitializeForSending(); // [GIVEN] Posted sales credit memo exists @@ -717,6 +759,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" TargetURL: Text; begin // [SCENARIO] Sending a draft sales credit memo through the API throws an error + Initialize(); + InitializeForSending(); // [GIVEN] Draft sales credit memo exists @@ -746,6 +790,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" TargetURL: Text; begin // [SCENARIO] User can send a draft sales credit memo through the API. + Initialize(); + InitializeForSending(); // [GIVEN] Cancelled sales credit memo exists @@ -769,12 +815,17 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" local procedure CreateCorrectiveSalesCreditMemo(var SalesCrMemoHeader: Record "Sales Cr.Memo Header") var + ReasonCode: Record "Reason Code"; SalesInvoiceHeader: Record "Sales Invoice Header"; SalesHeader: Record "Sales Header"; InvoiceCode: Code[20]; begin LibrarySales.CreateSalesInvoice(SalesHeader); ModifySalesHeaderPostingDate(SalesHeader, WORKDATE()); + EnsureReasonCode(); + ReasonCode.FindFirst(); + SalesHeader.Validate("Reason Code", ReasonCode.Code); + SalesHeader.Modify(true); InvoiceCode := LibrarySales.PostSalesDocument(SalesHeader, false, true); SalesInvoiceHeader.Get(InvoiceCode); Commit(); @@ -783,6 +834,16 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" SalesCrMemoHeader.FindFirst(); end; + local procedure EnsureReasonCode() + var + ReasonCode: Record "Reason Code"; + begin + if not ReasonCode.IsEmpty() then + exit; + + LibraryERM.CreateReasonCode(ReasonCode); + end; + local procedure CreateDraftSalesCreditMemo(var SalesHeader: Record "Sales Header") begin LibrarySales.CreateSalesCreditMemo(SalesHeader); @@ -952,6 +1013,8 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" SalesHeader1RecordRef.GETTABLE(SalesHeader1); SalesHeader2RecordRef.GETTABLE(SalesHeader2); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, DATABASE::"Sales Header", 'Operation Occurred Date'); Assert.RecordsAreEqualExceptCertainFields( SalesHeader1RecordRef, SalesHeader2RecordRef, TempIgnoredFieldsForComparison, 'Credit Memos do not match'); @@ -1071,4 +1134,3 @@ codeunit 139728 "APIV1 - Sales Credit Memos E2E" JobQueueEntry.Cancel(); end; } - diff --git a/src/Apps/W1/APIV1/test/src/APIV1SalesInvLinesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1SalesInvLinesE2E.Codeunit.al index 86e95b3f302..ad4c4c6606e 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1SalesInvLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1SalesInvLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139734 "APIV1 - Sales Inv. Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -33,6 +34,7 @@ codeunit 139734 "APIV1 - Sales Inv. Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; @@ -935,6 +937,7 @@ codeunit 139734 "APIV1 - Sales Inv. Lines E2E" TargetURL: Text; ResponseText: Text; InvoiceLineJSON: Text; + LineDescription: Text; begin // [SCENARIO] Posting a line with description only will get a type item // [GIVEN] A post request with description only @@ -943,7 +946,8 @@ codeunit 139734 "APIV1 - Sales Inv. Lines E2E" COMMIT(); - InvoiceLineJSON := '{"description":"test"}'; + LineDescription := Format(CreateGuid()); + InvoiceLineJSON := LibraryGraphMgt.AddPropertytoJSON('', 'description', LineDescription); // [WHEN] we just POST a blank line TargetURL := LibraryGraphMgt @@ -955,8 +959,10 @@ codeunit 139734 "APIV1 - Sales Inv. Lines E2E" LibraryGraphMgt.PostToWebService(TargetURL, InvoiceLineJSON, ResponseText); // [THEN] Line of type Item is created - FindFirstSalesLine(SalesHeader, SalesLine); - SalesLine.FINDLAST(); + SalesLine.SETRANGE("Document Type", SalesHeader."Document Type"); + SalesLine.SETRANGE("Document No.", SalesHeader."No."); + SalesLine.SETRANGE(Description, LineDescription); + Assert.IsTrue(SalesLine.FINDFIRST(), 'Could not find the created invoice line'); Assert.AreEqual('', SalesLine."No.", 'No should be blank'); Assert.AreEqual(SalesLine.Type, SalesLine.Type::Item, 'Wrong type is set'); VerifyIdsAreBlank(ResponseText); @@ -1070,6 +1076,8 @@ codeunit 139734 "APIV1 - Sales Inv. Lines E2E" Assert.AreNotEqual('', InvoiceLineID, 'ID should not be empty'); LineNo := SalesLine."Line No."; LibraryInventory.CreateItem(Item); + LibraryGraphDocumentTools.EnsureVATPostingSetupExists( + SalesLine."VAT Bus. Posting Group", Item."VAT Prod. Posting Group"); InvoiceLineJSON := STRSUBSTNO('{"itemId":"%1"}', LibraryGraphMgt.StripBrackets(Format(Item.SystemId))); COMMIT(); diff --git a/src/Apps/W1/APIV1/test/src/APIV1SalesOrderLinesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1SalesOrderLinesE2E.Codeunit.al index 2afa4cf7193..4f0ca203149 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1SalesOrderLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1SalesOrderLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139735 "APIV1 - Sales Order Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -31,6 +32,7 @@ codeunit 139735 "APIV1 - Sales Order Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; @@ -712,6 +714,7 @@ codeunit 139735 "APIV1 - Sales Order Lines E2E" TargetURL: Text; ResponseText: Text; OrderLineJSON: Text; + LineDescription: Text; begin // [SCENARIO] Posting a line with description only will get a type item // [GIVEN] A post request with description only @@ -720,7 +723,8 @@ codeunit 139735 "APIV1 - Sales Order Lines E2E" COMMIT(); - OrderLineJSON := '{"description":"test"}'; + LineDescription := Format(CreateGuid()); + OrderLineJSON := LibraryGraphMgt.AddPropertytoJSON('', 'description', LineDescription); // [WHEN] we just POST a blank line TargetURL := LibraryGraphMgt @@ -732,8 +736,10 @@ codeunit 139735 "APIV1 - Sales Order Lines E2E" LibraryGraphMgt.PostToWebService(TargetURL, OrderLineJSON, ResponseText); // [THEN] Line of type Item is created - FindFirstSalesLine(SalesHeader, SalesLine); - SalesLine.FINDLAST(); + SalesLine.SETRANGE("Document Type", SalesHeader."Document Type"); + SalesLine.SETRANGE("Document No.", SalesHeader."No."); + SalesLine.SETRANGE(Description, LineDescription); + Assert.IsTrue(SalesLine.FINDFIRST(), 'Could not find the created order line'); Assert.AreEqual('', SalesLine."No.", 'No should be blank'); Assert.AreEqual(SalesLine.Type, SalesLine.Type::Item, 'Wrong type is set'); @@ -844,6 +850,8 @@ codeunit 139735 "APIV1 - Sales Order Lines E2E" Assert.AreNotEqual('', OrderId, 'ID should not be empty'); LibraryInventory.CreateItem(Item); + LibraryGraphDocumentTools.EnsureVATPostingSetupExists( + SalesLine."VAT Bus. Posting Group", Item."VAT Prod. Posting Group"); OrderLineJSON := STRSUBSTNO('{"itemId":"%1"}', LibraryGraphMgt.StripBrackets(Format(Item.SystemId))); COMMIT(); @@ -1279,14 +1287,6 @@ codeunit 139735 "APIV1 - Sales Order Lines E2E" - - - - - - - - diff --git a/src/Apps/W1/APIV1/test/src/APIV1SalesOrdersE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1SalesOrdersE2E.Codeunit.al index ec9fb22f169..37582fd28a5 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1SalesOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1SalesOrdersE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139711 "APIV1 - Sales Orders E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -40,6 +41,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO 184721] Create Sales Orders and use a GET method to retrieve them + Initialize(); + // [GIVEN] 2 orders in the table LibrarySales.CreateSalesOrder(SalesHeader); OrderNo[1] := SalesHeader."No."; @@ -78,6 +81,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO 184721] Create sales orders JSON and use HTTP POST to create them + Initialize(); + // [GIVEN] a customer LibrarySales.CreateCustomerWithAddress(SellToCustomer); LibrarySales.CreateCustomerWithAddress(BillToCustomer); @@ -127,6 +132,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO 184721] Create sales order for customer with location and use HTTP POST to create it + Initialize(); + // [GIVEN] an order with customer with location code LibrarySales.CreateCustomer(Customer); LibraryWarehouse.CreateLocation(Location); @@ -170,6 +177,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO 184721] Create sales order with specific currency set and use HTTP POST to create it + Initialize(); + // [GIVEN] an order with a non-LCY currencyCode set LibrarySales.CreateCustomer(Customer); CustomerNo := Customer."No."; @@ -203,21 +212,32 @@ codeunit 139711 "APIV1 - Sales Orders E2E" [Test] procedure TestModifyOrders() begin + Initialize(); + TestMultipleModifyOrders(false, false); end; [Test] procedure TestEmptyModifyOrders() begin + Initialize(); + TestMultipleModifyOrders(true, false); end; [Test] procedure TestPartialModifyOrders() begin + Initialize(); + TestMultipleModifyOrders(false, true); end; + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; + local procedure TestMultipleModifyOrders(EmptyData: Boolean; PartiallyEmptyData: Boolean) var SellToCustomer: Record "Customer"; @@ -291,6 +311,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO 184721] Create sales orders and use HTTP DELETE to delete them + Initialize(); + // [GIVEN] 2 orders in the table LibrarySales.CreateSalesOrder(SalesHeader); OrderNo[1] := SalesHeader."No."; @@ -336,6 +358,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" OrderWithComplexJSON: Text; begin // [SCENARIO 184721] Create an order both through the client UI and through the API and compare them. They should be the same and have the same fields autocompleted wherever needed. + Initialize(); + LibraryGraphDocumentTools.InitializeUIPage(); // [GIVEN] a customer @@ -381,6 +405,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" PageSalesHeader.Get(PageSalesHeader."Document Type"::Order, SalesOrder."No.".VALUE()); ApiRecordRef.GetTable(ApiSalesHeader); PageRecordRef.GetTable(PageSalesHeader); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, DATABASE::"Sales Header", 'Operation Occurred Date'); Assert.RecordsAreEqualExceptCertainFields(ApiRecordRef, PageRecordRef, TempIgnoredFieldsForComparison, 'Page and API order do not match'); @@ -396,6 +422,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO 184721] When an order is created, the GET Method should update the order and assign a total + Initialize(); + // [GIVEN] an order without totals assigned LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending(SalesHeader, DiscountPct, SalesHeader."Document Type"::Order); SalesHeader.CalcFields("Recalculate Invoice Disc."); @@ -426,6 +454,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO 184721] When an order is created, the GET Method should update the order and redistribute the discount amount + Initialize(); + // [GIVEN] an order with discount amount that should be redistributed LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending(SalesHeader, DiscountPct, SalesHeader."Document Type"::Order); SalesHeader.CalcFields(Amount); @@ -461,6 +491,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO 184721] Create Sales Order, use a PATCH method to change it and then verify the changes + Initialize(); + // [GIVEN] an order with lines CreateOrderWithLines(SalesHeader); OrderId := SalesHeader.SystemId; @@ -497,6 +529,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO 184721] Clearing manually set discount + Initialize(); + // [GIVEN] an order CreateOrderWithLines(SalesHeader); OrderNo := SalesHeader."No."; @@ -533,6 +567,8 @@ codeunit 139711 "APIV1 - Sales Orders E2E" begin // [SCENARIO] User can ship and invoice a sales order through the API. + Initialize(); + // [GIVEN] a sales order with lines CreateOrderWithLines(SalesHeader); OrderId := SalesHeader.SystemId; diff --git a/src/Apps/W1/APIV1/test/src/APIV1SalesQuoteLinesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1SalesQuoteLinesE2E.Codeunit.al index b4e577f634b..c2c4c1b3507 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1SalesQuoteLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1SalesQuoteLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139736 "APIV1 - Sales Quote Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -29,6 +30,7 @@ codeunit 139736 "APIV1 - Sales Quote Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; @@ -614,6 +616,7 @@ codeunit 139736 "APIV1 - Sales Quote Lines E2E" TargetURL: Text; ResponseText: Text; QuoteLineJSON: Text; + LineDescription: Text; begin // [SCENARIO] Posting a line with description only will get a type item // [GIVEN] A post request with description only @@ -622,7 +625,8 @@ codeunit 139736 "APIV1 - Sales Quote Lines E2E" COMMIT(); - QuoteLineJSON := '{"description":"test"}'; + LineDescription := Format(CreateGuid()); + QuoteLineJSON := LibraryGraphMgt.AddPropertytoJSON('', 'description', LineDescription); // [WHEN] we just POST a blank line TargetURL := LibraryGraphMgt @@ -634,8 +638,10 @@ codeunit 139736 "APIV1 - Sales Quote Lines E2E" LibraryGraphMgt.PostToWebService(TargetURL, QuoteLineJSON, ResponseText); // [THEN] Line of type Item is created - FindFirstSalesLine(SalesHeader, SalesLine); - SalesLine.FINDLAST(); + SalesLine.SETRANGE("Document Type", SalesHeader."Document Type"); + SalesLine.SETRANGE("Document No.", SalesHeader."No."); + SalesLine.SETRANGE(Description, LineDescription); + Assert.IsTrue(SalesLine.FINDFIRST(), 'Could not find the created quote line'); Assert.AreEqual('', SalesLine."No.", 'No should be blank'); Assert.AreEqual(SalesLine.Type, SalesLine.Type::Item, 'Wrong type is set'); @@ -1005,12 +1011,6 @@ codeunit 139736 "APIV1 - Sales Quote Lines E2E" - - - - - - diff --git a/src/Apps/W1/APIV1/test/src/APIV1SalesQuotesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1SalesQuotesE2E.Codeunit.al index b395b79b8e8..c11848db893 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1SalesQuotesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1SalesQuotesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -39,6 +40,11 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" InvoiceIdErr: Label 'The invoice ID should differ from the quote ID.', Locked = true; MailingJobErr: Label 'The mailing job is not created.', Locked = true; + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; + local procedure InitializeForSending() var TempEmailAccount: Record "Email Account"; @@ -64,6 +70,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" begin // [SCENARIO] Create Sales Quotes and use a GET method to retrieve them + Initialize(); + // [GIVEN] 2 quotes in the table CreateSalesQuoteWithLines(SalesHeader); QuoteID[1] := SalesHeader."No."; @@ -102,6 +110,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" begin // [SCENARIO] Create sales quotes JSON and use HTTP POST to create them + Initialize(); + // [GIVEN] a customer LibrarySales.CreateCustomerWithAddress(SellToCustomer); LibrarySales.CreateCustomerWithAddress(ShipToCustomer); @@ -147,6 +157,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" begin // [SCENARIO] Create sales quote with specific currency set and use HTTP POST to create it + Initialize(); + // [GIVEN] a quote with a non-LCY currencyCode set LibrarySales.CreateCustomer(Customer); CustomerNo := Customer."No."; @@ -176,18 +188,24 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" [Test] procedure TestModifyQuotes() begin + Initialize(); + TestMultipleModifyQuotes(false, false); end; [Test] procedure TestEmptyModifyQuotes() begin + Initialize(); + TestMultipleModifyQuotes(true, false); end; [Test] procedure TestPartialModifyQuotes() begin + Initialize(); + TestMultipleModifyQuotes(false, true); end; @@ -281,6 +299,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" begin // [SCENARIO] Create sales quotes and use HTTP DELETE to delete them + Initialize(); + // [GIVEN] 2 quotes in the table CreateSalesQuoteWithLines(SalesHeader); QuoteID[1] := SalesHeader."No."; @@ -326,6 +346,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" QuoteExists: Boolean; begin // [SCENARIO] Create a quote both through the client UI and through the API and compare them. They should be the same and have the same fields autocompleted wherever needed. + Initialize(); + LibraryGraphDocumentTools.InitializeUIPage(); // [GIVEN] a customer @@ -367,6 +389,11 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" PageSalesHeader.Get(PageSalesHeader."Document Type"::Quote, SalesQuote."No.".VALUE()); ApiRecordRef.GETTABLE(ApiSalesHeader); PageRecordRef.GETTABLE(PageSalesHeader); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, DATABASE::"Sales Header", 'Operation Occurred Date'); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, DATABASE::"Sales Header", 'VAT Reporting Date'); + Assert.RecordsAreEqualExceptCertainFields(ApiRecordRef, PageRecordRef, TempIgnoredFieldsForComparison, 'Page and API quote do not match'); end; @@ -381,6 +408,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" begin // [SCENARIO] When a quote is created, the GET Method should update the quote and assign a total + Initialize(); + // [GIVEN] a quote without totals assigned LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending(SalesHeader, DiscountPct, SalesHeader."Document Type"::Quote); SalesHeader.CalcFields("Recalculate Invoice Disc."); @@ -411,6 +440,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" begin // [SCENARIO] When a quote is created, the GET Method should update the quote and redistribute the discount amount + Initialize(); + // [GIVEN] a quote with discount amount that should be redistributed LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending(SalesHeader, DiscountPct, SalesHeader."Document Type"::Quote); SalesHeader.CalcFields(Amount); @@ -447,6 +478,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" QuoteID: Text; begin // [SCENARIO 184721] Create Sales Quote, use a PATCH method to change it and then verify the changes + Initialize(); + LibrarySales.CreateCustomerWithAddress(Customer); // [GIVEN] an item with unit price and unit cost @@ -494,6 +527,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" begin // [SCENARIO 184721] Clearing manually set discount + Initialize(); + // [GIVEN] an item with unit price and unit cost LibraryInventory.CreateItemWithUnitPriceAndUnitCost( Item, LibraryRandom.RandDecInRange(1, 100, 2), LibraryRandom.RandDecInRange(1, 100, 2)); @@ -541,6 +576,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" TargetURL: Text; begin // [SCENARIO] User can send a sales quote through the API. + Initialize(); + InitializeForSending(); // [GIVEN] Draft sales quote exists @@ -585,6 +622,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" begin // [SCENARIO] User can convert a sales quote to a sales invoice through the API. + Initialize(); + // [GIVEN] Sales quote exists CreateSalesQuoteWithLines(SalesHeader); CreateEmailParameters(SalesHeader); @@ -643,6 +682,8 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" begin // [SCENARIO] User can convert a sales quote to a sales order through the API. + Initialize(); + // [GIVEN] Sales quote exists CreateSalesQuoteWithLines(SalesHeader); CreateEmailParameters(SalesHeader); @@ -770,6 +811,9 @@ codeunit 139723 "APIV1 - Sales Quotes E2E" LibrarySmallBusiness.CreateCustomer(Customer); LibrarySmallBusiness.CreateItem(Item); LibrarySmallBusiness.CreateSalesQuoteHeaderWithLines(SalesHeader, Customer, Item, 1, 1); + SalesHeader.Validate("Posting Date", WorkDate()); + SalesHeader.Validate("Document Date", WorkDate()); + SalesHeader.Modify(true); end; local procedure FindSalesHeader(var SalesHeader: Record "Sales Header"; CustomerNo: Text; QuoteNumber: Text): Boolean diff --git a/src/Apps/W1/APIV1/test/src/APIV1ShipmentMethodsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1ShipmentMethodsE2E.Codeunit.al index 09cf7ce2b3e..258e339c1c9 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1ShipmentMethodsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1ShipmentMethodsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139705 "APIV1 - Shipment Methods E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -21,6 +22,7 @@ codeunit 139705 "APIV1 - Shipment Methods E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1TaxAreasE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1TaxAreasE2E.Codeunit.al index bffc2b39d55..382b9e630c5 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1TaxAreasE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1TaxAreasE2E.Codeunit.al @@ -24,6 +24,7 @@ codeunit 139726 "APIV1 - Tax Areas E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1TrialBalanceE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1TrialBalanceE2E.Codeunit.al index c495bc2ddfc..3daeb9c1c0a 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1TrialBalanceE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1TrialBalanceE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139718 "APIV1 - Trial Balance E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -60,6 +61,7 @@ codeunit 139718 "APIV1 - Trial Balance E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/APIV1UofME2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1UofME2E.Codeunit.al index b283bc61d9d..d4f8b661f30 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1UofME2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1UofME2E.Codeunit.al @@ -26,6 +26,8 @@ codeunit 139712 "APIV1 - UofM E2E" begin // [SCENARIO] User can get the units of measure. + Initialize(); + // [GIVEN] Units of measure. GenerateUnitsOfMeasure(UnitOfMeasure, 5); @@ -46,6 +48,8 @@ codeunit 139712 "APIV1 - UofM E2E" begin // [SCENARIO] User can update a unit of measure. + Initialize(); + // [GIVEN] Units of measure. GenerateUnitsOfMeasure(UnitOfMeasure, 5); @@ -75,6 +79,8 @@ codeunit 139712 "APIV1 - UofM E2E" begin // [SCENARIO] User can delete a unit of measure. + Initialize(); + // [GIVEN] Units of measure. GenerateUnitsOfMeasure(UnitOfMeasure, 5); @@ -96,6 +102,8 @@ codeunit 139712 "APIV1 - UofM E2E" begin // [SCENARIO] User can insert a unit of measure. + Initialize(); + // [GIVEN] A new unit of measure. GenerateUnitOfMeasure(UnitOfMeasure); Request := CreateInsertUnitOfMeasureRequest(UnitOfMeasure); @@ -111,6 +119,11 @@ codeunit 139712 "APIV1 - UofM E2E" ValidateUnitOfMeasure(UnitOfMeasure, Response); end; + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; + local procedure GenerateUnitsOfMeasure(var UnitOfMeasure: Record "Unit of Measure"; "Count": Integer) var i: Integer; diff --git a/src/Apps/W1/APIV1/test/src/APIV1VendorsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1VendorsE2E.Codeunit.al index 44570b29311..f21938f5859 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1VendorsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1VendorsE2E.Codeunit.al @@ -25,6 +25,7 @@ codeunit 139703 "APIV1 - Vendors E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/CountriesRegionsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/CountriesRegionsE2E.Codeunit.al index 1e4843ec39c..0948d98d400 100644 --- a/src/Apps/W1/APIV1/test/src/CountriesRegionsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/CountriesRegionsE2E.Codeunit.al @@ -155,6 +155,7 @@ codeunit 139710 "Countries/Regions E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/PaymentMethodsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/PaymentMethodsE2E.Codeunit.al index 005c5f0add8..a0dedcde372 100644 --- a/src/Apps/W1/APIV1/test/src/PaymentMethodsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/PaymentMethodsE2E.Codeunit.al @@ -155,6 +155,7 @@ codeunit 139714 "Payment Methods E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV1/test/src/SalesInvoicesE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/SalesInvoicesE2E.Codeunit.al index dbf39f9a725..ff8ab0ede12 100644 --- a/src/Apps/W1/APIV1/test/src/SalesInvoicesE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/SalesInvoicesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139709 "Sales Invoices E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -48,6 +49,11 @@ codeunit 139709 "Sales Invoices E2E" NotEmptyParameterErr: Label 'Email parameter %1 is not empty.', Locked = true; MailingJobErr: Label 'The mailing job is not created.', Locked = true; + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; + local procedure InitializeForSending() var TempEmailAccount: Record "Email Account"; @@ -73,6 +79,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO 184721] Create posted and unposted Sales invoices and use a GET method to retrieve them + Initialize(); + // [GIVEN] 2 invoices, one posted and one unposted CreateSalesInvoices(InvoiceID1, InvoiceID2); COMMIT(); @@ -106,6 +114,8 @@ codeunit 139709 "Sales Invoices E2E" InvoiceWithComplexJSON: Text; begin // [SCENARIO 184721] Create posted and unposted Sales invoices and use HTTP POST to delete them + Initialize(); + // [GIVEN] 2 invoices, one posted and one unposted LibrarySales.CreateCustomer(SellToCustomer); @@ -157,6 +167,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO 184721] Create posted and unposted with specific currency set and use HTTP POST to create them + Initialize(); + // [GIVEN] an Invoice with a non-LCY currencyCode set LibrarySales.CreateCustomer(Customer); CustomerNo := Customer."No."; @@ -203,6 +215,8 @@ codeunit 139709 "Sales Invoices E2E" CurrencyCode: Code[10]; begin // [SCENARIO 285872] Create posted and unposted with specific email set and use HTTP POST to create them + Initialize(); + Email := 'test@microsoft.com'; // [GIVEN] an Customer with no email set @@ -256,6 +270,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO 184721] Create unposted with specific document and due date set and use HTTP POST to create them + Initialize(); + // [GIVEN] an Invoice with a document and due date set LibrarySales.CreateCustomer(Customer); CustomerNo := Customer."No."; @@ -294,18 +310,24 @@ codeunit 139709 "Sales Invoices E2E" [Test] procedure TestModifyInvoices() begin + Initialize(); + TestMultipleModifyInvoices(FALSE, FALSE); end; [Test] procedure TestEmptyModifyInvoices() begin + Initialize(); + TestMultipleModifyInvoices(TRUE, FALSE); end; [Test] procedure TestPartialModifyInvoices() begin + Initialize(); + TestMultipleModifyInvoices(FALSE, TRUE); end; @@ -405,6 +427,8 @@ codeunit 139709 "Sales Invoices E2E" InvoiceWithBlanksJSON: Text; begin // [SCENARIO 184721] Create Sales Invoice with all the Ids filled, use a PATCH method to blank the Ids and the Codes + Initialize(); + LibrarySales.CreateCustomerWithAddress(Customer); // [GIVEN] a currency @@ -470,6 +494,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO 184721] Create draft invoice and issue a patch request to change the number + Initialize(); + // [GIVEN] 1 draft invoice and a json with a new number LibrarySales.CreateSalesInvoice(SalesHeader); NewInvoiceNumber := COPYSTR(CREATEGUID(), 1, MAXSTRLEN(SalesHeader."No.")); @@ -493,6 +519,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO 184721] Create unposted Sales invoice and use HTTP DELETE to delete it + Initialize(); + // [GIVEN] An unposted invoice CreateDraftSalesInvoice(SalesHeader); InvoiceID := SalesHeader."No."; @@ -532,6 +560,8 @@ codeunit 139709 "Sales Invoices E2E" // [SCENARIO 184721] Create an invoice both through the client UI and through the API // [SCENARIO] and compare them. They should be the same and have the same fields autocompleted wherever needed. + Initialize(); + // [GIVEN] An unposted invoice LibraryGraphDocumentTools.InitializeUIPage(); LibraryApplicationArea.DisableApplicationAreaSetup(); @@ -577,6 +607,9 @@ codeunit 139709 "Sales Invoices E2E" PageSalesHeader.GET(PageSalesHeader."Document Type"::Invoice, SalesInvoice."No.".VALUE()); ApiRecordRef.GETTABLE(ApiSalesHeader); PageRecordRef.GETTABLE(PageSalesHeader); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, DATABASE::"Sales Header", 'Operation Occurred Date'); + Assert.RecordsAreEqualExceptCertainFields(ApiRecordRef, PageRecordRef, TempIgnoredFieldsForComparison, 'Page and API Invoice do not match'); @@ -594,7 +627,10 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO 184721] When an invoice is created,the GET Method should update the invoice and assign a total + Initialize(); + // [GIVEN] 2 invoices, one posted and one unposted without totals assigned + LibraryApplicationArea.EnableFoundationSetup(); LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending( SalesHeader, DiscountPct, SalesHeader."Document Type"::Invoice); SalesHeader.CALCFIELDS("Recalculate Invoice Disc."); @@ -627,6 +663,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO 184721] When an invoice is created, the GET Method should update the invoice and assign a total + Initialize(); + // [GIVEN] 2 invoices, one posted and one unposted with discount amount that should be redistributed LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending( SalesHeader, DiscountPct, SalesHeader."Document Type"::Invoice); @@ -663,6 +701,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO 184721] Create an invoice wihtout Customer throws an error + Initialize(); + // [GIVEN] a sales invoice JSON with currency only Currency.SETFILTER(Code, '<>%1', ''); Currency.FINDFIRST(); @@ -690,6 +730,8 @@ codeunit 139709 "Sales Invoices E2E" InvoiceID: Text; begin // [SCENARIO 184721] Create Sales Invoice, use a PATCH method to change it and then verify the changes + Initialize(); + LibrarySales.CreateCustomerWithAddress(Customer); // [GIVEN] an item with unit price and unit cost @@ -737,6 +779,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO 184721] Clearing manually set discount + Initialize(); + // [GIVEN] an item with unit price and unit cost LibraryInventory.CreateItemWithUnitPriceAndUnitCost( Item, LibraryRandom.RandDecInRange(1, 100, 2), LibraryRandom.RandDecInRange(1, 100, 2)); @@ -793,6 +837,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO] User can post a sales invoice through the API. + Initialize(); + // [GIVEN] Draft sales invoice exists CreateDraftSalesInvoice(SalesHeader); DraftInvoiceRecordRef.GetTable(SalesHeader); @@ -838,6 +884,8 @@ codeunit 139709 "Sales Invoices E2E" TargetURL: Text; begin // [SCENARIO] User can post and send a sales invoice through the API. + Initialize(); + InitializeForSending(); // [GIVEN] Draft sales invoice exists @@ -877,12 +925,15 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO] User can cancel a posted sales invoice through API. + Initialize(); + // [GIVEN] Posted sales invoice exists CreatePostedSalesInvoice(SalesInvoiceHeader); SetCustomerEmail(SalesInvoiceHeader."Sell-to Customer No."); DocumentId := SalesInvoiceHeader."Draft Invoice SystemId"; // Special case for AU + EnsureReasonCode(); LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup(); Commit(); @@ -912,6 +963,8 @@ codeunit 139709 "Sales Invoices E2E" TargetURL: Text; begin // [SCENARIO] User can cancel a posted sales invoice through API. + Initialize(); + InitializeForSending(); // [GIVEN] Posted sales invoice exists @@ -920,6 +973,7 @@ codeunit 139709 "Sales Invoices E2E" DocumentId := SalesInvoiceHeader."Draft Invoice SystemId"; // Special case for AU + EnsureReasonCode(); LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup(); Commit(); @@ -952,6 +1006,8 @@ codeunit 139709 "Sales Invoices E2E" TargetURL: Text; begin // [SCENARIO] User can send a posted sales invoice through the API. + Initialize(); + InitializeForSending(); // [GIVEN] Posted sales invoice exists @@ -984,6 +1040,8 @@ codeunit 139709 "Sales Invoices E2E" TargetURL: Text; begin // [SCENARIO] User can send a draft sales invoice through the API. + Initialize(); + InitializeForSending(); // [GIVEN] Draft sales invoice exists @@ -1016,6 +1074,8 @@ codeunit 139709 "Sales Invoices E2E" TargetURL: Text; begin // [SCENARIO] User can send a draft sales invoice through the API. + Initialize(); + InitializeForSending(); // [GIVEN] Cancelled sales invoice exists @@ -1057,6 +1117,8 @@ codeunit 139709 "Sales Invoices E2E" begin // [SCENARIO] User can create a corrective credit memo for the posted sales invoice through the API. + Initialize(); + // [GIVEN] A posted sales invoice exists CreatePostedSalesInvoice(SalesInvoiceHeader); PostedInvoiceRecordRef.GetTable(SalesInvoiceHeader); @@ -1235,9 +1297,22 @@ codeunit 139709 "Sales Invoices E2E" local procedure CreateCancelledSalesInvoice(var SalesInvoiceHeader: Record "Sales Invoice Header") begin CreatePostedSalesInvoice(SalesInvoiceHeader); + EnsureReasonCode(); + LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup(); + Commit(); CODEUNIT.Run(CODEUNIT::"Correct Posted Sales Invoice", SalesInvoiceHeader); end; + local procedure EnsureReasonCode() + var + ReasonCode: Record "Reason Code"; + begin + if not ReasonCode.IsEmpty() then + exit; + + LibraryERM.CreateReasonCode(ReasonCode); + end; + local procedure CreateSalesInvoices(var InvoiceID1: Text; var InvoiceID2: Text) var SalesInvoiceHeader: Record "Sales Invoice Header"; diff --git a/src/Apps/W1/APIV1/test/src/TaxGroupsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/TaxGroupsE2E.Codeunit.al index 15b2166d131..fd6bea2c96d 100644 --- a/src/Apps/W1/APIV1/test/src/TaxGroupsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/TaxGroupsE2E.Codeunit.al @@ -23,6 +23,7 @@ codeunit 139708 "Tax Groups E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); IF IsInitialized THEN EXIT; diff --git a/src/Apps/W1/APIV2/test/src/APIV2AccountingPeriodsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2AccountingPeriodsE2E.Codeunit.al index c578df54f2d..8bc2d4bca55 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2AccountingPeriodsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2AccountingPeriodsE2E.Codeunit.al @@ -16,6 +16,8 @@ codeunit 139859 "APIV2 - Accounting Periods E2E" TargetURL: Text; i: Integer; begin + Initialize(); + // [SCENARIO] Use a GET method to retrieve all accounting periods // [GIVEN] Accounting Periods for i := 1 to 10 do @@ -74,4 +76,9 @@ codeunit 139859 "APIV2 - Accounting Periods E2E" AccountingPeriod.Insert(true); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2AccountsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2AccountsE2E.Codeunit.al index 9389de358ba..05df02dba22 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2AccountsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2AccountsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139801 "APIV2 - Accounts E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -19,6 +20,8 @@ codeunit 139801 "APIV2 - Accounts E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -106,4 +109,3 @@ codeunit 139801 "APIV2 - Accounts E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2AgedAPE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2AgedAPE2E.Codeunit.al index 2418082ad5b..f0f0daa5059 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2AgedAPE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2AgedAPE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139819 "APIV2 - Aged AP E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -60,6 +61,8 @@ codeunit 139819 "APIV2 - Aged AP E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -82,4 +85,3 @@ codeunit 139819 "APIV2 - Aged AP E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2AgedARE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2AgedARE2E.Codeunit.al index 2a280d83eb5..4cd041cfc97 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2AgedARE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2AgedARE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139820 "APIV2 - Aged AR E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -60,6 +61,8 @@ codeunit 139820 "APIV2 - Aged AR E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -81,4 +84,3 @@ codeunit 139820 "APIV2 - Aged AR E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2ApplyVendorEntE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ApplyVendorEntE2E.Codeunit.al index 4b30e2db6ef..03805dfef6c 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ApplyVendorEntE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ApplyVendorEntE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139867 "APIV2 - Apply Vendor Ent. E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -170,10 +171,13 @@ codeunit 139867 "APIV2 - Apply Vendor Ent. E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + LibraryTestInitialize.OnTestInitialize(Codeunit::"APIV2 - Apply Vendor Ent. E2E"); - if not isInitialized then + if not isInitialized then begin isInitialized := true; + end; LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"APIV2 - Apply Vendor Ent. E2E"); end; diff --git a/src/Apps/W1/APIV2/test/src/APIV2ApprovalEntriesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ApprovalEntriesE2E.Codeunit.al index 9ae78501641..158a03dcbc4 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ApprovalEntriesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ApprovalEntriesE2E.Codeunit.al @@ -1,6 +1,5 @@ codeunit 139917 "APIV2 - Approval Entries E2E" { - Subtype = Test; TestType = IntegrationTest; TestPermissions = Disabled; @@ -22,6 +21,8 @@ codeunit 139917 "APIV2 - Approval Entries E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO] Check that approval entries can be retrieved via API // [GIVEN] a Sales order exists @@ -44,4 +45,8 @@ codeunit 139917 "APIV2 - Approval Entries E2E" Assert.IsTrue(LibraryGraphMgt.GetObjectIDFromJSON(ResponseText, 'id', ApprovalEntryId), 'Could not find approval entry'); end; + + local procedure Initialize() + begin + end; } \ No newline at end of file diff --git a/src/Apps/W1/APIV2/test/src/APIV2ApprovalUserSetupE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ApprovalUserSetupE2E.Codeunit.al index 2a259376141..a00ca4ee232 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ApprovalUserSetupE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ApprovalUserSetupE2E.Codeunit.al @@ -1,6 +1,5 @@ codeunit 139918 "APIV2 - Approval UserSetup E2E" { - Subtype = Test; TestType = IntegrationTest; TestPermissions = Disabled; @@ -20,6 +19,8 @@ codeunit 139918 "APIV2 - Approval UserSetup E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO] Check that approval user setup can be retrieved via API // [GIVEN] an Approval User Setup exists @@ -39,4 +40,8 @@ codeunit 139918 "APIV2 - Approval UserSetup E2E" Assert.IsTrue(LibraryGraphMgt.GetObjectIDFromJSON(ResponseText, 'id', UserSetupId), 'Could not find approval user setup'); end; + + local procedure Initialize() + begin + end; } \ No newline at end of file diff --git a/src/Apps/W1/APIV2/test/src/APIV2AssemblyOrdersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2AssemblyOrdersE2E.Codeunit.al index 9de9e6343ae..82a0c779309 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2AssemblyOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2AssemblyOrdersE2E.Codeunit.al @@ -26,6 +26,8 @@ codeunit 139925 "APIV2 - Assembly Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create an assembly order and use GET to retrieve it // [GIVEN] An assembly order LibraryInventory.CreateItem(Item); @@ -48,6 +50,8 @@ codeunit 139925 "APIV2 - Assembly Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create an assembly order and GET it by SystemId // [GIVEN] An assembly order LibraryInventory.CreateItem(Item); @@ -72,6 +76,8 @@ codeunit 139925 "APIV2 - Assembly Orders E2E" TargetURL: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] GET an assembly order with $expand=dimensionSetLines // [GIVEN] An assembly order if not AssemblyHeader.FindFirst() then begin @@ -99,6 +105,8 @@ codeunit 139925 "APIV2 - Assembly Orders E2E" TargetURL: Text; AttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET an assembly order with $expand=attachments // [GIVEN] An assembly order if not AssemblyHeader.FindFirst() then begin @@ -126,6 +134,8 @@ codeunit 139925 "APIV2 - Assembly Orders E2E" TargetURL: Text; DocumentAttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET an assembly order with $expand=documentAttachments // [GIVEN] An assembly order if not AssemblyHeader.FindFirst() then begin @@ -153,6 +163,8 @@ codeunit 139925 "APIV2 - Assembly Orders E2E" TargetURL: Text; PdfDocumentValue: Text; begin + Initialize(); + // [SCENARIO] GET an assembly order with $expand=pdfDocument // [GIVEN] An assembly order if not AssemblyHeader.FindFirst() then begin @@ -180,6 +192,8 @@ codeunit 139925 "APIV2 - Assembly Orders E2E" TargetURL: Text; LinesValue: Text; begin + Initialize(); + // [SCENARIO] GET an assembly order with $expand=assemblyOrderLines // [GIVEN] An assembly order if not AssemblyHeader.FindFirst() then begin @@ -204,4 +218,9 @@ codeunit 139925 "APIV2 - Assembly Orders E2E" exit(TargetURL + '&$expand=' + ExpandValue); exit(TargetURL + '?$expand=' + ExpandValue); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2AttachmentsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2AttachmentsE2E.Codeunit.al index 0ba1716ac2d..7894a37e349 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2AttachmentsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2AttachmentsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139833 "APIV2 - Attachments E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -42,6 +43,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateGenJournalLine(DocumentRecordRef); @@ -65,6 +68,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table GLEntryGuid := CreateGLEntry(DocumentRecordRef); @@ -88,6 +93,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); @@ -110,6 +117,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateDraftSalesInvoice(DocumentRecordRef); @@ -132,6 +141,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateDraftSalesOrder(DocumentRecordRef); @@ -156,6 +167,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreatePostedPurchaseInvoice(DocumentRecordRef, DocumentId); @@ -178,6 +191,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateDraftPurchaseInvoice(DocumentRecordRef); @@ -200,6 +215,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateSalesQuote(DocumentRecordRef); @@ -222,6 +239,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Incoming Document Attachment table CreateGenJournalLine(DocumentRecordRef); @@ -246,6 +265,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Incoming Document Attachment table JournalName := LibraryUtility.GenerateRandomCode(GenJournalBatch.FieldNo(Name), Database::"Gen. Journal Batch"); @@ -272,6 +293,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Incoming Document Attachment table CreateGLEntry(DocumentRecordRef); @@ -295,6 +318,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Incoming Document Attachment table CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); @@ -317,6 +342,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Incoming Document Attachment table CreateDraftSalesInvoice(DocumentRecordRef); @@ -339,6 +366,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Incoming Document Attachment table CreateDraftSalesOrder(DocumentRecordRef); @@ -361,6 +390,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Incoming Document Attachment table CreateSalesQuote(DocumentRecordRef); @@ -383,6 +414,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateDraftPurchaseOrder(DocumentRecordRef); @@ -409,6 +442,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ExpectedBase64Content: Text; ActualBase64Content: Text; begin + Initialize(); + // [SCENARIO] User can update linked attachment binary content through the Attachment API. // [GIVEN] A linked attachment exists CreateGenJournalLine(DocumentRecordRef); @@ -442,6 +477,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ExpectedBase64Content: Text; ActualBase64Content: Text; begin + Initialize(); + // [SCENARIO] User can update linked attachment binary content through the Attachment API. // [GIVEN] A linked attachment exists CreateGLEntry(DocumentRecordRef); @@ -468,6 +505,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateGenJournalLine(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -477,6 +516,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateGLEntry(DocumentRecordRef); TestCreateGLEAttachment(DocumentRecordRef); end; @@ -487,6 +528,8 @@ codeunit 139833 "APIV2 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); TestCreateAttachment(DocumentRecordRef); end; @@ -496,6 +539,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftSalesInvoice(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -505,6 +550,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftSalesOrder(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -515,6 +562,8 @@ codeunit 139833 "APIV2 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedPurchaseInvoice(DocumentRecordRef, DocumentId); TestCreateAttachment(DocumentRecordRef); end; @@ -524,6 +573,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseInvoice(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -533,6 +584,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseOrder(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -634,6 +687,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateSalesQuote(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -643,6 +698,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateGenJournalLine(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -652,6 +709,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateGLEntry(DocumentRecordRef); TestDeleteGLEAttachment(DocumentRecordRef); end; @@ -662,6 +721,8 @@ codeunit 139833 "APIV2 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); TestDeleteAttachment2(DocumentRecordRef); end; @@ -671,6 +732,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftSalesInvoice(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -681,6 +744,8 @@ codeunit 139833 "APIV2 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedPurchaseInvoice(DocumentRecordRef, DocumentId); TestDeleteAttachment2(DocumentRecordRef); end; @@ -690,6 +755,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseInvoice(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -699,6 +766,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateSalesQuote(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -773,6 +842,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] The Attachment is transferred from a Draft Invoice the to Posted Invoice after posting. // [GIVEN] A draft sales invoice exists. CreateDraftSalesInvoice(DocumentRecordRef); @@ -813,6 +884,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] The Attachment is transferred from a Draft Invoice the to Posted Invoice after posting. // [GIVEN] A draft sales invoice exists. CreateDraftPurchaseInvoice(DocumentRecordRef); @@ -855,6 +928,8 @@ codeunit 139833 "APIV2 - Attachments E2E" OldBase64Content: Text; NewBase64Content: Text; begin + Initialize(); + // [SCENARIO] Changing an attachment file name keeps other fields unchanged // [GIVEN] A sales quote exists. CreateSalesQuote(DocumentRecordRef); @@ -899,6 +974,8 @@ codeunit 139833 "APIV2 - Attachments E2E" OldFileName: Text; NewFileName: Text; begin + Initialize(); + // [SCENARIO] Changing an attachment content keeps other fields unchanged // [GIVEN] A draft sales invoice exists. CreateDraftSalesInvoice(DocumentRecordRef); @@ -937,6 +1014,8 @@ codeunit 139833 "APIV2 - Attachments E2E" TargetURL: Text; JSONBody: Text; begin + Initialize(); + // [SCENARIO] User cannot change the attachment ID by making a PATCH request to the Attachments API // [GIVEN] Two documents exist. CreateSalesQuote(DocumentRecordRef[1]); @@ -967,6 +1046,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreatePostedPurchaseCreditMemo(DocumentRecordRef, DocumentId); @@ -989,6 +1070,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Incoming Document Attachment table CreateDraftPurchaseCreditMemo(DocumentRecordRef); @@ -1009,6 +1092,8 @@ codeunit 139833 "APIV2 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedPurchaseCreditMemo(DocumentRecordRef, DocumentId); TestCreateAttachment(DocumentRecordRef); end; @@ -1018,6 +1103,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseCreditMemo(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -1028,6 +1115,8 @@ codeunit 139833 "APIV2 - Attachments E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedPurchaseCreditMemo(DocumentRecordRef, DocumentId); TestDeleteAttachment2(DocumentRecordRef); end; @@ -1037,6 +1126,8 @@ codeunit 139833 "APIV2 - Attachments E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseCreditMemo(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -1054,6 +1145,8 @@ codeunit 139833 "APIV2 - Attachments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] The Attachment is transferred from a Draft Credit Memo the to Posted Credit Memo after posting. // [GIVEN] A draft purchase credit memo exists. LibraryERMCountryData.UpdatePurchasesPayablesSetup(); @@ -1592,4 +1685,9 @@ codeunit 139833 "APIV2 - Attachments E2E" exit(StrSubstNo('%1.%2', Name, Extension)); exit(Name); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2AutomationRSPackage.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2AutomationRSPackage.Codeunit.al index 31c14c5d3ab..5da48e970b6 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2AutomationRSPackage.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2AutomationRSPackage.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139831 "APIV2 - Automation RS Package" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -28,9 +29,9 @@ codeunit 139831 "APIV2 - Automation RS Package" var TenantConfigPackageFile: Record "Tenant Config. Package File"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); TenantConfigPackageFile.DELETEALL(true); - SamplePackageFile := GenerateSamplePackageFile(); end; @@ -354,6 +355,5 @@ codeunit 139831 "APIV2 - Automation RS Package" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2BalanceSheetE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2BalanceSheetE2E.Codeunit.al index f99099da896..54ea5e46b16 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2BalanceSheetE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2BalanceSheetE2E.Codeunit.al @@ -62,6 +62,8 @@ codeunit 139815 "APIV2 - Balance Sheet E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -88,4 +90,3 @@ codeunit 139815 "APIV2 - Balance Sheet E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2BlPurchOrdersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2BlPurchOrdersE2E.Codeunit.al index 25dbc2bfd72..9cae2a48f2e 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2BlPurchOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2BlPurchOrdersE2E.Codeunit.al @@ -24,6 +24,8 @@ codeunit 139908 "APIV2 - Bl. Purch. Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a blanket purchase order and use GET to retrieve it // [GIVEN] A blanket purchase order LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::"Blanket Order", ''); @@ -44,6 +46,8 @@ codeunit 139908 "APIV2 - Bl. Purch. Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a blanket purchase order and GET it by SystemId // [GIVEN] A blanket purchase order LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::"Blanket Order", ''); @@ -66,6 +70,8 @@ codeunit 139908 "APIV2 - Bl. Purch. Orders E2E" TargetURL: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket purchase order with $expand=dimensionSetLines // [GIVEN] A blanket purchase order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Blanket Order"); @@ -92,6 +98,8 @@ codeunit 139908 "APIV2 - Bl. Purch. Orders E2E" TargetURL: Text; AttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket purchase order with $expand=attachments // [GIVEN] A blanket purchase order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Blanket Order"); @@ -118,6 +126,8 @@ codeunit 139908 "APIV2 - Bl. Purch. Orders E2E" TargetURL: Text; DocumentAttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket purchase order with $expand=documentAttachments // [GIVEN] A blanket purchase order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Blanket Order"); @@ -144,6 +154,8 @@ codeunit 139908 "APIV2 - Bl. Purch. Orders E2E" TargetURL: Text; PdfDocumentValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket purchase order with $expand=pdfDocument // [GIVEN] A blanket purchase order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Blanket Order"); @@ -170,6 +182,8 @@ codeunit 139908 "APIV2 - Bl. Purch. Orders E2E" TargetURL: Text; LinesValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket purchase order with $expand=blanketPurchaseOrderLines // [GIVEN] A blanket purchase order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Blanket Order"); @@ -194,4 +208,8 @@ codeunit 139908 "APIV2 - Bl. Purch. Orders E2E" exit(TargetURL + '&$expand=' + ExpandValue); exit(TargetURL + '?$expand=' + ExpandValue); end; + + local procedure Initialize() + begin + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2BlSalesOrdersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2BlSalesOrdersE2E.Codeunit.al index e70ad8a2eb3..e355a39cb05 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2BlSalesOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2BlSalesOrdersE2E.Codeunit.al @@ -24,6 +24,8 @@ codeunit 139909 "APIV2 - Bl. Sales Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a blanket sales order and use GET to retrieve it // [GIVEN] A blanket sales order LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::"Blanket Order", ''); @@ -44,6 +46,8 @@ codeunit 139909 "APIV2 - Bl. Sales Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a blanket sales order and GET it by SystemId // [GIVEN] A blanket sales order LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::"Blanket Order", ''); @@ -66,6 +70,8 @@ codeunit 139909 "APIV2 - Bl. Sales Orders E2E" TargetURL: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket sales order with $expand=dimensionSetLines // [GIVEN] A blanket sales order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Blanket Order"); @@ -92,6 +98,8 @@ codeunit 139909 "APIV2 - Bl. Sales Orders E2E" TargetURL: Text; AttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket sales order with $expand=attachments // [GIVEN] A blanket sales order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Blanket Order"); @@ -118,6 +126,8 @@ codeunit 139909 "APIV2 - Bl. Sales Orders E2E" TargetURL: Text; DocumentAttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket sales order with $expand=documentAttachments // [GIVEN] A blanket sales order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Blanket Order"); @@ -144,6 +154,8 @@ codeunit 139909 "APIV2 - Bl. Sales Orders E2E" TargetURL: Text; PdfDocumentValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket sales order with $expand=pdfDocument // [GIVEN] A blanket sales order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Blanket Order"); @@ -170,6 +182,8 @@ codeunit 139909 "APIV2 - Bl. Sales Orders E2E" TargetURL: Text; LinesValue: Text; begin + Initialize(); + // [SCENARIO] GET a blanket sales order with $expand=blanketSalesOrderLines // [GIVEN] A blanket sales order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Blanket Order"); @@ -194,4 +208,8 @@ codeunit 139909 "APIV2 - Bl. Sales Orders E2E" exit(TargetURL + '&$expand=' + ExpandValue); exit(TargetURL + '?$expand=' + ExpandValue); end; + + local procedure Initialize() + begin + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2CashFlowStatementE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2CashFlowStatementE2E.Codeunit.al index 9ff2fa17758..1a9c508f40c 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2CashFlowStatementE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2CashFlowStatementE2E.Codeunit.al @@ -62,6 +62,8 @@ codeunit 139817 "APIV2 - CashFlow Statement E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -93,4 +95,3 @@ codeunit 139817 "APIV2 - CashFlow Statement E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2CompanyInfoE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2CompanyInfoE2E.Codeunit.al index 9f13dd998bb..9b62669a928 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2CompanyInfoE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2CompanyInfoE2E.Codeunit.al @@ -26,6 +26,8 @@ codeunit 139806 "APIV2 - Company Info. E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2ContactsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ContactsE2E.Codeunit.al index 431c3a98b1c..52049df0d76 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ContactsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ContactsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139866 "APIV2 - Contacts E2E" // version Test,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -22,6 +23,8 @@ codeunit 139866 "APIV2 - Contacts E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2ContactsInfE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ContactsInfE2E.Codeunit.al index 5612f0eb26c..d7c36c41da9 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ContactsInfE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ContactsInfE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139853 "APIV2 - Contacts Inf. E2E" // version Test,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -30,6 +31,8 @@ codeunit 139853 "APIV2 - Contacts Inf. E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [FEATURE] [Customer] // [SCENARIO] Get all contact information for a customer @@ -60,6 +63,8 @@ codeunit 139853 "APIV2 - Contacts Inf. E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [FEATURE] [Customer] // [SCENARIO] Get all contact information for a customer @@ -92,6 +97,8 @@ codeunit 139853 "APIV2 - Contacts Inf. E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [FEATURE] [Vendor] // [SCENARIO] Get all contact information for a vendor @@ -122,6 +129,8 @@ codeunit 139853 "APIV2 - Contacts Inf. E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [FEATURE] [Vendor] // [SCENARIO] Get all contact information for a Vendor @@ -177,4 +186,9 @@ codeunit 139853 "APIV2 - Contacts Inf. E2E" Contact.Validate("Company No.", CompanyNo); Contact.Modify(true); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2CountriesRegionsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2CountriesRegionsE2E.Codeunit.al index 0bd63f98d47..ce452ec9ecb 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2CountriesRegionsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2CountriesRegionsE2E.Codeunit.al @@ -155,6 +155,8 @@ codeunit 139810 "APIV2 - Countries/Regions E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -233,4 +235,3 @@ codeunit 139810 "APIV2 - Countries/Regions E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2CurrenciesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2CurrenciesE2E.Codeunit.al index 5e8bfb987bc..f8defd96544 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2CurrenciesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2CurrenciesE2E.Codeunit.al @@ -155,6 +155,8 @@ codeunit 139813 "APIV2 - Currencies E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -232,4 +234,3 @@ codeunit 139813 "APIV2 - Currencies E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2CurrencyExchRateE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2CurrencyExchRateE2E.Codeunit.al index 36e62a1b344..6fbdb548a34 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2CurrencyExchRateE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2CurrencyExchRateE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139858 "APIV2 Currency Exch. Rate E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; var LibraryERM: Codeunit "Library - ERM"; @@ -107,6 +108,7 @@ codeunit 139858 "APIV2 Currency Exch. Rate E2E" Currency: Record Currency; CurrencyExchangeRate: Record "Currency Exchange Rate"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); Currency.DeleteAll(); CurrencyExchangeRate.DeleteAll(); end; diff --git a/src/Apps/W1/APIV2/test/src/APIV2CustRetReasonsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2CustRetReasonsE2E.Codeunit.al index 5749e8a0fb7..3b82b54ce42 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2CustRetReasonsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2CustRetReasonsE2E.Codeunit.al @@ -22,6 +22,8 @@ codeunit 139869 "APIV2 - Cust. Ret. Reasons E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2CustomerPaymentsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2CustomerPaymentsE2E.Codeunit.al index b2e150e30af..1083e5c9a25 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2CustomerPaymentsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2CustomerPaymentsE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139840 "APIV2 - Customer Payments E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -769,10 +770,12 @@ codeunit 139840 "APIV2 - Customer Payments E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryTestInitialize.OnTestInitialize(Codeunit::"APIV2 - Customer Payments E2E"); - if not isInitialized then + if not isInitialized then begin isInitialized := true; + end; LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"APIV2 - Customer Payments E2E"); end; @@ -806,4 +809,3 @@ codeunit 139840 "APIV2 - Customer Payments E2E" exit(ServiceSubpageNameTxt + '(' + LibraryGraphMgt.StripBrackets(CustomerPaymentId) + ')'); end; } - diff --git a/src/Apps/W1/APIV2/test/src/APIV2CustomersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2CustomersE2E.Codeunit.al index 567d0166f0a..8e4df1d6f9e 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2CustomersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2CustomersE2E.Codeunit.al @@ -34,6 +34,8 @@ codeunit 139802 "APIV2 - Customers E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2DefaultDimensionsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2DefaultDimensionsE2E.Codeunit.al index 5a72973f69d..3822cca9f75 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2DefaultDimensionsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2DefaultDimensionsE2E.Codeunit.al @@ -35,6 +35,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the customer @@ -48,6 +49,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the vendor @@ -61,6 +63,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Item @@ -74,6 +77,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a Employee, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Employee @@ -87,6 +91,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the customer @@ -100,6 +105,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a Vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Vendor @@ -113,6 +119,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Item @@ -126,6 +133,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a Employee, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Employee @@ -139,6 +147,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the customer, with mismatching dimesnion and dimension value @@ -152,6 +161,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a Vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Vendor, with mismatching dimesnion and dimension value @@ -165,6 +175,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Item, with mismatching dimesnion and dimension value @@ -178,6 +189,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a Employee, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension on the Employee, with mismatching dimesnion and dimension value @@ -191,6 +203,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension on the customer @@ -204,6 +217,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a Vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension on the Vendor @@ -217,6 +231,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension on the Item @@ -230,6 +245,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a Employee, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension on the Employee @@ -243,6 +259,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension value on the customer @@ -256,6 +273,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a Vendor, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension value on the Vendor @@ -269,6 +287,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a Item, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension value on the Item @@ -282,6 +301,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a Employee, a dimension and a dimension value // [WHEN] The user posts a http request to create a default dimension with a blocked dimension value on the Employee @@ -295,6 +315,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to delete the default dimension on the customer @@ -308,6 +329,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a Vendor with a default dimension // [WHEN] The user posts a http request to delete a default dimension on the Vendor @@ -321,6 +343,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a Item with a default dimension // [WHEN] The user posts a http request to delete a default dimension on the Item @@ -334,6 +357,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a Employee with a default dimension // [WHEN] The user posts a http request to delete a default dimension on the Employee @@ -347,6 +371,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to get the default dimension on the customer @@ -360,6 +385,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a Vendor with a default dimension // [WHEN] The user posts a http request to get a default dimension on the Vendor @@ -373,6 +399,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a Item with a default dimension // [WHEN] The user posts a http request to get a default dimension on the Item @@ -386,6 +413,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a Employee with a default dimension // [WHEN] The user posts a http request to get a default dimension on the Employee @@ -399,6 +427,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to patch the default dimension on the customer @@ -412,6 +441,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a Vendor with a default dimension // [WHEN] The user posts a http request to patch a default dimension on the Vendor @@ -425,6 +455,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a Item with a default dimension // [WHEN] The user posts a http request to patch a default dimension on the Item @@ -438,6 +469,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a Employee with a default dimension // [WHEN] The user posts a http request to patch a default dimension on the Employee @@ -451,6 +483,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to patch the default dimension with a blocked dimension value on the customer @@ -464,6 +497,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a Vendor with a default dimension // [WHEN] The user posts a http request to patch a default dimension with a blocked dimension value on the Vendor @@ -477,6 +511,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a Item with a default dimension // [WHEN] The user posts a http request to patch a default dimension with a blocked dimension value on the Item @@ -490,6 +525,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a Employee with a default dimension // [WHEN] The user posts a http request to patch a default dimension with a blocked dimension value on the Employee @@ -503,6 +539,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Customer: Record "Customer"; begin + Initialize(); // [FEATURE] [Customer] // [GIVEN] a customer with a default dimension // [WHEN] The user posts a http request to patch the default dimension with a blocked dimension value on the customer @@ -516,6 +553,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Vendor: Record "Vendor"; begin + Initialize(); // [FEATURE] [Vendor] // [GIVEN] a vendor with a default dimension // [WHEN] The user posts a http request to patch the default dimension with a blocked dimension value on the vendor @@ -529,6 +567,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Item: Record "Item"; begin + Initialize(); // [FEATURE] [Item] // [GIVEN] a item with a default dimension // [WHEN] The user posts a http request to patch the default dimension with a blocked dimension value on the item @@ -542,6 +581,7 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" var Employee: Record "Employee"; begin + Initialize(); // [FEATURE] [Employee] // [GIVEN] a employee with a default dimension // [WHEN] The user posts a http request to patch the default dimension with a blocked dimension value on the employee @@ -561,6 +601,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" DimensionValueId: Text; ParentIdAsText: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); ParentIdAsText := LowerCase(Format(ParentId)); @@ -592,6 +634,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" DimensionId: Text; DimensionValueId: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); ParentIdAsText := LowerCase(Format(ParentId)); @@ -624,6 +668,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" DimensionId: Text; DimensionValue2Id: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); LibraryDimension.CreateDimension(Dimension2); @@ -653,6 +699,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" DimensionId: Text; DimensionValueId: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); Dimension.Validate(Blocked, true); @@ -682,6 +730,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" DimensionId: Text; DimensionValueId: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); DimensionValue.Validate(Blocked, true); @@ -711,6 +761,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" ParentIdAsText: Text; DimensionId: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); DefaultDimension.Validate("Table ID", TableNo); @@ -748,6 +800,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" DimensionId: Text; DimensionValueId: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); DefaultDimension.Validate("Table ID", TableNo); @@ -785,6 +839,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" DimensionId: Text; DimensionValue2Id: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); LibraryDimension.CreateDimensionValue(DimensionValue2, Dimension.Code); @@ -826,6 +882,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" DimensionId: Text; DimensionValue2Id: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); LibraryDimension.CreateDimensionValue(DimensionValue2, Dimension.Code); @@ -866,6 +924,8 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" ParentIdAsText: Text; DimensionId: Text; begin + Initialize(); + LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimension(Dimension2); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); @@ -975,4 +1035,9 @@ codeunit 139832 "APIV2 - Default Dimensions E2E" end; exit(DefaultDimensionParentType::" "); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2DimSetLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2DimSetLinesE2E.Codeunit.al index 503e68355db..0a36e614155 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2DimSetLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2DimSetLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -28,6 +29,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); end; [Test] @@ -38,6 +40,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" JournalName: Code[10]; JournalLineGUID: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in journal through a POST method and check if it was created LibraryGraphJournalLines.Initialize(); @@ -62,6 +65,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales order and a sales order line through a POST method and check if it was created // [GIVEN] A sales order LibrarySales.CreateSalesOrder(SalesHeader); @@ -90,6 +94,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineId: Guid; CustomerNo: Code[20]; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales quote and sales quote line through a POST method and check if it was created // [GIVEN] A sales quote LibrarySales.CreateCustomer(Customer); @@ -118,6 +123,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales credit memo and a sales cr memo line through a POST method and check if it was created // [GIVEN] A sales credit memo LibrarySales.CreateSalesCreditMemo(SalesHeader); @@ -144,6 +150,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales invoice and a sales invoice line through a POST method and check if it was created // [GIVEN] A sales invoice LibrarySales.CreateSalesInvoice(SalesHeader); @@ -170,6 +177,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a purchase invoice and a purchase invoice line through a POST method and check if it was created // [GIVEN] A purchase invoice LibraryPurchase.CreatePurchaseInvoice(PurchaseHeader); @@ -196,6 +204,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a purchase order and a purchase order line through a POST method and check if it was created // [GIVEN] A purchase order LibraryPurchase.CreatePurchaseOrder(PurchaseHeader); @@ -222,6 +231,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" DocumentRecordRef: RecordRef; TimeSheetDetailId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a time registration entry through a POST method and check if it was created // [GIVEN] A Time registration entry UserSetup.DeleteAll(); @@ -242,6 +252,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO] Creating a dimension line through a POST method without specifying a parent Id fails LibraryGraphJournalLines.Initialize(); @@ -273,6 +285,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Try to create a dimension line with an already existing code LibraryGraphJournalLines.Initialize(); @@ -318,6 +332,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" JournalName: Code[10]; JournalLineGUID: Guid; begin + Initialize(); // [SCENARIO] Create dimension lines in a journal line and use a GET method to retrieve them // [GIVEN] a journal in the General Journal Table LibraryGraphJournalLines.Initialize(); @@ -335,6 +350,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" SalesLine: Record "Sales Line"; LineId: Guid; begin + Initialize(); // [SCENARIO] Create dimension lines in a sales order and sales order line and use a GET method to retrieve them // [GIVEN] a sales order with lines LibrarySales.CreateSalesOrder(SalesHeader); @@ -358,6 +374,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" CustomerNo: Code[20]; LineId: Guid; begin + Initialize(); // [SCENARIO] Create dimension lines in a sales quote and sales quote line and use a GET method to retrieve them // [GIVEN] a sales quote with lines LibrarySales.CreateCustomer(Customer); @@ -381,6 +398,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" SalesLine: Record "Sales Line"; LineId: Guid; begin + Initialize(); // [SCENARIO] Create dimension lines in a sales cr memo and sales cr memo line and use a GET method to retrieve them // [GIVEN] a sales cr memo with lines LibrarySales.CreateSalesCreditMemo(SalesHeader); @@ -402,6 +420,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" SalesLine: Record "Sales Line"; LineId: Guid; begin + Initialize(); // [SCENARIO] Create dimension lines in a sales invoice and sales invoice line and use a GET method to retrieve them // [GIVEN] a sales invoice with lines LibrarySales.CreateSalesInvoice(SalesHeader); @@ -423,6 +442,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" PurchaseLine: Record "Purchase Line"; LineId: Guid; begin + Initialize(); // [SCENARIO] Create dimension lines in a pucrhase invoice and purchase invoice line and use a GET method to retrieve them // [GIVEN] a purchase invoice with lines LibraryPurchase.CreatePurchaseInvoice(PurchaseHeader); @@ -444,6 +464,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" PurchaseLine: Record "Purchase Line"; LineId: Guid; begin + Initialize(); // [SCENARIO] Create dimension lines in a pucrhase order and purchase order line and use a GET method to retrieve them // [GIVEN] a purchase order with lines LibraryPurchase.CreatePurchaseOrder(PurchaseHeader); @@ -467,6 +488,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" DocumentRecordRef: RecordRef; TimeSheetDetailId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a time registration entry through a POST method and and use a GET method to retrieve them // [GIVEN] A Time registration entry UserSetup.DeleteAll(); @@ -491,6 +513,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" TargetURL: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] Create a G/L Entry with dimenions after Posting Sales Invoice and use a GET method to retreive them // [GIVEN] Create Customer, Items and Sales Invoice for different Items. @@ -522,6 +546,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Using a GET request to retrieve dimension lines without a filter fails LibraryGraphJournalLines.Initialize(); @@ -544,6 +570,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" JournalName: Code[10]; JournalLineGUID: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line, use a PATCH method to change it and then verify the changes LibraryGraphJournalLines.Initialize(); @@ -565,6 +592,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales order and a sales order line, use a PATCH method to change it and then verify the changes // [GIVEN] A sales order LibrarySales.CreateSalesOrder(SalesHeader); @@ -593,6 +621,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineId: Guid; CustomerNo: Code[20]; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales quote and a sales quote line, use a PATCH method to change it and then verify the changes // [GIVEN] A sales quote LibrarySales.CreateCustomer(Customer); @@ -621,6 +650,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales credit memo and a sales cr memo line, use a PATCH method to change it and then verify the changes // [GIVEN] A sales credit memo LibrarySales.CreateSalesCreditMemo(SalesHeader); @@ -647,6 +677,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales invoice and a sales invoice line, use a PATCH method to change it and then verify the changes // [GIVEN] A sales invoice LibrarySales.CreateSalesInvoice(SalesHeader); @@ -673,6 +704,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a purchase invoice and a purchase invoice line, use a PATCH method to change it and then verify the changes // [GIVEN] A purchase invoice LibraryPurchase.CreatePurchaseInvoice(PurchaseHeader); @@ -699,6 +731,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a purchase order and a purchase order line, use a PATCH method to change it and then verify the changes // [GIVEN] A purchase order LibraryPurchase.CreatePurchaseOrder(PurchaseHeader); @@ -725,6 +758,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" DocumentRecordRef: RecordRef; TimeSheetDetailId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a time registration entry, use a PATCH method to change it and then verify the changes // [GIVEN] A Time registration entry UserSetup.DeleteAll(); @@ -745,6 +779,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a purchase credit memo and a purchase cr memo line through a POST method and check if it was created // [GIVEN] A purchase credit memo LibraryPurchase.CreatePurchaseCreditMemo(PurchaseHeader); @@ -769,6 +804,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" PurchaseLine: Record "Purchase Line"; LineId: Guid; begin + Initialize(); // [SCENARIO] Create dimension lines in a purchase cr memo and purchase cr memo line and use a GET method to retrieve them // [GIVEN] a purchase cr memo with lines LibraryPurchase.CreatePurchaseCreditMemo(PurchaseHeader); @@ -792,6 +828,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a purchase credit memo and a purchase cr memo line, use a PATCH method to change it and then verify the changes // [GIVEN] A purchase credit memo LibraryPurchase.CreatePurchaseCreditMemo(PurchaseHeader); @@ -818,6 +855,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a purchase credit memo and a purchase cr memo line, use a DELETE method to remove it and then verify the deletion // [GIVEN] A purchase credit memo LibraryPurchase.CreatePurchaseCreditMemo(PurchaseHeader); @@ -851,6 +889,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" TargetURL: Text; DimensionSetID: Integer; begin + Initialize(); + // [GIVEN] 2 dimension json texts LibraryDimension.CreateDimension(Dimension); DimensionCode := Dimension.Code; @@ -928,6 +968,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Try to change the code of an existing dimension line LibraryGraphJournalLines.Initialize(); @@ -978,6 +1020,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" JournalName: Code[10]; JournalLineGUID: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line, use a DELETE method to remove it and then verify the deletion LibraryGraphJournalLines.Initialize(); @@ -1000,6 +1043,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales order and a sales order, use a DELETE method to remove it and then verify the deletion // [GIVEN] A sales order LibrarySales.CreateSalesOrder(SalesHeader); @@ -1028,6 +1072,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineId: Guid; CustomerNo: Code[20]; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales quote and sales quote line, use a DELETE method to remove it and then verify the deletion // [GIVEN] A sales quote LibrarySales.CreateCustomer(Customer); @@ -1056,6 +1101,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales credit memo and a sales cr memo line, use a DELETE method to remove it and then verify the deletion // [GIVEN] A sales credit memo LibrarySales.CreateSalesCreditMemo(SalesHeader); @@ -1082,6 +1128,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a sales invoice and a sales invoice line, use a DELETE method to remove it and then verify the deletion // [GIVEN] A sales invoice LibrarySales.CreateSalesInvoice(SalesHeader); @@ -1108,6 +1155,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a purchase invoice and a purchase invoice line, use a DELETE method to remove it and then verify the deletion LibraryPurchase.CreatePurchaseInvoice(PurchaseHeader); DocumentRecordRef.GetTable(PurchaseHeader); @@ -1133,6 +1181,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" LineRecordRef: RecordRef; LineId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a purchase order and a purchase order, use a DELETE method to remove it and then verify the deletion // [GIVEN] A purchase order LibraryPurchase.CreatePurchaseOrder(PurchaseHeader); @@ -1157,6 +1206,7 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" DocumentRecordRef: RecordRef; TimeSheetDetailId: Guid; begin + Initialize(); // [SCENARIO] Create a dimension line in a time registration entry, use a DELETE method to remove it and then verify the deletion // [GIVEN] A Time registration entry TimeSheetDetailId := CreateTimeSheet(); @@ -1179,6 +1229,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [GIVEN] a dimension line in the journal line LibraryDimension.CreateDimension(Dimension); DimensionValue.Reset(); @@ -1240,6 +1292,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [GIVEN] a dimension line in the journal line LibraryDimension.CreateDimension(Dimension); DimensionValue.Reset(); @@ -1296,6 +1350,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [GIVEN] a dimension with a value LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); @@ -1357,6 +1413,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [GIVEN] a dimension with a value LibraryDimension.CreateDimension(Dimension); LibraryDimension.CreateDimensionValue(DimensionValue, Dimension.Code); @@ -1406,6 +1464,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [GIVEN] 2 dimensions with dimension values LibraryDimension.CreateDimension(Dimension); DimensionCode[2] := Dimension.Code; @@ -1450,6 +1510,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [GIVEN] 2 dimensions with dimension values LibraryDimension.CreateDimension(Dimension); DimensionCode[2] := Dimension.Code; @@ -1501,6 +1563,8 @@ codeunit 139825 "APIV2 - Dim. Set Lines E2E" TargetURL: Text; DimensionSetID: Integer; begin + Initialize(); + // [GIVEN] 2 dimension json texts LibraryDimension.CreateDimension(Dimension); DimensionCode := Dimension.Code; diff --git a/src/Apps/W1/APIV2/test/src/APIV2DimensionsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2DimensionsE2E.Codeunit.al index 9b14ca531ea..52f23aabd95 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2DimensionsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2DimensionsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139824 "APIV2 - Dimensions E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -20,6 +21,8 @@ codeunit 139824 "APIV2 - Dimensions E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -136,4 +139,3 @@ codeunit 139824 "APIV2 - Dimensions E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2DocumentAttachE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2DocumentAttachE2E.Codeunit.al index d38126db6a0..81f6deb7db2 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2DocumentAttachE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2DocumentAttachE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139899 "APIV2 - Document Attach. E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -32,6 +33,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table LibrarySales.CreateCustomer(Customer); @@ -56,6 +59,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table LibrarySmallBusiness.CreateItem(Item); @@ -80,6 +85,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table LibraryHumanResources.CreateEmployee(Employee); @@ -104,6 +111,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table LibraryJob.CreateJob(Job); @@ -128,6 +137,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table LibrarySmallBusiness.CreateVendor(Vendor); @@ -152,6 +163,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); @@ -174,6 +187,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table CreateDraftSalesInvoice(DocumentRecordRef); @@ -197,6 +212,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table CreatePostedPurchaseInvoice(DocumentRecordRef, DocumentId); @@ -219,6 +236,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table CreateDraftPurchaseInvoice(DocumentRecordRef); @@ -241,6 +260,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table CreateSalesQuote(DocumentRecordRef); @@ -264,6 +285,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Document Attachment table CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); @@ -286,6 +309,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Document Attachment table CreateDraftSalesInvoice(DocumentRecordRef); @@ -308,6 +333,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Document Attachment table CreateDraftSalesOrder(DocumentRecordRef); @@ -330,6 +357,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve the Attachment record from the Attachment API. // [GIVEN] Attachment exists in the Document Attachment table CreateSalesQuote(DocumentRecordRef); @@ -352,6 +381,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table CreateDraftPurchaseOrder(DocumentRecordRef); @@ -379,6 +410,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ExpectedBase64Content: Text; ActualBase64Content: Text; begin + Initialize(); + // [SCENARIO] User can update linked attachment binary content through the Attachment API. // [GIVEN] A linked attachment exists LibrarySmallBusiness.CreateCustomer(Customer); @@ -407,6 +440,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" Customer: Record Customer; DocumentRecordRef: RecordRef; begin + Initialize(); + LibrarySmallBusiness.CreateCustomer(Customer); DocumentRecordRef.GetTable(Customer); TestCreateAttachment(DocumentRecordRef); @@ -418,6 +453,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" Vendor: Record Vendor; DocumentRecordRef: RecordRef; begin + Initialize(); + LibrarySmallBusiness.CreateVendor(Vendor); DocumentRecordRef.GetTable(Vendor); TestCreateAttachment(DocumentRecordRef); @@ -430,6 +467,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" DocumentId: Guid; DocumentType: Text; begin + Initialize(); + CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); DocumentType := GetDocumentType(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef, DocumentId, DocumentType); @@ -440,6 +479,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftSalesInvoice(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -449,6 +490,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftSalesOrder(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -460,6 +503,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" DocumentId: Guid; DocumentType: Text; begin + Initialize(); + CreatePostedPurchaseInvoice(DocumentRecordRef, DocumentId); DocumentType := GetDocumentType(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef, DocumentId, DocumentType); @@ -470,6 +515,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseInvoice(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -479,6 +526,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseOrder(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -530,6 +579,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateSalesQuote(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -540,6 +591,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" Vendor: Record Vendor; DocumentRecordRef: RecordRef; begin + Initialize(); + LibrarySmallBusiness.CreateVendor(Vendor); DocumentRecordRef.GetTable(Vendor); CreateAttachment(DocumentRecordRef); @@ -552,6 +605,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" Employee: Record Employee; DocumentRecordRef: RecordRef; begin + Initialize(); + LibraryHumanResources.CreateEmployee(Employee); DocumentRecordRef.GetTable(Employee); CreateAttachment(DocumentRecordRef); @@ -564,6 +619,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" Job: Record Job; DocumentRecordRef: RecordRef; begin + Initialize(); + LibraryJob.CreateJob(Job); DocumentRecordRef.GetTable(Job); CreateAttachment(DocumentRecordRef); @@ -576,6 +633,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedSalesInvoice(DocumentRecordRef, DocumentId); TestDeleteAttachment2(DocumentRecordRef); end; @@ -585,6 +644,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftSalesInvoice(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -595,6 +656,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedPurchaseInvoice(DocumentRecordRef, DocumentId); TestDeleteAttachment2(DocumentRecordRef); end; @@ -604,6 +667,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseInvoice(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -613,6 +678,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateSalesQuote(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -625,6 +692,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table CreateDraftPurchaseCreditMemo(DocumentRecordRef); @@ -648,6 +717,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can retrieve all records from the Attachments API. // [GIVEN] 2 Attachments in the Document Attachment table CreatePostedPurchaseCreditMemo(DocumentRecordRef, DocumentId); @@ -667,6 +738,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseCreditMemo(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef); end; @@ -678,6 +751,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" DocumentId: Guid; DocumentType: Text; begin + Initialize(); + CreatePostedPurchaseCreditMemo(DocumentRecordRef, DocumentId); DocumentType := GetDocumentType(DocumentRecordRef); TestCreateAttachment(DocumentRecordRef, DocumentId, DocumentType); @@ -688,6 +763,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" var DocumentRecordRef: RecordRef; begin + Initialize(); + CreateDraftPurchaseCreditMemo(DocumentRecordRef); TestDeleteAttachment(DocumentRecordRef); end; @@ -698,6 +775,8 @@ codeunit 139899 "APIV2 - Document Attach. E2E" DocumentRecordRef: RecordRef; DocumentId: Guid; begin + Initialize(); + CreatePostedPurchaseCreditMemo(DocumentRecordRef, DocumentId); TestDeleteAttachment2(DocumentRecordRef); end; @@ -1035,4 +1114,9 @@ codeunit 139899 "APIV2 - Document Attach. E2E" exit(StrSubstNo('%1.%2', Name, Extension)); exit(Name); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2EmployeesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2EmployeesE2E.Codeunit.al index 9dca78748ec..3d4580e9e46 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2EmployeesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2EmployeesE2E.Codeunit.al @@ -25,6 +25,8 @@ codeunit 139822 "APIV2 - Employees E2E" var LibraryApplicationArea: Codeunit "Library - Application Area"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + LibraryApplicationArea.EnableBasicHRSetup(); // Lazy Setup. @@ -223,4 +225,3 @@ codeunit 139822 "APIV2 - Employees E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2FALocationsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2FALocationsE2E.Codeunit.al index 9a23cb8f5c7..33d9fd7564b 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2FALocationsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2FALocationsE2E.Codeunit.al @@ -21,6 +21,8 @@ codeunit 139906 "APIV2 - FA Locations E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2FixedAssetsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2FixedAssetsE2E.Codeunit.al index 3efd9d6a789..e6ecd5097e4 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2FixedAssetsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2FixedAssetsE2E.Codeunit.al @@ -23,6 +23,8 @@ codeunit 139907 "APIV2 - Fixed Assets E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2GLEntriesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2GLEntriesE2E.Codeunit.al index bb7b691b29f..42290b56b05 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2GLEntriesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2GLEntriesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139830 "APIV2 - GLEntries E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -24,6 +25,8 @@ codeunit 139830 "APIV2 - GLEntries E2E" LibraryERMCountryData: Codeunit "Library - ERM Country Data"; LibraryApplicationArea: Codeunit "Library - Application Area"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + LibraryApplicationArea.EnableFoundationSetup(); if IsInitialized then exit; @@ -161,5 +164,3 @@ codeunit 139830 "APIV2 - GLEntries E2E" - - diff --git a/src/Apps/W1/APIV2/test/src/APIV2GLSetupE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2GLSetupE2E.Codeunit.al index 187cb7f3af7..810fbb556c7 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2GLSetupE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2GLSetupE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139860 "APIV2 - G/L Setup E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; var Assert: Codeunit "Assert"; @@ -13,6 +14,8 @@ codeunit 139860 "APIV2 - G/L Setup E2E" GeneralLedgerSetup: Record "General Ledger Setup"; Response, TargetURL : Text; begin + Initialize(); + GeneralLedgerSetup.Get(); TargetURL := LibraryGraphMgt.CreateTargetURL('', Page::"APIV2 - G/L Setup", ServiceNameTxt); LibraryGraphMgt.GetFromWebService(Response, TargetURL); @@ -60,4 +63,9 @@ codeunit 139860 "APIV2 - G/L Setup E2E" Assert.AreEqual(GeneralLedgerSetup."Shortcut Dimension 8 Code", PropertyJsonToken.AsValue().AsText(), 'Expected the same shortcutDimension8Code for generalLedgerSetup'); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } \ No newline at end of file diff --git a/src/Apps/W1/APIV2/test/src/APIV2GenProdPostGroupE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2GenProdPostGroupE2E.Codeunit.al index 6120bf37cdd..aee0369473a 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2GenProdPostGroupE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2GenProdPostGroupE2E.Codeunit.al @@ -1,12 +1,9 @@ codeunit 139856 "APIV2 - GenProdPostGroup E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; - trigger OnRun() - begin - end; - var ERMVATToolHelper: Codeunit "ERM VAT Tool - Helper"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; @@ -21,6 +18,8 @@ codeunit 139856 "APIV2 - GenProdPostGroup E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [SCENARIO] Create a General Product Posting Group and use a GET method to retrieve it // [GIVEN] A Gen. Prod. Post. Group ERMVATToolHelper.CreateGenProdPostingGroup(GenProductPostingGroup, true); @@ -41,4 +40,9 @@ codeunit 139856 "APIV2 - GenProdPostGroup E2E" end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } \ No newline at end of file diff --git a/src/Apps/W1/APIV2/test/src/APIV2IncomeStatementE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2IncomeStatementE2E.Codeunit.al index 94109479bc6..d22ae4175e2 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2IncomeStatementE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2IncomeStatementE2E.Codeunit.al @@ -62,6 +62,8 @@ codeunit 139816 "APIV2 - Income Statement E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -88,4 +90,3 @@ codeunit 139816 "APIV2 - Income Statement E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2InventoryPostGroupE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2InventoryPostGroupE2E.Codeunit.al index 3f357b613b8..f9189eef277 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2InventoryPostGroupE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2InventoryPostGroupE2E.Codeunit.al @@ -1,11 +1,8 @@ codeunit 139857 "APIV2 - InventoryPostGroup E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; - trigger OnRun() - begin - end; - var LibraryInventory: Codeunit "Library - Inventory"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; @@ -21,6 +18,8 @@ codeunit 139857 "APIV2 - InventoryPostGroup E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [SCENARIO] Create an Inventory Posting Group and use a GET to retrieve it // [GIVEN] An Inventory Posting Group LibraryInventory.CreateInventoryPostingGroup(InventoryPostingGroup); @@ -40,4 +39,9 @@ codeunit 139857 "APIV2 - InventoryPostGroup E2E" 'Could not find created Inventory Posting Group on the response'); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } \ No newline at end of file diff --git a/src/Apps/W1/APIV2/test/src/APIV2ItemCategoriesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ItemCategoriesE2E.Codeunit.al index 48a2175efe0..bf55f5936a1 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ItemCategoriesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ItemCategoriesE2E.Codeunit.al @@ -155,6 +155,8 @@ codeunit 139807 "APIV2 - Item Categories E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -231,4 +233,3 @@ codeunit 139807 "APIV2 - Item Categories E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2ItemVariantsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ItemVariantsE2E.Codeunit.al index 2850134d790..7892406ba53 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ItemVariantsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ItemVariantsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139839 "APIV2 - Item Variants E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -20,6 +21,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create an item variant through a POST method and check if it was created // [GIVEN] a JSON text with an item variant with itemId CreateItem(Item); @@ -44,6 +47,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Cannot create an Item Variant with non-existing itemId // [GIVEN] a JSON text with an item variant with non-existing itemId ItemId := CreateGuid(); @@ -65,6 +70,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create an item variant through a POST method and check if it was created // [GIVEN] a JSON text with an item variant with itemNumber CreateItem(Item); @@ -90,6 +97,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Cannot create an Item Variant with non-existing itemNumber // [GIVEN] a JSON text with an item variant with non-existing itemNumber ItemNo := LibraryUtility.GenerateRandomCode(ItemVariant.FieldNo(Code), Database::"Item Variant"); @@ -111,6 +120,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create an item variant through a POST method and check if it was created // [GIVEN] a JSON text with an item variant with itemNumber and itemId CreateItem(Item); @@ -136,6 +147,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Cannot create an Item Variant with mismatching itemNumber and itemId // [GIVEN] a JSON text with an item variant with mismatching itemNumber and itemId CreateItem(Item1); @@ -159,6 +172,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Cannot create an Item Variant if there is an item variant with same itemNumber and code // [GIVEN] a JSON text with an item variant with same itemNumber and code CreateItem(Item); @@ -181,6 +196,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Get a simple customer with a GET request to the service. // [GIVEN] An item variant exists in the system CreateItem(Item); @@ -206,6 +223,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create an item variant, use a PATCH method to change it and then verify the changes // [GIVEN] an item variant exists in the system CreateItem(Item); @@ -238,6 +257,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create an item variant, use a PATCH method to change it and then verify the changes // [GIVEN] an item variant exists in the system CreateItem(Item1); @@ -271,6 +292,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create an item variant, use a PATCH method to change it and then verify the changes // [GIVEN] an item variant exists in the system CreateItem(Item1); @@ -300,6 +323,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create an item variant, use a DELETE method to remove it and then verify the deletion // [GIVEN] an item variant in the system CreateItem(Item); @@ -326,6 +351,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Cannot delete an item variant in use // [GIVEN] an item variant in the system and used in a sales order line LibraryInventory.CreateItem(Item); @@ -342,6 +369,7 @@ codeunit 139839 "APIV2 - Item Variants E2E" var LibraryGraphMgt: Codeunit "Library - Graph Mgt"; + LibraryGraphDocumentTools: Codeunit "Library - Graph Document Tools"; LibraryUtility: Codeunit "Library - Utility"; LibraryRandom: Codeunit "Library - Random"; LibraryInventory: Codeunit "Library - Inventory"; @@ -425,6 +453,8 @@ codeunit 139839 "APIV2 - Item Variants E2E" LibrarySales: Codeunit "Library - Sales"; begin LibrarySales.CreateSalesOrder(SalesHeader); + LibraryGraphDocumentTools.EnsureVATPostingSetupExists( + SalesHeader."VAT Bus. Posting Group", Item."VAT Prod. Posting Group"); LibrarySales.CreateSalesLine(SalesLine, SalesHeader, SalesLine.Type::Item, Item."No.", 2); SalesLine."Variant Code" := ItemVariant.Code; SalesLine.Modify(); @@ -440,4 +470,9 @@ codeunit 139839 "APIV2 - Item Variants E2E" exit(CopyStr('GRAPHITEM' + '00001', 1, 20)); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2ItemsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ItemsE2E.Codeunit.al index 98f53fcb285..037dc6d9f58 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ItemsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ItemsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139800 "APIV2 - Items E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -30,6 +31,8 @@ codeunit 139800 "APIV2 - Items E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -936,8 +939,6 @@ codeunit 139800 "APIV2 - Items E2E" - - diff --git a/src/Apps/W1/APIV2/test/src/APIV2JobQueueEntriesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2JobQueueEntriesE2E.Codeunit.al index fd33be96961..8311d92ab03 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2JobQueueEntriesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2JobQueueEntriesE2E.Codeunit.al @@ -25,6 +25,8 @@ codeunit 139862 "APIV2JobQueueEntriesE2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO] Create 1 JobQueueEntry and use a GET method to retrieve it· // [GIVEN] Clean Job Queue Entries and create a new JobQueueEntry JobQueueEntry.DeleteAll(); @@ -51,6 +53,8 @@ codeunit 139862 "APIV2JobQueueEntriesE2E" ResponseText: Text; JobQueueEntryJSON: Text; begin + Initialize(); + // [SCENARIO] Create 1 JobQueueEntry and use a GET method to retrieve it. // [GIVEN] Clean Job Queue Entries and create a new JobQueueEntry and one corresponding JobQueueLogEntry JobQueueEntry.DeleteAll(); @@ -79,6 +83,8 @@ codeunit 139862 "APIV2JobQueueEntriesE2E" ResponseText: Text; JobQueueLogEntryJSON: Text; begin + Initialize(); + // [SCENARIO] Create 1 JobQueueEntry with 2 corresponding JobQueueLogEntries and use a GET method to retrieve it. // [GIVEN] Clean Job Queue Entries and create a new JobQueueEntry and 3 corresponding JobQueueLogEntries JobQueueEntry.DeleteAll(); @@ -105,6 +111,8 @@ codeunit 139862 "APIV2JobQueueEntriesE2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO] Create 1 JobQueueEntry with status error. Use an action to reschedule the JobQueueEntry // [GIVEN] Clean Job Queue Entries and create a new JobQueueEntry with status error JobQueueEntry.DeleteAll(); @@ -201,4 +209,9 @@ codeunit 139862 "APIV2JobQueueEntriesE2E" until (Index = LibraryGraphMgt.GetCollectionCountFromJSON(JobQueueLogEntryJSON)); Assert.AreEqual(Count, Index, 'The number of Job Queue Log Entries is wrong.'); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2JobQueueLogEntriesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2JobQueueLogEntriesE2E.Codeunit.al index 85e8931992b..4eedd7aed15 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2JobQueueLogEntriesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2JobQueueLogEntriesE2E.Codeunit.al @@ -21,6 +21,8 @@ codeunit 139861 "APIV2JobQueueLogEntriesE2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO] Use a GET method to retrieve Job Queue Log Entries // [GIVEN] A new Job Queue Log Entry created JobQueueLogEntry.DeleteAll(); @@ -63,4 +65,9 @@ codeunit 139861 "APIV2JobQueueLogEntriesE2E" JobQueueLogEntry.Insert(); exit(JobQueueLogEntry); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2JournalsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2JournalsE2E.Codeunit.al index 5d6b35a0891..2c8c343d2a5 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2JournalsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2JournalsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139827 "APIV2 - Journals E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -32,6 +33,8 @@ codeunit 139827 "APIV2 - Journals E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -190,6 +193,8 @@ codeunit 139827 "APIV2 - Journals E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [GIVEN] A general journal batch with a general journal line BalAccountNo := LibraryERM.CreateGLAccountNoWithDirectPosting(); BalAccountType := GenJournalLine."Bal. Account Type"::"G/L Account"; @@ -272,4 +277,3 @@ codeunit 139827 "APIV2 - Journals E2E" GenJournalBatch.Modify(true); end; } - diff --git a/src/Apps/W1/APIV2/test/src/APIV2LocationsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2LocationsE2E.Codeunit.al index 667ae62e2f1..a75ccee71fc 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2LocationsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2LocationsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139868 "APIV2 - Locations E2E" // version Test,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -24,6 +25,8 @@ codeunit 139868 "APIV2 - Locations E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2OpportunitiesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2OpportunitiesE2E.Codeunit.al index 50b6a4c45dd..0f968135abf 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2OpportunitiesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2OpportunitiesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139855 "APIV2 - Opportunities E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -31,6 +32,8 @@ codeunit 139855 "APIV2 - Opportunities E2E" ResponseText: Text; OpportunityId: Text; begin + Initialize(); + // [SCENARIO] Create an opportunity and use a GET method to retrieve them // [GIVEN] An opportunity ContactNo := LibraryMarketing.CreateCompanyContactNo(); @@ -60,6 +63,8 @@ codeunit 139855 "APIV2 - Opportunities E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO 184721] Create an opportunity through a POST method and check if it was created // [GIVEN] a JSON text with an Opportunity only with a Description property OpportunityJSON := CreateMinimalOpportunityJSON(OpportunityDescription); @@ -85,6 +90,8 @@ codeunit 139855 "APIV2 - Opportunities E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO 184721] Create an opportunity through a POST method and check if it was created // [GIVEN] a JSON text with an Opportunity only with a contact no ContactNo := LibraryMarketing.CreateCompanyContactNo(); @@ -125,6 +132,8 @@ codeunit 139855 "APIV2 - Opportunities E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO 184721] Create an opportunity through a POST method // [GIVEN] a JSON text with an Opportunity only with a contact number that does not exist ContactNo := 'wrongContNo'; @@ -146,6 +155,8 @@ codeunit 139855 "APIV2 - Opportunities E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO 184721] Create an opportunity through a POST method // [GIVEN] a JSON text with an Opportunity only with a salesperson number that does not exist SalespersonNo := 'wrongSPNo'; @@ -169,6 +180,8 @@ codeunit 139855 "APIV2 - Opportunities E2E" ResponseText: Text; OpportunityId: Guid; begin + Initialize(); + // [SCENARIO] Use a PATCH method to change the description of an opportunity // [GIVEN] An opportunity ContactNo := LibraryMarketing.CreateCompanyContactNo(); @@ -199,6 +212,8 @@ codeunit 139855 "APIV2 - Opportunities E2E" ResponseText: Text; OpportunityId: Guid; begin + Initialize(); + // [SCENARIO] Use a PATCH method to change the contact no of a Won opportunity // [GIVEN] An won opportunity CompanyContactNo := LibraryMarketing.CreateCompanyContactNo(); @@ -228,6 +243,8 @@ codeunit 139855 "APIV2 - Opportunities E2E" ResponseText: Text; OpportunityId: Guid; begin + Initialize(); + // [SCENARIO] Use a PATCH method to change the salesperson code of a Won opportunity // [GIVEN] An won opportunity SalesPersonCode := CreateSalesperson(SalespersonPurchaser); @@ -256,6 +273,8 @@ codeunit 139855 "APIV2 - Opportunities E2E" ResponseText: Text; OpportunityId: Guid; begin + Initialize(); + // [SCENARIO] Use a PATCH method to change the contact no of an opportunity in progress to a contact of a different company // [GIVEN] An won opportunity CompanyContactNo1 := LibraryMarketing.CreateCompanyContactNo(); @@ -408,4 +427,9 @@ codeunit 139855 "APIV2 - Opportunities E2E" Opportunity.SetRange(Description, DescriptionValue); Assert.IsFalse(Opportunity.IsEmpty(), 'Opportunity does not exist'); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2PDFDocumentE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PDFDocumentE2E.Codeunit.al index 63c5aabb741..6d30a564f20 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PDFDocumentE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PDFDocumentE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139841 "APIV2 - PDF Document E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -26,6 +27,7 @@ codeunit 139841 "APIV2 - PDF Document E2E" var CompanyInformation: Record "Company Information"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); CompanyInformation.Get(); if CompanyInformation."Giro No." = '' then CompanyInformation."Giro No." := '1234567'; @@ -381,4 +383,3 @@ codeunit 139841 "APIV2 - PDF Document E2E" Commit(); end; } - diff --git a/src/Apps/W1/APIV2/test/src/APIV2PaymentMethodsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PaymentMethodsE2E.Codeunit.al index ca63c08260f..29e8b14e1c8 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PaymentMethodsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PaymentMethodsE2E.Codeunit.al @@ -155,6 +155,8 @@ codeunit 139814 "APIV2 - Payment Methods E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -231,4 +233,3 @@ codeunit 139814 "APIV2 - Payment Methods E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2PaymentTermsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PaymentTermsE2E.Codeunit.al index 0e56cd7e8dc..f2a0eb2565b 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PaymentTermsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PaymentTermsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139804 "APIV2 - Payment Terms E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -19,6 +20,8 @@ codeunit 139804 "APIV2 - Payment Terms E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -97,4 +100,3 @@ codeunit 139804 "APIV2 - Payment Terms E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2PicturesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PicturesE2E.Codeunit.al index 317006420bd..baca3f2b57f 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PicturesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PicturesE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139842 "APIV2 - Pictures E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -29,6 +30,8 @@ codeunit 139842 "APIV2 - Pictures E2E" [Scope('OnPrem')] procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -44,6 +47,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobExpected: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Customer] // [SCENARIO] Get value picture from Customer Record @@ -68,6 +73,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Customer] // [SCENARIO] Get a picture metadata from Customer Record @@ -91,6 +98,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobResponse: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Customer] // [SCENARIO] Get value picture from Customer Record when no image exist @@ -112,6 +121,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Customer] // [SCENARIO] Get a picture metadata from Customer Record when no image is present @@ -137,6 +148,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Customer] // [SCENARIO] Set Picture on a customer without picture @@ -169,6 +182,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Customer] // [SCENARIO] Replace the Picture on a customer @@ -200,6 +215,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Customer] // [SCENARIO] Replace the Picture on a customer @@ -227,6 +244,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobExpected: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Vendor] // [SCENARIO] Get value picture from Vendor Record @@ -251,6 +270,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Vendor] // [SCENARIO] Get a picture metadata from Vendor Record @@ -274,6 +295,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobResponse: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Vendor] // [SCENARIO] Get value picture from Vendor Record when no image exist @@ -295,6 +318,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Vendor] // [SCENARIO] Get a picture metadata from Vendor Record when no image is present @@ -320,6 +345,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Vendor] // [SCENARIO] Set Picture on a Vendor without picture @@ -352,6 +379,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Vendor] // [SCENARIO] Replace the Picture on a Vendor @@ -383,6 +412,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Vendor] // [SCENARIO] Replace the Picture on a Vendor @@ -410,6 +441,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobExpected: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Employee] // [SCENARIO] Get value picture from Employee Record @@ -434,6 +467,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Employee] // [SCENARIO] Get a picture metadata from Employee Record @@ -457,6 +492,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobResponse: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Employee] // [SCENARIO] Get value picture from Employee Record when no image exist @@ -478,6 +515,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Employee] // [SCENARIO] Get a picture metadata from Employee Record when no image is present @@ -503,6 +542,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Employee] // [SCENARIO] Set Picture on a Employee without picture @@ -535,6 +576,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Employee] // [SCENARIO] Replace the Picture on a Employee @@ -566,6 +609,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Employee] // [SCENARIO] Replace the Picture on a Employee @@ -593,6 +638,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobExpected: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Item] // [SCENARIO] Get value picture from Item Record @@ -617,6 +664,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Item] // [SCENARIO] Get a picture metadata from Item Record @@ -640,6 +689,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobResponse: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Item] // [SCENARIO] Get value picture from Item Record when no image exist @@ -661,6 +712,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Item] // [SCENARIO] Get a picture metadata from Item Record when no image is present @@ -686,6 +739,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Item] // [SCENARIO] Set Picture on a Item without picture @@ -718,6 +773,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Item] // [SCENARIO] Replace the Picture on a Item @@ -749,6 +806,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Item] // [SCENARIO] Replace the Picture on a Item @@ -776,6 +835,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobExpected: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Contact] // [SCENARIO] Get value picture from Contact Record @@ -800,6 +861,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Contact] // [SCENARIO] Get a picture metadata from Contact Record @@ -823,6 +886,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TempBlobResponse: Codeunit "Temp Blob"; TargetURL: Text; begin + Initialize(); + // [FEATURE] [Contact] // [SCENARIO] Get value picture from Contact Record when no image exist @@ -844,6 +909,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Contact] // [SCENARIO] Get a picture metadata from Contact Record when no image is present @@ -869,6 +936,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Contact] // [SCENARIO] Set Picture on a contact without picture @@ -901,6 +970,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Contact] // [SCENARIO] Replace the Picture on a contact @@ -932,6 +1003,8 @@ codeunit 139842 "APIV2 - Pictures E2E" TargetURL: Text; Response: Text; begin + Initialize(); + // [FEATURE] [Contact] // [SCENARIO] Replace the Picture on a contact @@ -1102,4 +1175,3 @@ codeunit 139842 "APIV2 - Pictures E2E" end; } - diff --git a/src/Apps/W1/APIV2/test/src/APIV2PstdApprovalEntriesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PstdApprovalEntriesE2E.Codeunit.al index 8db85c18246..edc4bf87fff 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PstdApprovalEntriesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PstdApprovalEntriesE2E.Codeunit.al @@ -21,6 +21,8 @@ codeunit 139919 "APIV2 PstdApprovalEntries E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO] Check that posted approval entries can be retrieved via API // [GIVEN] a Sales order exists @@ -60,4 +62,8 @@ codeunit 139919 "APIV2 PstdApprovalEntries E2E" PostedApprovalEntry.Insert(); end; + + local procedure Initialize() + begin + end; } \ No newline at end of file diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchCrMLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchCrMLinesE2E.Codeunit.al index 71212c1efab..980ea545d06 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchCrMLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchCrMLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -30,6 +31,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Call GET on the lines without providing a parent Credit Memo ID. // [GIVEN] the credit memo API exposedSetAutoCalcFields @@ -56,6 +59,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" LineNo: Integer; SequenceValue: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Line of a credit memo // [GIVEN] a credit memo with a line.SetAutoCalcFields CreditMemoId := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -86,6 +91,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" LineNo1: Text; LineNo2: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Lines of a unposted Credit Memo // [GIVEN] An credit memo with lines.SetAutoCalcFields CreditMemoID := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -115,6 +122,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" LineNo1: Text; LineNo2: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Lines of a credit memo // [GIVEN] a credit memo with lines.SetAutoCalcFields CreditMemoId := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -144,6 +153,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" LineNo1: Text; LineNo2: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Lines of a posted Credit Memo // [GIVEN] A posted credit memo with lines.SetAutoCalcFields CreditMemoID := CreatePostedPurchaseCreditMemoWithLines(PurchCrMemoHdr); @@ -172,6 +183,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoID: Text; LineNo: Integer; begin + Initialize(); + // [SCENARIO] POST a new line to an unposted Credit Memo // [GIVEN] An existing unposted credit memo and a valid JSON describing the new credit memo lineSetAutoCalcFields CreditMemoID := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -203,6 +216,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoID: Text; LineNo: Integer; begin + Initialize(); + // [SCENARIO] POST a new line to an unposted Credit Memo with a sequence number // [GIVEN] An existing unposted credit memo and a valid JSON describing the new credit memo lineSetAutoCalcFields CreditMemoID := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -241,6 +256,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" PurchaseQuantity: Integer; PurchaseQuantityFromJSON: Text; begin + Initialize(); + // [SCENARIO] PATCH a line of an unposted Credit Memo // [GIVEN] An unposted credit memo with lines and a valid JSON describing the fields that we want to changeSetAutoCalcFields CreditMemoID := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -278,6 +295,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoId: Text; NewSequence: Integer; begin + Initialize(); + // [SCENARIO] PATCH a line of a credit memo will fail if sequence is modified // [GIVEN] A credit memo with lines and a valid JSON describing the fields that we want to changeSetAutoCalcFields CreditMemoId := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -318,6 +337,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoID: Text; LineNo: Integer; begin + Initialize(); + // [SCENARIO] DELETE a line from an unposted Credit Memo // [GIVEN] An unposted credit memo with linesSetAutoCalcFields CreditMemoID := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -348,6 +369,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoID: Text; LineNo: Integer; begin + Initialize(); + // [SCENARIO] Call DELETE on a line of a posted Credit Memo // [GIVEN] A posted credit memo with linesSetAutoCalcFields CreditMemoID := CreatePostedPurchaseCreditMemoWithLines(PurchCrMemoHdr); @@ -384,6 +407,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" ItemNo: Code[20]; VendorNo: Code[20]; begin + Initialize(); + // [SCENARIO] Create an credit memo both through the client UI and through the API and compare their final values. // [GIVEN] An unposted credit memo and a JSON describing the line we want to create LibraryPurchase.CreateVendor(Vendor); @@ -422,6 +447,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" ResponseText: Text; LinesJSON: Text; begin + Initialize(); + // [SCENARIO] Getting a line through API lists all possible types // [GIVEN] An credit memo with lines of different typesSetAutoCalcFields CreateCreditMemoWithDifferentLineTypes(PurchaseHeader, ExpectedNumberOfLines); @@ -447,6 +474,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" ResponseText: Text; CreditMemoLineJSON: Text; begin + Initialize(); + // [SCENARIO] Posting a line with description only will get a type item // [GIVEN] A post request with description onlySetAutoCalcFields CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -482,6 +511,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" ResponseText: Text; CreditMemoLineJSON: Text; begin + Initialize(); + // [FEATURE] [Comment] // [SCENARIO] Posting a line with Type Comment and description will make a comment line // [GIVEN] A post request with type and descriptionSetAutoCalcFields @@ -520,6 +551,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoLineJSON: Text; CreditMemoID: Text; begin + Initialize(); + // [SCENARIO] PATCH a Type on a line of an unposted Credit Memo // [GIVEN] An unposted credit memo with lines and a valid JSON describing the fields that we want to changeSetAutoCalcFields CreditMemoID := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -551,6 +584,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoLineJSON: Text; CreditMemoLineID: Text; begin + Initialize(); + // [SCENARIO] PATCH a Type on a line of an unposted Credit Memo // [GIVEN] An unposted credit memo with lines and a valid JSON describing the fields that we want to changeSetAutoCalcFields CreateCreditMemoWithDifferentLineTypes(PurchaseHeader, ExpectedNumberOfLines); @@ -588,6 +623,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoLineJSON: Text; CreditMemoID: Text; begin + Initialize(); + // [SCENARIO] PATCH a Type on a line of an unposted Credit Memo // [GIVEN] An unposted credit memo with lines and a valid JSON describing the fields that we want to changeSetAutoCalcFields CreditMemoID := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -622,6 +659,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoID: Text; LineNo: Integer; begin + Initialize(); + // [SCENARIO] POST a new line to an unposted Credit Memo with item variant // [GIVEN] An existing unposted credit memo and a valid JSON describing the new credit memo line with item variantSetAutoCalcFields CreditMemoID := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -658,6 +697,8 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" CreditMemoLineJSON: Text; CreditMemoID: Text; begin + Initialize(); + // [SCENARIO] POST a new line to an unposted Credit Memo with wrong item variant // [GIVEN] An existing unposted credit memo and a valid JSON describing the new credit memo line with item variantSetAutoCalcFields CreditMemoID := CreatePurchaseCreditMemoWithLines(PurchaseHeader); @@ -950,4 +991,9 @@ codeunit 139874 "APIV2 - Purch. Cr.M. Lines E2E" PurchaseLineComment.Description := 'Thank you for your business!'; PurchaseLineComment.Modify(); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchCrMemosE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchCrMemosE2E.Codeunit.al index 99bf5468337..f658d8cfcc2 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchCrMemosE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchCrMemosE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -39,6 +40,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create posted and unposted purchase credit memos and use a GET method to retrieve them // [GIVEN] 2 credit memos, one posted and one unposted CreatePurchaseCreditMemos(CreditMemoNo1, CreditMemoNo2); @@ -71,8 +74,11 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" TargetURL: Text; CreditMemo: Text; begin + Initialize(); + // [SCENARIO] Create posted and unposted Purchase credit memos and use HTTP POST to delete them // [GIVEN] 2 credit memos, one posted and one unposted + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryPurchase.CreateVendorWithAddress(BuyFromVendor); LibraryPurchase.CreateVendorWithAddress(PayToVendor); VendorNo := BuyFromVendor."No."; @@ -115,6 +121,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" CreditMemoJSON: Text; CurrencyCode: Code[10]; begin + Initialize(); + // [SCENARIO] Create posted and unposted with specific currency set and use HTTP POST to create them // [GIVEN] an CreditMemo with a non-LCY currencyCode set @@ -156,6 +164,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" CreditMemoJSON: Text; VendorCreditMemoNumber: Text; begin + Initialize(); + // [SCENARIO] Create posted and unposted with specific vendor credit memo number set and use HTTP POST to create them // [GIVEN] A credit memo with vendor credit memo number set @@ -186,18 +196,24 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" [Test] procedure TestModifyCreditMemos() begin + Initialize(); + TestMultipleModifyCreditMemos(false, false); end; [Test] procedure TestEmptyModifyCreditMemos() begin + Initialize(); + TestMultipleModifyCreditMemos(true, false); end; [Test] procedure TestPartialModifyCreditMemos() begin + Initialize(); + TestMultipleModifyCreditMemos(false, true); end; @@ -274,6 +290,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" CreditMemoNo: Text; CreditMemoID: Text; begin + Initialize(); + // [SCENARIO] Create unposted purchase credit memo and use HTTP DELETE to delete it // [GIVEN] An unposted credit memo CreateDraftPurchaseCreditMemo(PurchaseHeader); @@ -305,9 +323,12 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" CreditMemoPostingDate: Date; CreditMemoJSON: Text; begin + Initialize(); + // [SCENARIO] Create an credit memo both through the client UI and through the API // [SCENARIO] and compare them. They should be the same and have the same fields autocompleted wherever needed. // [GIVEN] An unposted credit memo + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryGraphDocumentTools.InitializeUIPage(); LibraryPurchase.CreateVendor(BuyFromVendor); @@ -343,6 +364,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" ResponseText: Text; CreditMemoID: Text; begin + Initialize(); + // [SCENARIO 184721] Create Credit Memo, use a PATCH method to change it and then verify the changes LibraryPurchase.CreateVendorWithAddress(Vendor); @@ -389,6 +412,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" ResponseText: Text; CreditMemoID: Text; begin + Initialize(); + // [SCENARIO 184721] Clearing manually set discount // [GIVEN] an item with unit price and unit cost @@ -439,6 +464,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can post a purchase credit memo through the API. LibraryERMCountryData.UpdatePurchasesPayablesSetup(); // [GIVEN] Draft purchase credit memo exists @@ -472,6 +499,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can cancel a posted purchase credit memo through API. // [GIVEN] Non-corrective purchase credit memo exists @@ -500,6 +529,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can cancel a posted purchase credit memo through API. // [GIVEN] Corrective purchase credit memo exists @@ -669,6 +700,8 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" PurchaseHeader1RecordRef.GetTable(PurchaseHeader1); PurchaseHeader2RecordRef.GetTable(PurchaseHeader2); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, Database::"Purchase Header", 'Operation Occurred Date'); Assert.RecordsAreEqualExceptCertainFields( PurchaseHeader1RecordRef, PurchaseHeader2RecordRef, TempIgnoredFieldsForComparison, 'Credit Memos do not match'); @@ -714,5 +747,9 @@ codeunit 139865 "APIV2 - Purch. Cr. Memos E2E" Assert.IsTrue(PurchCrMemoEntityBuffer.FindFirst(), CannotFindPostedCreditMemoErr); Assert.AreEqual(Status, PurchCrMemoEntityBuffer.Status, CreditMemoStatusErr); end; -} + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; +} diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchOrderLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchOrderLinesE2E.Codeunit.al index 10c1f29cd26..f475dff691c 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchOrderLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchOrderLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139852 "APIV2 - Purch. Order Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -30,6 +31,8 @@ codeunit 139852 "APIV2 - Purch. Order Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -866,6 +869,8 @@ codeunit 139852 "APIV2 - Purch. Order Lines E2E" Assert.AreNotEqual('', OrderId, 'ID should not be empty'); LibraryInventory.CreateItem(Item); + LibraryGraphDocumentTools.EnsureVATPostingSetupExists( + PurchaseLine."VAT Bus. Posting Group", Item."VAT Prod. Posting Group"); OrderLineJSON := StrSubstNo('{"itemId":"%1"}', LibraryGraphMgt.StripBrackets(Item.SystemId)); Commit(); diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchQuotesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchQuotesE2E.Codeunit.al index fff9ebbec3e..8a6c8f51483 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchQuotesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchQuotesE2E.Codeunit.al @@ -24,6 +24,8 @@ codeunit 139922 "APIV2 - Purch. Quotes E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a purchase quote and use GET to retrieve it // [GIVEN] A purchase quote LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Quote, ''); @@ -44,6 +46,8 @@ codeunit 139922 "APIV2 - Purch. Quotes E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a purchase quote and GET it by SystemId // [GIVEN] A purchase quote LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Quote, ''); @@ -66,6 +70,8 @@ codeunit 139922 "APIV2 - Purch. Quotes E2E" TargetURL: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase quote with $expand=dimensionSetLines // [GIVEN] A purchase quote PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Quote); @@ -92,6 +98,8 @@ codeunit 139922 "APIV2 - Purch. Quotes E2E" TargetURL: Text; AttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase quote with $expand=attachments // [GIVEN] A purchase quote PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Quote); @@ -118,6 +126,8 @@ codeunit 139922 "APIV2 - Purch. Quotes E2E" TargetURL: Text; DocumentAttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase quote with $expand=documentAttachments // [GIVEN] A purchase quote PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Quote); @@ -144,6 +154,8 @@ codeunit 139922 "APIV2 - Purch. Quotes E2E" TargetURL: Text; PdfDocumentValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase quote with $expand=pdfDocument // [GIVEN] A purchase quote PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Quote); @@ -170,6 +182,8 @@ codeunit 139922 "APIV2 - Purch. Quotes E2E" TargetURL: Text; LinesValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase quote with $expand=purchaseQuoteLines // [GIVEN] A purchase quote PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Quote); @@ -194,4 +208,8 @@ codeunit 139922 "APIV2 - Purch. Quotes E2E" exit(TargetURL + '&$expand=' + ExpandValue); exit(TargetURL + '?$expand=' + ExpandValue); end; + + local procedure Initialize() + begin + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchRcptLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchRcptLinesE2E.Codeunit.al index c3c96805fb3..1483cd26db8 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchRcptLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchRcptLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139850 "APIV2 - Purch. Rcpt. Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -29,6 +30,8 @@ codeunit 139850 "APIV2 - Purch. Rcpt. Lines E2E" LineNo: Integer; SequenceValue: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Line of a purchase receipt // [GIVEN] A receipt with a line. LibraryPurchase.CreatePurchaseOrder(PurchaseHeader); @@ -62,6 +65,8 @@ codeunit 139850 "APIV2 - Purch. Rcpt. Lines E2E" LineNo1: Text; LineNo2: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Lines of a Purchase Receipt // [GIVEN] A purchase receipt with lines. CreatePurchaseOrderMultipleLines(PurchaseHeader); @@ -103,6 +108,8 @@ codeunit 139850 "APIV2 - Purch. Rcpt. Lines E2E" LineNo1: Text; LineNo2: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Lines of a purchase receipt // [GIVEN] A purchase receipt with lines. CreatePurchaseOrderMultipleLines(PurchaseHeader); @@ -136,6 +143,8 @@ codeunit 139850 "APIV2 - Purch. Rcpt. Lines E2E" LineIdTxt: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Line of a purchase receipt and expand the dimension set lines // [GIVEN] A receipt with a line. PurchRcptHeader.FindFirst(); @@ -250,4 +259,9 @@ codeunit 139850 "APIV2 - Purch. Rcpt. Lines E2E" exit(TargetURL); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchRetOrdersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchRetOrdersE2E.Codeunit.al index a80fc37128d..64744914e37 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchRetOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchRetOrdersE2E.Codeunit.al @@ -24,6 +24,8 @@ codeunit 139923 "APIV2 - Purch. Ret. Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a purchase return order and use GET to retrieve it // [GIVEN] A purchase return order LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::"Return Order", ''); @@ -44,6 +46,8 @@ codeunit 139923 "APIV2 - Purch. Ret. Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a purchase return order and GET it by SystemId // [GIVEN] A purchase return order LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::"Return Order", ''); @@ -66,6 +70,8 @@ codeunit 139923 "APIV2 - Purch. Ret. Orders E2E" TargetURL: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase return order with $expand=dimensionSetLines // [GIVEN] A purchase return order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Return Order"); @@ -92,6 +98,8 @@ codeunit 139923 "APIV2 - Purch. Ret. Orders E2E" TargetURL: Text; AttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase return order with $expand=attachments // [GIVEN] A purchase return order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Return Order"); @@ -118,6 +126,8 @@ codeunit 139923 "APIV2 - Purch. Ret. Orders E2E" TargetURL: Text; DocumentAttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase return order with $expand=documentAttachments // [GIVEN] A purchase return order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Return Order"); @@ -144,6 +154,8 @@ codeunit 139923 "APIV2 - Purch. Ret. Orders E2E" TargetURL: Text; PdfDocumentValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase return order with $expand=pdfDocument // [GIVEN] A purchase return order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Return Order"); @@ -170,6 +182,8 @@ codeunit 139923 "APIV2 - Purch. Ret. Orders E2E" TargetURL: Text; LinesValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase return order with $expand=purchaseReturnOrderLines // [GIVEN] A purchase return order PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::"Return Order"); @@ -194,4 +208,8 @@ codeunit 139923 "APIV2 - Purch. Ret. Orders E2E" exit(TargetURL + '&$expand=' + ExpandValue); exit(TargetURL + '?$expand=' + ExpandValue); end; + + local procedure Initialize() + begin + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchRetShptsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchRetShptsE2E.Codeunit.al index 7df56e4842f..a3c590533b9 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchRetShptsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchRetShptsE2E.Codeunit.al @@ -24,6 +24,8 @@ codeunit 139928 "APIV2 - Purch. Ret. Shpts. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Post a purchase return order and use GET to retrieve the resulting return shipment // [GIVEN] A posted purchase return shipment EnsurePurchaseReturnShipment(ReturnShipmentHeader); @@ -44,6 +46,8 @@ codeunit 139928 "APIV2 - Purch. Ret. Shpts. E2E" TargetURL: Text; AttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase return shipment with $expand=attachments // [GIVEN] A posted purchase return shipment EnsurePurchaseReturnShipment(ReturnShipmentHeader); @@ -66,6 +70,8 @@ codeunit 139928 "APIV2 - Purch. Ret. Shpts. E2E" TargetURL: Text; DocumentAttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase return shipment with $expand=documentAttachments // [GIVEN] A posted purchase return shipment EnsurePurchaseReturnShipment(ReturnShipmentHeader); @@ -88,6 +94,8 @@ codeunit 139928 "APIV2 - Purch. Ret. Shpts. E2E" TargetURL: Text; PdfDocumentValue: Text; begin + Initialize(); + // [SCENARIO] GET a purchase return shipment with $expand=pdfDocument // [GIVEN] A posted purchase return shipment EnsurePurchaseReturnShipment(ReturnShipmentHeader); @@ -121,4 +129,8 @@ codeunit 139928 "APIV2 - Purch. Ret. Shpts. E2E" exit(TargetURL + '&$expand=' + ExpandValue); exit(TargetURL + '?$expand=' + ExpandValue); end; + + local procedure Initialize() + begin + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchaseInvLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchaseInvLinesE2E.Codeunit.al index 0dbd34f7443..ee324d5d878 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchaseInvLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchaseInvLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139838 "APIV2 - Purchase Inv Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -30,6 +31,8 @@ codeunit 139838 "APIV2 - Purchase Inv Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -1145,6 +1148,5 @@ codeunit 139838 "APIV2 - Purchase Inv Lines E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchaseInvoicesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchaseInvoicesE2E.Codeunit.al index 2477d02b2ad..33d86a7d3a3 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchaseInvoicesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchaseInvoicesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139829 "APIV2 - Purchase Invoices E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -30,6 +31,7 @@ codeunit 139829 "APIV2 - Purchase Invoices E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); end; [Test] @@ -75,6 +77,8 @@ codeunit 139829 "APIV2 - Purchase Invoices E2E" OrderIdValue: Text; OrderNoValue: Text; begin + Initialize(); + // [SCENARIO] Create a Purchase Invoice from a Purchase Order and use GET method to retrieve them and check the orderId and orderNumber // [GIVEN] A purchase invoice created by posting a purchase order LibraryPurchase.CreatePurchaseOrder(PurchaseHeader); @@ -444,6 +448,8 @@ codeunit 139829 "APIV2 - Purchase Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can map systemId with Draft Invoice SystemId // [GIVEN] Posted purchase invoice exists diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchaseOrdersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchaseOrdersE2E.Codeunit.al index 1b799612203..26896be9f07 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchaseOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchaseOrdersE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139851 "APIV2 - Purchase Orders E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -31,7 +32,7 @@ codeunit 139851 "APIV2 - Purchase Orders E2E" local procedure Initialize() begin - WorkDate := Today(); + LibraryGraphMgt.SetLicenseSafeWorkDate(); end; [Test] @@ -92,8 +93,8 @@ codeunit 139851 "APIV2 - Purchase Orders E2E" ShipToVendor.Modify(true); Commit(); VendorNo := BuyFromVendor."No."; - OrderDate := Today(); - PostingDate := Today(); + OrderDate := WorkDate(); + PostingDate := WorkDate(); // [GIVEN] a JSON text with an order that contains the vendor and an address OrderJSON := CreateOrderJSONWithAddress(BuyFromVendor, PayToVendor, ShipToVendor, OrderDate, PostingDate); @@ -143,8 +144,8 @@ codeunit 139851 "APIV2 - Purchase Orders E2E" LibraryPurchase.CreateVendorWithAddress(BuyFromVendor); LibraryPurchase.CreateVendorWithAddress(PayToVendor); VendorNo := BuyFromVendor."No."; - OrderDate := Today(); - PostingDate := Today(); + OrderDate := WorkDate(); + PostingDate := WorkDate(); // [GIVEN] a JSON text with an order that contains the vendor and an address OrderJSON := CreateOrderJSONWithoutShipTo(BuyFromVendor, PayToVendor, OrderDate, PostingDate); @@ -402,8 +403,8 @@ codeunit 139851 "APIV2 - Purchase Orders E2E" // [GIVEN] a customer LibraryPurchase.CreateVendor(Vendor); VendorNo := Vendor."No."; - OrderDate := Today(); - PostingDate := Today(); + OrderDate := WorkDate(); + PostingDate := WorkDate(); // [GIVEN] a json describing our new order OrderJSON := CreateOrderJSONWithAddress(Vendor, Vendor, Vendor, OrderDate, PostingDate); @@ -427,6 +428,8 @@ codeunit 139851 "APIV2 - Purchase Orders E2E" LibraryUtility.AddTempField(TempIgnoredFieldsForComparison, ApiPurchaseHeader.FieldNo("No."), Database::"Purchase Header"); LibraryUtility.AddTempField( TempIgnoredFieldsForComparison, ApiPurchaseHeader.FieldNo("Posting Description"), Database::"Purchase Header"); + LibraryUtility.AddTempField( + TempIgnoredFieldsForComparison, ApiPurchaseHeader.FieldNo("Order Date"), Database::"Purchase Header"); // Special ignore case for GB LibraryUtility.AddTempField(TempIgnoredFieldsForComparison, ApiPurchaseHeader.FieldNo("Invoice Received Date"), Database::"Purchase Header"); // Special ignore case for ES @@ -441,14 +444,14 @@ codeunit 139851 "APIV2 - Purchase Orders E2E" LibraryUtility.AddTempField(TempIgnoredFieldsForComparison, RecordField."No.", Database::"Purchase Header"); // Time zone will impact how the date from the page vs WebService is saved. If removed this will fail in snap between 12:00 - 1 AM - if Time() < 020000T then begin - LibraryUtility.AddTempField(TempIgnoredFieldsForComparison, ApiPurchaseHeader.FieldNo("Order Date"), Database::"Purchase Header"); + if Time() < 020000T then LibraryUtility.AddTempField(TempIgnoredFieldsForComparison, ApiPurchaseHeader.FieldNo("Posting Date"), Database::"Purchase Header"); - end; PagePurchaseHeader.Get(PagePurchaseHeader."Document Type"::Order, PurchaseOrder."No.".Value()); ApiRecordRef.GetTable(ApiPurchaseHeader); PageRecordRef.GetTable(PagePurchaseHeader); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, Database::"Purchase Header", 'Operation Occurred Date'); Assert.RecordsAreEqualExceptCertainFields(ApiRecordRef, PageRecordRef, TempIgnoredFieldsForComparison, 'Page and API order do not match'); @@ -603,6 +606,8 @@ codeunit 139851 "APIV2 - Purchase Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can recieve and invoice a purchase order through the API. // [GIVEN] Create vendors and a Purchase order with lines @@ -667,6 +672,7 @@ codeunit 139851 "APIV2 - Purchase Orders E2E" PurchaseOrder."Buy-from Vendor No.".SetValue(Vendor."No."); PurchaseOrder."Document Date".SetValue(DocumentDate); PurchaseOrder."Posting Date".SetValue(PostingDate); + PurchaseOrder."Order Date".SetValue(DocumentDate); end; local procedure CheckShippingDetailsNotEmpty(var PurchaseHeader: Record "Purchase Header") diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchaseReceiptsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchaseReceiptsE2E.Codeunit.al index da2b96c946c..b6a4b065805 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchaseReceiptsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchaseReceiptsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139849 "APIV2 - Purchase Receipts E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -26,6 +27,8 @@ codeunit 139849 "APIV2 - Purchase Receipts E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create 2 purchase receipts (post sales order) and use a GET method to retrieve them // [GIVEN] 2 posted purchase receipts LibraryPurchase.CreatePurchaseOrder(PurchaseHeader); @@ -56,6 +59,8 @@ codeunit 139849 "APIV2 - Purchase Receipts E2E" ReceiptIdTxt: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] Call GET on purchase receipt and expand the dimension set lines // [GIVEN] A purchase receipt. @@ -106,4 +111,9 @@ codeunit 139849 "APIV2 - Purchase Receipts E2E" exit(TargetURL); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2RetEarningsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2RetEarningsE2E.Codeunit.al index 771bc75dd2f..2b0ef00ba87 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2RetEarningsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2RetEarningsE2E.Codeunit.al @@ -62,6 +62,8 @@ codeunit 139821 "APIV2 - Ret. Earnings E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -93,4 +95,3 @@ codeunit 139821 "APIV2 - Ret. Earnings E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesCrMemoLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesCrMemoLinesE2E.Codeunit.al index 203a1e04eb3..e1fba9fc53b 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesCrMemoLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesCrMemoLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139837 "APIV2 - Sales CrMemo Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -30,6 +31,8 @@ codeunit 139837 "APIV2 - Sales CrMemo Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -1413,8 +1416,6 @@ codeunit 139837 "APIV2 - Sales CrMemo Lines E2E" - - diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesCreditMemosE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesCreditMemosE2E.Codeunit.al index 91631a22534..144cb8f4b70 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesCreditMemosE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesCreditMemosE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -56,6 +57,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create posted and unposted sales credit memos and use a GET method to retrieve them // [GIVEN] 2 credit memos, one posted and one unposted CreateSalesCreditMemos(CreditMemoNo1, CreditMemoNo2); @@ -88,9 +91,12 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" TargetURL: Text; CreditMemo: Text; begin + Initialize(); + // [SCENARIO] Create posted and unposted Sales credit memos and use HTTP POST to delete them // [GIVEN] 2 credit memos, one posted and one unposted + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibrarySales.CreateCustomerWithAddress(SellToCustomer); LibrarySales.CreateCustomerWithAddress(BillToCustomer); CustomerNo := SellToCustomer."No."; @@ -133,6 +139,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" CreditMemoJSON: Text; CurrencyCode: Code[10]; begin + Initialize(); + // [SCENARIO] Create posted and unposted with specific currency set and use HTTP POST to create them // [GIVEN] an CreditMemo with a non-LCY currencyCode set @@ -165,18 +173,24 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" [Test] procedure TestModifyCreditMemos() begin + Initialize(); + TestMultipleModifyCreditMemos(false, false); end; [Test] procedure TestEmptyModifyCreditMemos() begin + Initialize(); + TestMultipleModifyCreditMemos(true, false); end; [Test] procedure TestPartialModifyCreditMemos() begin + Initialize(); + TestMultipleModifyCreditMemos(false, true); end; @@ -252,6 +266,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" CreditMemoNo: Text; CreditMemoID: Text; begin + Initialize(); + // [SCENARIO] Create unposted sales credit memo and use HTTP DELETE to delete it // [GIVEN] An unposted credit memo CreateDraftSalesCreditMemo(SalesHeader); @@ -283,9 +299,12 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" CreditMemoPostingDate: Date; CreditMemoJSON: Text; begin + Initialize(); + // [SCENARIO] Create an credit memo both through the client UI and through the API // [SCENARIO] and compare them. They should be the same and have the same fields autocompleted wherever needed. // [GIVEN] An unposted credit memo + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryGraphDocumentTools.InitializeUIPage(); LibrarySales.CreateCustomer(SellToCustomer); @@ -316,6 +335,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" TargetURL: Text; DiscountPct: Decimal; begin + Initialize(); + // [SCENARIO] When an credit memo is created,the GET Method should update the credit memo and assign a total // [GIVEN] 2 credit memos, one posted and one unposted without totals assigned LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending( @@ -348,6 +369,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" DiscountAmt: Decimal; InvDiscAmount: Decimal; begin + Initialize(); + // [SCENARIO] When an credit memo is created, the GET Method should update the credit memo and assign a total // [GIVEN] 2 credit memos, one posted and one unposted with discount amount that should be redistributed LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending( @@ -387,6 +410,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; CreditMemoID: Text; begin + Initialize(); + // [SCENARIO 184721] Create Credit Memo, use a PATCH method to change it and then verify the changes LibrarySales.CreateCustomerWithAddress(Customer); @@ -433,6 +458,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; CreditMemoID: Text; begin + Initialize(); + // [SCENARIO 184721] Clearing manually set discount // [GIVEN] an item with unit price and unit cost @@ -488,6 +515,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" PostedCreditMemoEmailAddress: Text; PostedCreditMemoEmailSubject: Text; begin + Initialize(); + // [SCENARIO] User can post a sales credit memo through the API. // [GIVEN] Draft sales credit memo exists @@ -535,6 +564,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can post and send a sales credit memo through the API. InitializeForSending(); @@ -573,6 +604,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can cancel a posted sales credit memo through API. // [GIVEN] Non-corrective sales credit memo exists @@ -601,6 +634,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can cancel a posted sales credit memo through API. // [GIVEN] Corrective sales credit memo exists @@ -633,6 +668,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can cancel a posted sales credit memo through API. InitializeForSending(); @@ -669,6 +706,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can send a posted sales credit memo through the API. InitializeForSending(); @@ -701,6 +740,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Sending a draft sales credit memo through the API throws an error InitializeForSending(); @@ -730,6 +771,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can send a draft sales credit memo through the API. InitializeForSending(); @@ -754,11 +797,16 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" local procedure CreateCorrectiveSalesCreditMemo(var SalesCrMemoHeader: Record "Sales Cr.Memo Header") var + ReasonCode: Record "Reason Code"; SalesInvoiceHeader: Record "Sales Invoice Header"; SalesHeader: Record "Sales Header"; InvoiceCode: Code[20]; begin LibrarySales.CreateSalesInvoice(SalesHeader); + EnsureReasonCode(); + ReasonCode.FindFirst(); + SalesHeader.Validate("Reason Code", ReasonCode.Code); + SalesHeader.Modify(true); InvoiceCode := LibrarySales.PostSalesDocument(SalesHeader, false, true); SalesInvoiceHeader.Get(InvoiceCode); Commit(); @@ -767,6 +815,16 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" SalesCrMemoHeader.FindFirst(); end; + local procedure EnsureReasonCode() + var + ReasonCode: Record "Reason Code"; + begin + if not ReasonCode.IsEmpty() then + exit; + + LibraryERM.CreateReasonCode(ReasonCode); + end; + local procedure CreateDraftSalesCreditMemo(var SalesHeader: Record "Sales Header") begin LibrarySales.CreateSalesCreditMemo(SalesHeader); @@ -925,6 +983,8 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" SalesHeader1RecordRef.GetTable(SalesHeader1); SalesHeader2RecordRef.GetTable(SalesHeader2); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, Database::"Sales Header", 'Operation Occurred Date'); Assert.RecordsAreEqualExceptCertainFields( SalesHeader1RecordRef, SalesHeader2RecordRef, TempIgnoredFieldsForComparison, 'Credit Memos do not match'); @@ -1043,5 +1103,9 @@ codeunit 139828 "APIV2 - Sales Credit Memos E2E" while JobQueueEntry.FindJobQueueEntry(JobQueueEntry."Object Type to Run"::Codeunit, CodeunitID) do JobQueueEntry.Cancel(); end; -} + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; +} diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesInvLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesInvLinesE2E.Codeunit.al index 3a88184d347..746d7a2365f 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesInvLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesInvLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139834 "APIV2 - Sales Inv. Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -31,6 +32,8 @@ codeunit 139834 "APIV2 - Sales Inv. Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -1079,6 +1082,8 @@ codeunit 139834 "APIV2 - Sales Inv. Lines E2E" Assert.AreNotEqual('', InvoiceLineID, 'ID should not be empty'); LibraryInventory.CreateItem(Item); + LibraryGraphDocumentTools.EnsureVATPostingSetupExists( + SalesLine."VAT Bus. Posting Group", Item."VAT Prod. Posting Group"); InvoiceLineJSON := StrSubstNo('{"itemId":"%1"}', LibraryGraphMgt.StripBrackets(Item.SystemId)); Commit(); diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesInvoicesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesInvoicesE2E.Codeunit.al index 9438dd8d7fc..b48cd7ca5a6 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesInvoicesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesInvoicesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -70,6 +71,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO 184721] Create posted and unposted Sales invoices and use a GET method to retrieve them // [GIVEN] 2 invoices, one posted and one unposted CreateSalesInvoices(InvoiceID1, InvoiceID2); @@ -102,6 +105,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" OrderIdValue: Text; OrderNoValue: Text; begin + Initialize(); + // [SCENARIO] Create a Sales Invoice from a Sales Order and use GET method to retrieve them and check the orderId and orderNumber // [GIVEN] A sales invoice created by posting a sales order LibrarySales.CreateSalesOrder(SalesHeader); @@ -145,9 +150,12 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" TargetURL: Text; InvoiceJSON: Text; begin + Initialize(); + // [SCENARIO 184721] Create posted and unposted Sales invoices and use HTTP POST to delete them // [GIVEN] 2 invoices, one posted and one unposted + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibrarySales.CreateCustomer(SellToCustomer); LibrarySales.CreateCustomer(BillToCustomer); LibrarySales.CreateCustomer(ShipToCustomer); @@ -195,6 +203,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" InvoiceJSON: Text; CurrencyCode: Code[10]; begin + Initialize(); + // [SCENARIO 184721] Create posted and unposted with specific currency set and use HTTP POST to create them // [GIVEN] an Invoice with a non-LCY currencyCode set @@ -242,6 +252,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" Email: Text; CurrencyCode: Code[10]; begin + Initialize(); + // [SCENARIO 285872] Create posted and unposted with specific email set and use HTTP POST to create them Email := 'test@microsoft.com'; // [GIVEN] an Customer with no email set @@ -293,8 +305,12 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" TargetURL: Text; InvoiceJSON: Text; begin + Initialize(); + // [SCENARIO 184721] Create unposted with specific document and due date set and use HTTP POST to create them + LibraryGraphMgt.SetLicenseSafeWorkDate(); + // [GIVEN] an Invoice with a document and due date set LibrarySales.CreateCustomer(Customer); CustomerNo := Customer."No."; @@ -333,18 +349,24 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" [Test] procedure TestModifyInvoices() begin + Initialize(); + TestMultipleModifyInvoices(false, false); end; [Test] procedure TestEmptyModifyInvoices() begin + Initialize(); + TestMultipleModifyInvoices(true, false); end; [Test] procedure TestPartialModifyInvoices() begin + Initialize(); + TestMultipleModifyInvoices(false, true); end; @@ -436,6 +458,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" TargetURL: Text; InvoiceWithBlanksJSON: Text; begin + Initialize(); + // [SCENARIO 184721] Create Sales Invoice with all the Ids filled, use a PATCH method to blank the Ids and the Codes LibrarySales.CreateCustomerWithAddress(Customer); @@ -500,6 +524,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" NewInvoiceNumber: Text; NewInvoiceNumberJSON: Text; begin + Initialize(); + // [SCENARIO 184721] Create draft invoice and issue a patch request to change the number // [GIVEN] 1 draft invoice and a json with a new number LibrarySales.CreateSalesInvoice(SalesHeader); @@ -522,6 +548,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO 184721] Create unposted Sales invoice and use HTTP DELETE to delete it // [GIVEN] An unposted invoice CreateDraftSalesInvoice(SalesHeader); @@ -559,9 +587,12 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" TargetURL: Text; InvoiceJSON: Text; begin + Initialize(); + // [SCENARIO 184721] Create an invoice both through the client UI and through the API // [SCENARIO] and compare them. They should be the same and have the same fields autocompleted wherever needed. // [GIVEN] An unposted invoice + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryGraphDocumentTools.InitializeUIPage(); LibraryApplicationArea.DisableApplicationAreaSetup(); @@ -606,6 +637,9 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" PageSalesHeader.Get(PageSalesHeader."Document Type"::Invoice, SalesInvoice."No.".Value()); ApiRecordRef.GetTable(ApiSalesHeader); PageRecordRef.GetTable(PageSalesHeader); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, Database::"Sales Header", 'Operation Occurred Date'); + Assert.RecordsAreEqualExceptCertainFields(ApiRecordRef, PageRecordRef, TempIgnoredFieldsForComparison, 'Page and API Invoice do not match'); @@ -621,6 +655,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" TargetURL: Text; DiscountPct: Decimal; begin + Initialize(); + // [SCENARIO 184721] When an invoice is created,the GET Method should update the invoice and assign a total // [GIVEN] 2 invoices, one posted and one unposted without totals assigned LibraryApplicationArea.EnableFoundationSetup(); @@ -654,6 +690,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" DiscountAmt: Decimal; InvDiscAmount: Decimal; begin + Initialize(); + // [SCENARIO 184721] When an invoice is created, the GET Method should update the invoice and assign a total // [GIVEN] 2 invoices, one posted and one unposted with discount amount that should be redistributed LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending( @@ -689,6 +727,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" InvoiceJSON: Text; CurrencyCode: Code[10]; begin + Initialize(); + // [SCENARIO 184721] Create an invoice wihtout Customer throws an error // [GIVEN] a sales invoice JSON with currency only @@ -717,6 +757,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; InvoiceID: Text; begin + Initialize(); + // [SCENARIO 184721] Create Sales Invoice, use a PATCH method to change it and then verify the changes LibrarySales.CreateCustomerWithAddress(Customer); @@ -763,6 +805,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; InvoiceID: Text; begin + Initialize(); + // [SCENARIO 184721] Clearing manually set discount // [GIVEN] an item with unit price and unit cost @@ -819,6 +863,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" PostedInvoiceEmailAddress: Text; PostedInvoiceEmailSubject: Text; begin + Initialize(); + // [SCENARIO] User can post a sales invoice through the API. // [GIVEN] Draft sales invoice exists @@ -865,6 +911,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can post and send a sales invoice through the API. InitializeForSending(); @@ -903,6 +951,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can cancel a posted sales invoice through API. // [GIVEN] Posted sales invoice exists @@ -911,6 +961,7 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" DocumentId := SalesInvoiceHeader."Draft Invoice SystemId"; // Special case for AU + EnsureReasonCode(); LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup(); Commit(); @@ -939,6 +990,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can cancel a posted sales invoice through API. InitializeForSending(); @@ -948,6 +1001,7 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" DocumentId := SalesInvoiceHeader."Draft Invoice SystemId"; // Special case for AU + EnsureReasonCode(); LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup(); Commit(); @@ -979,6 +1033,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can send a posted sales invoice through the API. InitializeForSending(); @@ -1011,6 +1067,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can send a draft sales invoice through the API. InitializeForSending(); @@ -1043,6 +1101,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can send a draft sales invoice through the API. InitializeForSending(); @@ -1083,6 +1143,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" CreditMemoEmailAddress: Text; CreditMemoEmailSubject: Text; begin + Initialize(); + // [SCENARIO] User can create a corrective credit memo for the posted sales invoice through the API. // [GIVEN] A posted sales invoice exists @@ -1127,6 +1189,8 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can map systemId with Draft Invoice SystemId // [GIVEN] Posted sales invoice exists @@ -1299,9 +1363,22 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" local procedure CreateCancelledSalesInvoice(var SalesInvoiceHeader: Record "Sales Invoice Header") begin CreatePostedSalesInvoice(SalesInvoiceHeader); + EnsureReasonCode(); + LibrarySales.SetDefaultCancelReasonCodeForSalesAndReceivablesSetup(); + Commit(); CODEUNIT.Run(CODEUNIT::"Correct Posted Sales Invoice", SalesInvoiceHeader); end; + local procedure EnsureReasonCode() + var + ReasonCode: Record "Reason Code"; + begin + if not ReasonCode.IsEmpty() then + exit; + + LibraryERM.CreateReasonCode(ReasonCode); + end; + local procedure CreateSalesInvoices(var InvoiceID1: Text; var InvoiceID2: Text) var SalesInvoiceHeader: Record "Sales Invoice Header"; @@ -1380,4 +1457,9 @@ codeunit 139809 "APIV2 - Sales Invoices E2E" LibraryGraphMgt.VerifyIDInJson(ResponseText); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesOrdArchE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesOrdArchE2E.Codeunit.al index 43a0cf41433..674758ed13e 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesOrdArchE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesOrdArchE2E.Codeunit.al @@ -25,6 +25,8 @@ codeunit 139927 "APIV2 - Sales Ord. Arch. E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Archive a sales order and use GET to retrieve the archive // [GIVEN] An archived sales order EnsureSalesOrderArchive(SalesHeaderArchive); @@ -45,6 +47,8 @@ codeunit 139927 "APIV2 - Sales Ord. Arch. E2E" TargetURL: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] GET a sales order archive with $expand=dimensionSetLines // [GIVEN] An archived sales order EnsureSalesOrderArchive(SalesHeaderArchive); @@ -67,6 +71,8 @@ codeunit 139927 "APIV2 - Sales Ord. Arch. E2E" TargetURL: Text; AttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a sales order archive with $expand=attachments // [GIVEN] An archived sales order EnsureSalesOrderArchive(SalesHeaderArchive); @@ -89,6 +95,8 @@ codeunit 139927 "APIV2 - Sales Ord. Arch. E2E" TargetURL: Text; DocumentAttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a sales order archive with $expand=documentAttachments // [GIVEN] An archived sales order EnsureSalesOrderArchive(SalesHeaderArchive); @@ -121,4 +129,8 @@ codeunit 139927 "APIV2 - Sales Ord. Arch. E2E" exit(TargetURL + '&$expand=' + ExpandValue); exit(TargetURL + '?$expand=' + ExpandValue); end; + + local procedure Initialize() + begin + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesOrderLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesOrderLinesE2E.Codeunit.al index 280882e872d..6e798b63901 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesOrderLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesOrderLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139835 "APIV2 - Sales Order Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -30,6 +31,8 @@ codeunit 139835 "APIV2 - Sales Order Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -863,6 +866,8 @@ codeunit 139835 "APIV2 - Sales Order Lines E2E" Assert.AreNotEqual('', OrderId, 'ID should not be empty'); LibraryInventory.CreateItem(Item); + LibraryGraphDocumentTools.EnsureVATPostingSetupExists( + SalesLine."VAT Bus. Posting Group", Item."VAT Prod. Posting Group"); OrderLineJSON := StrSubstNo('{"itemId":"%1"}', LibraryGraphMgt.StripBrackets(Item.SystemId)); Commit(); @@ -1477,9 +1482,6 @@ codeunit 139835 "APIV2 - Sales Order Lines E2E" - - - diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesOrdersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesOrdersE2E.Codeunit.al index 16759bdf1b6..eb240d05feb 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesOrdersE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139811 "APIV2 - Sales Orders E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -38,6 +39,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO 184721] Create Sales Orders and use a GET method to retrieve them // [GIVEN] 2 orders in the table @@ -76,8 +79,12 @@ codeunit 139811 "APIV2 - Sales Orders E2E" TargetURL: Text; OrderJSON: Text; begin + Initialize(); + // [SCENARIO 184721] Create sales orders JSON and use HTTP POST to create them + LibraryGraphMgt.SetLicenseSafeWorkDate(); + // [GIVEN] a customer LibrarySales.CreateCustomerWithAddress(SellToCustomer); LibrarySales.CreateCustomerWithAddress(BillToCustomer); @@ -125,6 +132,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" TargetURL: Text; OrderJSON: Text; begin + Initialize(); + // [SCENARIO 184721] Create sales order for customer with location and use HTTP POST to create it // [GIVEN] an order with customer with location code @@ -168,6 +177,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" OrderJSON: Text; CurrencyCode: Code[10]; begin + Initialize(); + // [SCENARIO 184721] Create sales order with specific currency set and use HTTP POST to create it // [GIVEN] an order with a non-LCY currencyCode set @@ -203,18 +214,24 @@ codeunit 139811 "APIV2 - Sales Orders E2E" [Test] procedure TestModifyOrders() begin + Initialize(); + TestMultipleModifyOrders(false, false); end; [Test] procedure TestEmptyModifyOrders() begin + Initialize(); + TestMultipleModifyOrders(true, false); end; [Test] procedure TestPartialModifyOrders() begin + Initialize(); + TestMultipleModifyOrders(false, true); end; @@ -283,6 +300,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO 184721] Create sales orders and use HTTP DELETE to delete them // [GIVEN] 2 orders in the table @@ -329,7 +348,10 @@ codeunit 139811 "APIV2 - Sales Orders E2E" TargetURL: Text; OrderJSON: Text; begin + Initialize(); + // [SCENARIO 184721] Create an order both through the client UI and through the API and compare them. They should be the same and have the same fields autocompleted wherever needed. + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryGraphDocumentTools.InitializeUIPage(); // [GIVEN] a customer @@ -375,6 +397,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" PageSalesHeader.Get(PageSalesHeader."Document Type"::Order, SalesOrder."No.".Value()); ApiRecordRef.GetTable(ApiSalesHeader); PageRecordRef.GetTable(PageSalesHeader); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, Database::"Sales Header", 'Operation Occurred Date'); Assert.RecordsAreEqualExceptCertainFields(ApiRecordRef, PageRecordRef, TempIgnoredFieldsForComparison, 'Page and API order do not match'); @@ -388,6 +412,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" TargetURL: Text; DiscountPct: Decimal; begin + Initialize(); + // [SCENARIO 184721] When an order is created, the GET Method should update the order and assign a total // [GIVEN] an order without totals assigned LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending(SalesHeader, DiscountPct, SalesHeader."Document Type"::Order); @@ -417,6 +443,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" DiscountAmt: Decimal; InvDiscAmount: Decimal; begin + Initialize(); + // [SCENARIO 184721] When an order is created, the GET Method should update the order and redistribute the discount amount // [GIVEN] an order with discount amount that should be redistributed LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending(SalesHeader, DiscountPct, SalesHeader."Document Type"::Order); @@ -451,6 +479,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" OrderNo: Text; OrderId: Guid; begin + Initialize(); + // [SCENARIO 184721] Create Sales Order, use a PATCH method to change it and then verify the changes // [GIVEN] an order with lines @@ -487,6 +517,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" ResponseText: Text; OrderNo: Text; begin + Initialize(); + // [SCENARIO 184721] Clearing manually set discount // [GIVEN] an order @@ -523,6 +555,8 @@ codeunit 139811 "APIV2 - Sales Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can ship and invoice a sales order through the API. // [GIVEN] a sales order with lines @@ -644,4 +678,9 @@ codeunit 139811 "APIV2 - Sales Orders E2E" LibraryGraphMgt.VerifyIDInJson(ResponseText); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesQuoteLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesQuoteLinesE2E.Codeunit.al index 803ae25520c..cbe8d4a615e 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesQuoteLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesQuoteLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139836 "APIV2 - Sales Quote Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -28,6 +29,8 @@ codeunit 139836 "APIV2 - Sales Quote Lines E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -998,6 +1001,5 @@ codeunit 139836 "APIV2 - Sales Quote Lines E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesQuotesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesQuotesE2E.Codeunit.al index e934a55669a..26c7c2d55bc 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesQuotesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesQuotesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -60,6 +61,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create Sales Quotes and use a GET method to retrieve them // [GIVEN] 2 quotes in the table @@ -98,8 +101,12 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" QuoteJSON: Text; QuoteExists: Boolean; begin + Initialize(); + // [SCENARIO] Create sales quotes JSON and use HTTP POST to create them + LibraryGraphMgt.SetLicenseSafeWorkDate(); + // [GIVEN] a customer LibrarySales.CreateCustomerWithAddress(SellToCustomer); LibrarySales.CreateCustomerWithAddress(ShipToCustomer); @@ -143,6 +150,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" CurrencyCode: Code[10]; QuoteExists: Boolean; begin + Initialize(); + // [SCENARIO] Create sales quote with specific currency set and use HTTP POST to create it // [GIVEN] a quote with a non-LCY currencyCode set @@ -174,18 +183,24 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" [Test] procedure TestModifyQuotes() begin + Initialize(); + TestMultipleModifyQuotes(false, false); end; [Test] procedure TestEmptyModifyQuotes() begin + Initialize(); + TestMultipleModifyQuotes(true, false); end; [Test] procedure TestPartialModifyQuotes() begin + Initialize(); + TestMultipleModifyQuotes(false, true); end; @@ -269,6 +284,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create sales quotes and use HTTP DELETE to delete them // [GIVEN] 2 quotes in the table @@ -315,7 +332,10 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" QuoteJSON: Text; QuoteExists: Boolean; begin + Initialize(); + // [SCENARIO] Create a quote both through the client UI and through the API and compare them. They should be the same and have the same fields autocompleted wherever needed. + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryGraphDocumentTools.InitializeUIPage(); // [GIVEN] a customer @@ -357,6 +377,11 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" PageSalesHeader.Get(PageSalesHeader."Document Type"::Quote, SalesQuote."No.".Value()); ApiRecordRef.GetTable(ApiSalesHeader); PageRecordRef.GetTable(PageSalesHeader); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, Database::"Sales Header", 'Operation Occurred Date'); + LibraryGraphMgt.AddFieldToIgnoreIfExists( + TempIgnoredFieldsForComparison, Database::"Sales Header", 'VAT Reporting Date'); + Assert.RecordsAreEqualExceptCertainFields(ApiRecordRef, PageRecordRef, TempIgnoredFieldsForComparison, 'Page and API quote do not match'); end; @@ -369,6 +394,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" TargetURL: Text; DiscountPct: Decimal; begin + Initialize(); + // [SCENARIO] When a quote is created, the GET Method should update the quote and assign a total // [GIVEN] a quote without totals assigned LibraryGraphDocumentTools.CreateDocumentWithDiscountPctPending(SalesHeader, DiscountPct, SalesHeader."Document Type"::Quote); @@ -398,6 +425,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" DiscountAmt: Decimal; InvDiscAmount: Decimal; begin + Initialize(); + // [SCENARIO] When a quote is created, the GET Method should update the quote and redistribute the discount amount // [GIVEN] a quote with discount amount that should be redistributed @@ -435,6 +464,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" ResponseText: Text; QuoteID: Text; begin + Initialize(); + // [SCENARIO 184721] Create Sales Quote, use a PATCH method to change it and then verify the changes LibrarySales.CreateCustomerWithAddress(Customer); @@ -481,6 +512,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" ResponseText: Text; QuoteID: Text; begin + Initialize(); + // [SCENARIO 184721] Clearing manually set discount // [GIVEN] an item with unit price and unit cost @@ -529,6 +562,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] User can send a sales quote through the API. InitializeForSending(); @@ -572,6 +607,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" InvoiceEmailAddress: Text; InvoiceEmailSubject: Text; begin + Initialize(); + // [SCENARIO] User can convert a sales quote to a sales invoice through the API. // [GIVEN] Sales quote exists @@ -630,6 +667,8 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" OrderEmailAddress: Text; OrderEmailSubject: Text; begin + Initialize(); + // [SCENARIO] User can convert a sales quote to a sales order through the API. // [GIVEN] Sales quote exists @@ -751,6 +790,9 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" LibrarySmallBusiness.CreateCustomer(Customer); LibrarySmallBusiness.CreateItem(Item); LibrarySmallBusiness.CreateSalesQuoteHeaderWithLines(SalesHeader, Customer, Item, 1, 1); + SalesHeader.Validate("Posting Date", WorkDate()); + SalesHeader.Validate("Document Date", WorkDate()); + SalesHeader.Modify(true); end; local procedure FindSalesHeader(var SalesHeader: Record "Sales Header"; CustomerNo: Text; QuoteNumber: Text): Boolean @@ -847,4 +889,9 @@ codeunit 139823 "APIV2 - Sales Quotes E2E" end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesRetOrdersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesRetOrdersE2E.Codeunit.al index c049e3837f6..177d315c20a 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesRetOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesRetOrdersE2E.Codeunit.al @@ -24,6 +24,8 @@ codeunit 139924 "APIV2 - Sales Ret. Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a sales return order and use GET to retrieve it // [GIVEN] A sales return order LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::"Return Order", ''); @@ -44,6 +46,8 @@ codeunit 139924 "APIV2 - Sales Ret. Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a sales return order and GET it by SystemId // [GIVEN] A sales return order LibrarySales.CreateSalesHeader(SalesHeader, SalesHeader."Document Type"::"Return Order", ''); @@ -66,6 +70,8 @@ codeunit 139924 "APIV2 - Sales Ret. Orders E2E" TargetURL: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] GET a sales return order with $expand=dimensionSetLines // [GIVEN] A sales return order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Return Order"); @@ -92,6 +98,8 @@ codeunit 139924 "APIV2 - Sales Ret. Orders E2E" TargetURL: Text; AttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a sales return order with $expand=attachments // [GIVEN] A sales return order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Return Order"); @@ -118,6 +126,8 @@ codeunit 139924 "APIV2 - Sales Ret. Orders E2E" TargetURL: Text; DocumentAttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a sales return order with $expand=documentAttachments // [GIVEN] A sales return order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Return Order"); @@ -144,6 +154,8 @@ codeunit 139924 "APIV2 - Sales Ret. Orders E2E" TargetURL: Text; PdfDocumentValue: Text; begin + Initialize(); + // [SCENARIO] GET a sales return order with $expand=pdfDocument // [GIVEN] A sales return order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Return Order"); @@ -170,6 +182,8 @@ codeunit 139924 "APIV2 - Sales Ret. Orders E2E" TargetURL: Text; LinesValue: Text; begin + Initialize(); + // [SCENARIO] GET a sales return order with $expand=salesReturnOrderLines // [GIVEN] A sales return order SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::"Return Order"); @@ -194,4 +208,8 @@ codeunit 139924 "APIV2 - Sales Ret. Orders E2E" exit(TargetURL + '&$expand=' + ExpandValue); exit(TargetURL + '?$expand=' + ExpandValue); end; + + local procedure Initialize() + begin + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesShipLinesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesShipLinesE2E.Codeunit.al index 3081e6c6df6..9832b0b0f0e 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesShipLinesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesShipLinesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139848 "APIV2 - Sales Ship. Lines E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -29,6 +30,8 @@ codeunit 139848 "APIV2 - Sales Ship. Lines E2E" LineNo: Integer; SequenceValue: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Line of a sales shipment // [GIVEN] A shipment with a line. @@ -63,6 +66,8 @@ codeunit 139848 "APIV2 - Sales Ship. Lines E2E" LineNo1: Text; LineNo2: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Lines of Sales Shipment // [GIVEN] An sales shipment with lines. @@ -105,6 +110,8 @@ codeunit 139848 "APIV2 - Sales Ship. Lines E2E" LineNo1: Text; LineNo2: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Lines of a sales shipment // [GIVEN] An sales shipment with lines. @@ -139,6 +146,8 @@ codeunit 139848 "APIV2 - Sales Ship. Lines E2E" LineIdTxt: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] Call GET on the Line of a sales shipment and expand the dimension set lines // [GIVEN] A shipment with a line. @@ -255,4 +264,9 @@ codeunit 139848 "APIV2 - Sales Ship. Lines E2E" exit(TargetURL); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalesShipmentsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalesShipmentsE2E.Codeunit.al index 230e2af2a5b..bff9ce03db6 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalesShipmentsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalesShipmentsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139847 "APIV2 - Sales Shipments E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -26,6 +27,8 @@ codeunit 139847 "APIV2 - Sales Shipments E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create 2 sales shipments (post sales order) and use a GET method to retrieve them // [GIVEN] 2 posted sales shipments @@ -57,6 +60,8 @@ codeunit 139847 "APIV2 - Sales Shipments E2E" ShipmentIdTxt: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] Call GET on a sales shipment and expand the dimension set lines // [GIVEN] A sales shipment. @@ -108,4 +113,9 @@ codeunit 139847 "APIV2 - Sales Shipments E2E" exit(TargetURL); end; + + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2SalespersonPurchE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2SalespersonPurchE2E.Codeunit.al index 00b9b57cfd8..a2e955e7662 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2SalespersonPurchE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2SalespersonPurchE2E.Codeunit.al @@ -14,6 +14,8 @@ codeunit 139882 "APIV2 - Salesperson/Purch E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2ShipmentMethodsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ShipmentMethodsE2E.Codeunit.al index b7f25bf36dd..9cf63b6d4c8 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ShipmentMethodsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ShipmentMethodsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139805 "APIV2 - Shipment Methods E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -21,6 +22,8 @@ codeunit 139805 "APIV2 - Shipment Methods E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2TaxAreasE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2TaxAreasE2E.Codeunit.al index 3e579576ff6..785ea4bf8f4 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2TaxAreasE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2TaxAreasE2E.Codeunit.al @@ -24,6 +24,8 @@ codeunit 139826 "APIV2 - Tax Areas E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -288,4 +290,3 @@ codeunit 139826 "APIV2 - Tax Areas E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2TaxGroupsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2TaxGroupsE2E.Codeunit.al index 71058576f58..9365e8ca1c2 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2TaxGroupsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2TaxGroupsE2E.Codeunit.al @@ -23,6 +23,8 @@ codeunit 139808 "APIV2 - Tax Groups E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -288,4 +290,3 @@ codeunit 139808 "APIV2 - Tax Groups E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2TransferOrdersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2TransferOrdersE2E.Codeunit.al index 93bda0b6eed..365bab453ab 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2TransferOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2TransferOrdersE2E.Codeunit.al @@ -27,6 +27,8 @@ codeunit 139926 "APIV2 - Transfer Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a transfer order and use GET to retrieve it // [GIVEN] A transfer order LibraryWarehouse.CreateTransferLocations(FromLocation, ToLocation, InTransitLocation); @@ -51,6 +53,8 @@ codeunit 139926 "APIV2 - Transfer Orders E2E" ResponseText: Text; TargetURL: Text; begin + Initialize(); + // [SCENARIO] Create a transfer order and GET it by SystemId // [GIVEN] A transfer order LibraryWarehouse.CreateTransferLocations(FromLocation, ToLocation, InTransitLocation); @@ -77,6 +81,8 @@ codeunit 139926 "APIV2 - Transfer Orders E2E" TargetURL: Text; DimensionSetValue: Text; begin + Initialize(); + // [SCENARIO] GET a transfer order with $expand=dimensionSetLines // [GIVEN] A transfer order if not TransferHeader.FindFirst() then begin @@ -106,6 +112,8 @@ codeunit 139926 "APIV2 - Transfer Orders E2E" TargetURL: Text; AttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a transfer order with $expand=attachments // [GIVEN] A transfer order if not TransferHeader.FindFirst() then begin @@ -135,6 +143,8 @@ codeunit 139926 "APIV2 - Transfer Orders E2E" TargetURL: Text; DocumentAttachmentsValue: Text; begin + Initialize(); + // [SCENARIO] GET a transfer order with $expand=documentAttachments // [GIVEN] A transfer order if not TransferHeader.FindFirst() then begin @@ -164,6 +174,8 @@ codeunit 139926 "APIV2 - Transfer Orders E2E" TargetURL: Text; PdfDocumentValue: Text; begin + Initialize(); + // [SCENARIO] GET a transfer order with $expand=pdfDocument // [GIVEN] A transfer order if not TransferHeader.FindFirst() then begin @@ -193,6 +205,8 @@ codeunit 139926 "APIV2 - Transfer Orders E2E" TargetURL: Text; LinesValue: Text; begin + Initialize(); + // [SCENARIO] GET a transfer order with $expand=transferOrderLines // [GIVEN] A transfer order if not TransferHeader.FindFirst() then begin @@ -217,4 +231,8 @@ codeunit 139926 "APIV2 - Transfer Orders E2E" exit(TargetURL + '&$expand=' + ExpandValue); exit(TargetURL + '?$expand=' + ExpandValue); end; + + local procedure Initialize() + begin + end; } diff --git a/src/Apps/W1/APIV2/test/src/APIV2TrialBalanceE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2TrialBalanceE2E.Codeunit.al index f94f316fc30..023fc39870c 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2TrialBalanceE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2TrialBalanceE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139818 "APIV2 - Trial Balance E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -60,6 +61,8 @@ codeunit 139818 "APIV2 - Trial Balance E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; @@ -85,4 +88,3 @@ codeunit 139818 "APIV2 - Trial Balance E2E" - diff --git a/src/Apps/W1/APIV2/test/src/APIV2UofME2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2UofME2E.Codeunit.al index 496d746235c..478e8015d50 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2UofME2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2UofME2E.Codeunit.al @@ -24,6 +24,8 @@ codeunit 139812 "APIV2 - UofM E2E" UnitOfMeasure: Record "Unit of Measure"; Response: Text; begin + Initialize(); + // [SCENARIO] User can get the units of measure. // [GIVEN] Units of measure. @@ -44,6 +46,8 @@ codeunit 139812 "APIV2 - UofM E2E" Response: Text; OldDescription: Text; begin + Initialize(); + // [SCENARIO] User can update a unit of measure. // [GIVEN] Units of measure. @@ -73,6 +77,8 @@ codeunit 139812 "APIV2 - UofM E2E" UnitOfMeasure: Record "Unit of Measure"; Response: Text; begin + Initialize(); + // [SCENARIO] User can delete a unit of measure. // [GIVEN] Units of measure. @@ -94,6 +100,8 @@ codeunit 139812 "APIV2 - UofM E2E" Request: Text; "Code": Text; begin + Initialize(); + // [SCENARIO] User can insert a unit of measure. // [GIVEN] A new unit of measure. @@ -186,9 +194,12 @@ codeunit 139812 "APIV2 - UofM E2E" Format(UnitOfMeasure."International Standard Code"), InternationalStandardCode, StrSubstNo(WrongPropertyValueErr, 'internationalStandardCode')); end; -} - + local procedure Initialize() + begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + end; +} diff --git a/src/Apps/W1/APIV2/test/src/APIV2VendorPaymentsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2VendorPaymentsE2E.Codeunit.al index 0fc02556e63..a5829f148d9 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2VendorPaymentsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2VendorPaymentsE2E.Codeunit.al @@ -1,6 +1,7 @@ codeunit 139843 "APIV2 - Vendor Payments E2E" { Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; @@ -884,10 +885,12 @@ codeunit 139843 "APIV2 - Vendor Payments E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryTestInitialize.OnTestInitialize(Codeunit::"APIV2 - Vendor Payments E2E"); - if not isInitialized then + if not isInitialized then begin isInitialized := true; + end; LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"APIV2 - Vendor Payments E2E"); end; diff --git a/src/Apps/W1/APIV2/test/src/APIV2VendorsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2VendorsE2E.Codeunit.al index fe84521cbd5..85031db1df5 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2VendorsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2VendorsE2E.Codeunit.al @@ -25,6 +25,8 @@ codeunit 139803 "APIV2 - Vendors E2E" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + if IsInitialized then exit; diff --git a/src/Apps/W1/APIV2/test/src/APIV2WorkflowApproversE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2WorkflowApproversE2E.Codeunit.al index 4a11340aa53..c2590fdd939 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2WorkflowApproversE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2WorkflowApproversE2E.Codeunit.al @@ -1,6 +1,5 @@ codeunit 139920 "APIV2 - Workflow Approvers E2E" { - Subtype = Test; TestType = IntegrationTest; TestPermissions = Disabled; @@ -29,6 +28,8 @@ codeunit 139920 "APIV2 - Workflow Approvers E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO] Check that workflow approvers can be retrieved via API // [GIVEN] A workflow exists LibraryWorkflow.CreateWorkflow(Workflow); @@ -64,4 +65,8 @@ codeunit 139920 "APIV2 - Workflow Approvers E2E" Assert.IsTrue(LibraryGraphMgt.GetObjectIDFromJSON(ResponseText, 'userId', UserId), 'Could not find workflow approver'); end; + + local procedure Initialize() + begin + end; } \ No newline at end of file diff --git a/src/Apps/W1/APIV2/test/src/APIV2WorkflowsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2WorkflowsE2E.Codeunit.al index d5973d08348..288a90cd3d5 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2WorkflowsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2WorkflowsE2E.Codeunit.al @@ -1,6 +1,5 @@ codeunit 139921 "APIV2 - Workflows E2E" { - Subtype = Test; TestType = IntegrationTest; TestPermissions = Disabled; @@ -20,6 +19,8 @@ codeunit 139921 "APIV2 - Workflows E2E" TargetURL: Text; ResponseText: Text; begin + Initialize(); + // [SCENARIO] Check that workflows can be retrieved via API // [GIVEN] A workflow exists LibraryWorkflow.CreateWorkflow(Workflow); @@ -37,4 +38,8 @@ codeunit 139921 "APIV2 - Workflows E2E" Assert.IsTrue(LibraryGraphMgt.GetObjectIDFromJSON(ResponseText, 'id', WorkFlowId), 'Could not find workflow'); end; + + local procedure Initialize() + begin + end; } \ No newline at end of file diff --git a/src/Apps/W1/APIV2/test/src/APIV2itemLedgEntriesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2itemLedgEntriesE2E.Codeunit.al index f8f1374ccec..5c234b5cfed 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2itemLedgEntriesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2itemLedgEntriesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139854 "APIV2 - Item Ledg. Entries E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = IntegrationTest; TestPermissions = Disabled; @@ -25,6 +26,8 @@ codeunit 139854 "APIV2 - Item Ledg. Entries E2E" LibraryERMCountryData: Codeunit "Library - ERM Country Data"; LibraryApplicationArea: Codeunit "Library - Application Area"; begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); + LibraryApplicationArea.EnableFoundationSetup(); if IsInitialized then exit; @@ -121,4 +124,3 @@ codeunit 139854 "APIV2 - Item Ledg. Entries E2E" - diff --git a/src/Apps/W1/EDocument/Test/src/Processing/EDocAPITest.Codeunit.al b/src/Apps/W1/EDocument/Test/src/Processing/EDocAPITest.Codeunit.al index 80b678db590..1af70edba82 100644 --- a/src/Apps/W1/EDocument/Test/src/Processing/EDocAPITest.Codeunit.al +++ b/src/Apps/W1/EDocument/Test/src/Processing/EDocAPITest.Codeunit.al @@ -16,17 +16,20 @@ codeunit 135575 "E-Doc. API Test" TestType = IntegrationTest; TestPermissions = Disabled; + var + LibraryGraphMgt: Codeunit "Library - Graph Mgt"; + [Test] procedure GetEDocument() var PurchaseHeader: Record "Purchase Header"; EDocument: Record "E-Document"; - LibrarygraphMgt: Codeunit "Library - Graph Mgt"; TargetURL: Text; Response: Text; EDocsApiServiceNameTok: Label 'eDocuments', Locked = true; begin // [SCENARIO] Get E-Document from api page + Initialize(); // [GIVEN] Related document for e document CreatePurchaseHeader(PurchaseHeader); @@ -49,13 +52,13 @@ codeunit 135575 "E-Doc. API Test" EDocumentService: Record "E-Document Service"; Assert: Codeunit Assert; Any: Codeunit Any; - LibraryGraphMgt: Codeunit "Library - Graph Mgt"; JSONRequest: Text; TargetURL: Text; Response: Text; CreateEDocumentsServiceTxt: Label 'createEDocuments', Locked = true; begin // [SCENARIO] Create E-Document using api page + Initialize(); // [GIVEN] E-Document service EDocumentService.Init(); @@ -72,10 +75,13 @@ codeunit 135575 "E-Doc. API Test" Assert.AreEqual('', Response, 'Response should be empty.'); end; + local procedure Initialize() + begin + end; + local procedure VerifyEDocumentResponse(EDocument: Record "E-Document"; Response: Text) var Assert: Codeunit Assert; - LibraryGraphMgt: Codeunit "Library - Graph Mgt"; AmtInclVatTxt: Text; AmtExclVatTxt: Text; AmtInclVat: Decimal; @@ -152,8 +158,6 @@ codeunit 135575 "E-Doc. API Test" end; local procedure GetEDocumentCreateRequest(EDocumentServiceCode: Code[20]; var JSONRequest: Text) - var - LibraryGraphMgt: Codeunit "Library - Graph Mgt"; begin JSONRequest := LibraryGraphMgt.AddPropertytoJSON(JSONRequest, 'eDocumentService', EDocumentServiceCode); JSONRequest := LibraryGraphMgt.AddPropertytoJSON(JSONRequest, 'base64file', NavApp.GetResourceAsText('API/base64file.txt', TextEncoding::UTF8)); diff --git a/src/Apps/W1/ExpenseAgent/app/src/Travel Request/Codeunits/TravelRequestApproval.Codeunit.al b/src/Apps/W1/ExpenseAgent/app/src/Travel Request/Codeunits/TravelRequestApproval.Codeunit.al index b8ee5762dc7..8b290df2331 100644 --- a/src/Apps/W1/ExpenseAgent/app/src/Travel Request/Codeunits/TravelRequestApproval.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/app/src/Travel Request/Codeunits/TravelRequestApproval.Codeunit.al @@ -6,7 +6,6 @@ namespace Microsoft.ExpenseAgent; using Microsoft.Finance.SpendRequest; using System.Telemetry; -using System.Text; codeunit 7133 "Travel Request Approval" { @@ -318,13 +317,17 @@ codeunit 7133 "Travel Request Approval" var ExpenseApprovalSetup: Record "Expense Approval Setup"; ExpenseAgentSetup: Record "Expense Agent Setup"; - SelectionFilterManagement: Codeunit SelectionFilterManagement; - RecRef: RecordRef; + AssignedFilter: TextBuilder; begin ExpenseApprovalSetup.SetCurrentKey("Approver No."); ExpenseApprovalSetup.SetRange("Approver No.", ApproverExpenseUserNo); - RecRef.GetTable(ExpenseApprovalSetup); - RequestedForFilter := SelectionFilterManagement.GetSelectionFilter(RecRef, ExpenseApprovalSetup.FieldNo("Expense User No.")); + ExpenseApprovalSetup.SetLoadFields("Expense User No."); + // Ranges between setup rows could include expense users without any approval setup. + if ExpenseApprovalSetup.FindSet() then + repeat + AppendSubmitterFilter(AssignedFilter, ExpenseApprovalSetup."Expense User No."); + until ExpenseApprovalSetup.Next() = 0; + RequestedForFilter := AssignedFilter.ToText(); ExpenseAgentSetup.GetRecordOnce(); if ExpenseAgentSetup."Default Approver No." = ApproverExpenseUserNo then @@ -337,7 +340,6 @@ codeunit 7133 "Travel Request Approval" local procedure AppendDefaultSubmitters(var RequestedForFilter: Text) var ExpenseUser: Record "Expense User"; - SelectionFilterManagement: Codeunit SelectionFilterManagement; DefaultFilter: TextBuilder; begin if RequestedForFilter <> '' then @@ -348,14 +350,23 @@ codeunit 7133 "Travel Request Approval" ExpenseUser.SetLoadFields("No."); if ExpenseUser.FindSet() then repeat - if DefaultFilter.Length > 0 then - DefaultFilter.Append('|'); - DefaultFilter.Append(SelectionFilterManagement.AddQuotes(ExpenseUser."No.")); + AppendSubmitterFilter(DefaultFilter, ExpenseUser."No."); until ExpenseUser.Next() = 0; RequestedForFilter := DefaultFilter.ToText(); end; + local procedure AppendSubmitterFilter(var SubmitterFilter: TextBuilder; ExpenseUserNo: Code[20]) + var + ExpenseUserFilter: Record "Expense User"; + begin + // Serialize an exact value so filter operators in user numbers remain literal. + ExpenseUserFilter.SetRange("No.", ExpenseUserNo); + if SubmitterFilter.Length > 0 then + SubmitterFilter.Append('|'); + SubmitterFilter.Append(ExpenseUserFilter.GetFilter("No.")); + end; + var FeatureTelemetry: Codeunit "Feature Telemetry"; ExpenseActivityLogMgt: Codeunit "Expense Activity Log Mgt."; diff --git a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseActivityLogAPITest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseActivityLogAPITest.Codeunit.al index 90781c7634d..c88171be4d8 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseActivityLogAPITest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseActivityLogAPITest.Codeunit.al @@ -22,7 +22,6 @@ codeunit 148343 "Expense Activity Log API Test" LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; LibrarySetupStorage: Codeunit "Library - Setup Storage"; - APITestAuthHelper: Codeunit "Expense API Test Auth Helper"; IsInitialized: Boolean; ServiceNameTok: Label 'expenseActivityLogEntries', Locked = true; ExpenseReportsServiceNameTok: Label 'expenseReports', Locked = true; @@ -476,11 +475,14 @@ codeunit 148343 "Expense Activity Log API Test" RequestBody.WriteTo(RequestText); ReportURL := LibraryGraphMgt.CreateTargetURLWithSubpage( Format(SubmitterExpenseUser.SystemId), Page::"Expense Users API", ExpenseUsersServiceNameTok, ExpenseReportsServiceNameTok); - ReportURL += '(' + LibraryGraphMgt.StripBrackets(Format(ExpenseReportHeader.SystemId)) + ')'; + ReportURL := LibraryGraphMgt.AppendPathToTargetURL( + ReportURL, '(' + LibraryGraphMgt.StripBrackets(Format(ExpenseReportHeader.SystemId)) + ')'); Commit(); // [WHEN] The standard submission action is requested through the submitting user. - LibraryGraphMgt.PostToWebServiceAndCheckResponseCode(ReportURL + '/' + SubmitWithCommentActionTok, RequestText, ResponseText, 200); + Clear(ResponseText); + LibraryGraphMgt.PostToWebServiceAndCheckResponseCode( + LibraryGraphMgt.AppendPathToTargetURL(ReportURL, '/' + SubmitWithCommentActionTok), RequestText, ResponseText, 200); // [THEN] Exactly one structured snapshot is visible without a new callback or capability. ExpenseActivityLogEntry.SetRange("Subject System ID", ExpenseReportHeader.SystemId); @@ -488,7 +490,8 @@ codeunit 148343 "Expense Activity Log API Test" Assert.RecordCount(ExpenseActivityLogEntry, 1); ExpenseActivityLogEntry.FindFirst(); Clear(ResponseText); - LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, ReportURL + '/' + ServiceNameTok, 200); + LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode( + ResponseText, LibraryGraphMgt.AppendPathToTargetURL(ReportURL, '/' + ServiceNameTok), 200); VerifyPolicyCategoryCode(ResponseText, ExpenseCategory.Code); ResponseText := LowerCase(ResponseText); Assert.AreNotEqual(0, StrPos(ResponseText, '"eventtype":"policyevaluated"'), 'The event type must identify the policy snapshot.'); @@ -502,7 +505,8 @@ codeunit 148343 "Expense Activity Log API Test" HistoryURL := LibraryGraphMgt.CreateTargetURLWithSubpage( Format(SubmitterExpenseUser.SystemId), Page::"Expense Users API", ExpenseUsersServiceNameTok, ServiceNameTok); Clear(ResponseText); - LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, HistoryURL + '?$filter=historyActorRole eq ''Submitter''', 200); + LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode( + ResponseText, LibraryGraphMgt.AppendQueryParameterToTargetURL(HistoryURL, '$filter=historyActorRole eq ''Submitter'''), 200); // [THEN] The real submitter sees the agent snapshot in the complete timeline. Assert.AreNotEqual(0, StrPos(LowerCase(ResponseText), LowerCase(LibraryGraphMgt.StripBrackets(Format(ExpenseActivityLogEntry.SystemId)))), 'The submitter timeline must contain the snapshot.'); @@ -511,7 +515,8 @@ codeunit 148343 "Expense Activity Log API Test" HistoryURL := LibraryGraphMgt.CreateTargetURLWithSubpage( Format(ApproverExpenseUser.SystemId), Page::"Expense Users API", ExpenseUsersServiceNameTok, ServiceNameTok); Clear(ResponseText); - LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, HistoryURL + '?$filter=historyActorRole eq ''Approver''', 200); + LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode( + ResponseText, LibraryGraphMgt.AppendQueryParameterToTargetURL(HistoryURL, '$filter=historyActorRole eq ''Approver'''), 200); // [THEN] The agent event must not grant approver participation. Assert.AreEqual(0, StrPos(LowerCase(ResponseText), LowerCase(LibraryGraphMgt.StripBrackets(Format(ExpenseReportHeader.SystemId)))), 'The agent snapshot must not grant approver history access.'); @@ -803,7 +808,6 @@ codeunit 148343 "Expense Activity Log API Test" if IsInitialized then exit; - BindSubscription(APITestAuthHelper); LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Expense Activity Log API Test"); LibraryERMCountryData.UpdateGeneralLedgerSetup(); if not ExpenseAgentSetup.Get() then begin diff --git a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseCapabilitiesAPITest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseCapabilitiesAPITest.Codeunit.al index 4436c873d54..056859c9f9c 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseCapabilitiesAPITest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseCapabilitiesAPITest.Codeunit.al @@ -18,7 +18,6 @@ codeunit 148318 "Expense Capabilities API Test" LibraryExpenseAgent: Codeunit "Library - Expense Agent"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; - APITestAuthHelper: Codeunit "Expense API Test Auth Helper"; IsInitialized: Boolean; ServiceNameTok: Label 'expenseCapabilities', Locked = true; ActivityLogCapabilityNameTok: Label 'activityLog', Locked = true; @@ -104,8 +103,6 @@ codeunit 148318 "Expense Capabilities API Test" TargetURL: Text; ResponseText: Text; begin - // Excluded in BCApps CI until authenticated OData execution in a dedicated test company - // with disabled isolation is available; then remove this method's DisabledTest.json entry. // [SCENARIO] Travel requests are advertised when the supporting APIs are installed. Initialize(); @@ -248,7 +245,6 @@ codeunit 148318 "Expense Capabilities API Test" if IsInitialized then exit; - BindSubscription(APITestAuthHelper); LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Expense Capabilities API Test"); IsInitialized := true; Commit(); diff --git a/src/Apps/W1/ExpenseAgent/test/src/API/ExpensePerDiemLocationsTest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/API/ExpensePerDiemLocationsTest.Codeunit.al index 40fdf025b82..17ff4df8cfe 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/API/ExpensePerDiemLocationsTest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/API/ExpensePerDiemLocationsTest.Codeunit.al @@ -17,7 +17,6 @@ codeunit 148349 "Expense PerDiem Locations Test" LibraryUtility: Codeunit "Library - Utility"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; - APITestAuthHelper: Codeunit "Expense API Test Auth Helper"; IsInitialized: Boolean; [Test] @@ -82,11 +81,11 @@ codeunit 148349 "Expense PerDiem Locations Test" local procedure Initialize() begin + LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryTestInitialize.OnTestInitialize(Codeunit::"Expense PerDiem Locations Test"); if IsInitialized then exit; - BindSubscription(APITestAuthHelper); LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Expense PerDiem Locations Test"); IsInitialized := true; Commit(); diff --git a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseProjectsAPITest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseProjectsAPITest.Codeunit.al index 45ed9ae6d25..b7387da12b6 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseProjectsAPITest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseProjectsAPITest.Codeunit.al @@ -24,7 +24,6 @@ codeunit 148331 "Expense Projects API Test" LibraryHumanResource: Codeunit "Library - Human Resource"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; - APITestAuthHelper: Codeunit "Expense API Test Auth Helper"; IsInitialized: Boolean; ExpenseUsersServiceNameTok: Label 'expenseUsers', Locked = true; ProjectsServiceNameTok: Label 'expenseProjects', Locked = true; @@ -723,7 +722,6 @@ codeunit 148331 "Expense Projects API Test" if IsInitialized then exit; - BindSubscription(APITestAuthHelper); LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Expense Projects API Test"); if not ExpenseAgentSetup.Get() then begin ExpenseAgentSetup.Init(); diff --git a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseUsersAPITest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseUsersAPITest.Codeunit.al index f80c8eb6e80..f048ed31877 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseUsersAPITest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseUsersAPITest.Codeunit.al @@ -21,7 +21,6 @@ codeunit 148315 "Expense Users API Test" LibraryUtility: Codeunit "Library - Utility"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; - APITestAuthHelper: Codeunit "Expense API Test Auth Helper"; IsInitialized: Boolean; ServiceNameTok: Label 'expenseUsers', Locked = true; EmployeesServiceNameTok: Label 'employees', Locked = true; @@ -125,7 +124,6 @@ codeunit 148315 "Expense Users API Test" if IsInitialized then exit; - BindSubscription(APITestAuthHelper); LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Expense Users API Test"); if not ExpenseAgentSetup.Get() then begin ExpenseAgentSetup.Init(); diff --git a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseVATSpecAPITest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseVATSpecAPITest.Codeunit.al index 7c30f7723fa..99bad8bb916 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseVATSpecAPITest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/API/ExpenseVATSpecAPITest.Codeunit.al @@ -11,6 +11,7 @@ codeunit 148348 "Expense VAT Spec. API Test" { Subtype = Test; TestType = IntegrationTest; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; var @@ -19,7 +20,6 @@ codeunit 148348 "Expense VAT Spec. API Test" LibraryERM: Codeunit "Library - ERM"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; - APITestAuthHelper: Codeunit "Expense API Test Auth Helper"; IsInitialized: Boolean; ServiceNameTok: Label 'expenseVATSpecifications', Locked = true; @@ -89,7 +89,6 @@ codeunit 148348 "Expense VAT Spec. API Test" if IsInitialized then exit; - BindSubscription(APITestAuthHelper); LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Expense VAT Spec. API Test"); LibraryExpense.SetupNumberSeriesInExpenseMgmt(); LibraryERM.CreateVATBusinessPostingGroup(VATBusinessPostingGroup); diff --git a/src/Apps/W1/ExpenseAgent/test/src/API/PoliciesToEvaluateAPITest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/API/PoliciesToEvaluateAPITest.Codeunit.al index ef512122f3d..156bc8b877c 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/API/PoliciesToEvaluateAPITest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/API/PoliciesToEvaluateAPITest.Codeunit.al @@ -18,7 +18,6 @@ codeunit 148345 "Policies To Evaluate API Test" LibraryExpense: Codeunit "Library - Expense"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; - APITestAuthHelper: Codeunit "Expense API Test Auth Helper"; IsInitialized: Boolean; ExpenseReportLinesServiceNameTok: Label 'expenseReportLines', Locked = true; @@ -117,7 +116,6 @@ codeunit 148345 "Policies To Evaluate API Test" if IsInitialized then exit; - BindSubscription(APITestAuthHelper); LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Policies To Evaluate API Test"); LibraryERMCountryData.CreateVATData(); LibraryERMCountryData.UpdateGeneralPostingSetup(); diff --git a/src/Apps/W1/ExpenseAgent/test/src/API/PolicyEvaluationsAPITest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/API/PolicyEvaluationsAPITest.Codeunit.al index 97488f4294c..208a39d76dc 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/API/PolicyEvaluationsAPITest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/API/PolicyEvaluationsAPITest.Codeunit.al @@ -18,7 +18,6 @@ codeunit 148344 "Policy Evaluations API Test" LibraryExpense: Codeunit "Library - Expense"; LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; - APITestAuthHelper: Codeunit "Expense API Test Auth Helper"; IsInitialized: Boolean; ServiceNameTok: Label 'expensePolicyEvaluations', Locked = true; BadRequestResponseErr: Label 'Response code is 400', Locked = true; @@ -121,7 +120,6 @@ codeunit 148344 "Policy Evaluations API Test" if IsInitialized then exit; - BindSubscription(APITestAuthHelper); LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Policy Evaluations API Test"); LibraryERMCountryData.CreateVATData(); LibraryERMCountryData.UpdateGeneralPostingSetup(); diff --git a/src/Apps/W1/ExpenseAgent/test/src/API/TravelRequestsAPITest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/API/TravelRequestsAPITest.Codeunit.al index 2134bd14296..7657306c31b 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/API/TravelRequestsAPITest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/API/TravelRequestsAPITest.Codeunit.al @@ -10,12 +10,6 @@ using Microsoft.Finance.GeneralLedger.Setup; using Microsoft.Finance.SpendRequest; using Microsoft.HumanResources.Employee; -// These HTTP tests remain excluded in Expense_Agent_Tests.DisabledTest.json until the -// authentication prerequisite provides an authenticated OData endpoint and a dedicated -// test company with committed fixtures and disabled test isolation. -// In-process employee filtering, traveler mapping/navigation, lifecycle, date, and scope coverage -// in "Spend Request Test", and restrictive role coverage in "Expense Permissions Test", remain enabled. -// Only the HTTP scenarios are excluded. codeunit 148347 "Travel Requests API Test" { Subtype = Test; @@ -31,7 +25,6 @@ codeunit 148347 "Travel Requests API Test" LibraryHumanResource: Codeunit "Library - Human Resource"; LibraryRandom: Codeunit "Library - Random"; LibraryTestInitialize: Codeunit "Library - Test Initialize"; - APITestAuthHelper: Codeunit "Expense API Test Auth Helper"; IsInitialized: Boolean; ExpenseUsersServiceNameTok: Label 'expenseUsers', Locked = true; #if not CLEAN30 @@ -1291,7 +1284,6 @@ codeunit 148347 "Travel Requests API Test" if IsInitialized then exit; - BindSubscription(APITestAuthHelper); LibraryTestInitialize.OnBeforeTestSuiteInitialize(Codeunit::"Travel Requests API Test"); if not ExpenseAgentSetup.Get() then begin ExpenseAgentSetup.Init(); diff --git a/src/Apps/W1/ExpenseAgent/test/src/ExpensePermissionsTest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/ExpensePermissionsTest.Codeunit.al index aa05633221e..89ecec0c706 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/ExpensePermissionsTest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/ExpensePermissionsTest.Codeunit.al @@ -32,6 +32,9 @@ codeunit 148338 "Expense Permissions Test" AutomationPermissionSetTok: Label 'Exp. Auto Test', Locked = true; D365BasicPermissionSetTok: Label 'D365 BASIC', Locked = true; ExpenseAgentPermissionSetTok: Label 'Expense Agent', Locked = true; + DetailOnlyPermissionSetTok: Label 'Exp. Detail Test', Locked = true; + HeaderModifyPermissionErr: Label 'TableData %1 %2 IndirectModify', Comment = '%1 = Spend Request table ID, %2 = Spend Request table caption', Locked = true; + RequestMustBeOpenErr: Label 'The %1 %2 must have the status %3.', Comment = '%1 = document type description, %2 = document number, %3 = Open status'; ExpenseAgentAppIdTok: Label '66efe10c-8033-403b-a86d-77c0887178ba', Locked = true; ExpenseMgmtAdminPermissionSetTok: Label 'Expense Mgmt. Admin', Locked = true; SecurityPermissionSetTok: Label 'SECURITY', Locked = true; @@ -63,15 +66,100 @@ codeunit 148338 "Expense Permissions Test" [Test] procedure D365BasicCanUpdateTravelRequestDetailsIndirectly() begin + // [SCENARIO 646383] D365 BASIC applies successive detail amount deltas without direct header or detail writes. + Initialize(); VerifyTravelRequestDetailUpdateIndirectly(D365BasicPermissionSetTok); end; [Test] procedure ExpenseAgentCanUpdateTravelRequestDetailsIndirectly() begin + // [SCENARIO 646383] Expense Agent applies successive detail amount deltas without direct header or detail writes. + Initialize(); VerifyTravelRequestDetailUpdateIndirectly(ExpenseAgentPermissionSetTok); end; + [Test] + procedure DetailAmountUpdateFailsWithoutHeaderModifyPermission() + var + SpendRequest: Record "Spend Request"; + SpendRequestDetail: Record "Spend Request Detail"; + TravelRequestSubform: TestPage "Travel Request Subform"; + SpendRequestCanWrite: Boolean; + SpendRequestDetailCanWrite: Boolean; + PermissionErrorCode: Text; + PermissionErrorText: Text; + begin + // [SCENARIO 646383] A caller with only header read and indirect detail modify cannot update the header through an amount change. + Initialize(); + + // [GIVEN] An open request "R" with a committed detail "D" worth 10. + LibraryExpense.CreateSpendRequest(SpendRequest); + LibraryExpense.CreateSpendRequestDetail(SpendRequestDetail, SpendRequest."No.", 10); + VerifyTravelRequestAmounts(SpendRequest, SpendRequestDetail, 10); + Commit(); + LibraryLowerPermissions.StartLoggingNAVPermissions(); + LibraryLowerPermissions.SetExactPermissionSet(DetailOnlyPermissionSetTok); + SpendRequestCanWrite := SpendRequest.WritePermission(); + SpendRequestDetailCanWrite := SpendRequestDetail.WritePermission(); + TravelRequestSubform.OpenEdit(); + TravelRequestSubform.GoToRecord(SpendRequestDetail); + + // [WHEN] The caller changes the amount through the public page. + asserterror TravelRequestSubform.Amount.SetValue(20); + PermissionErrorCode := GetLastErrorCode(); + PermissionErrorText := GetLastErrorText(); + TravelRequestSubform.Close(); + RestoreFullPermissions(); + LibraryLowerPermissions.StopLoggingNAVPermissions(); + + // [THEN] The page reports the specific header modify denial and neither record changes. + VerifyCapturedPageError(PermissionErrorCode, PermissionErrorText, + StrSubstNo(HeaderModifyPermissionErr, Database::"Spend Request", SpendRequest.TableCaption())); + Assert.IsFalse(SpendRequestCanWrite, 'The caller must not have direct request write permission.'); + Assert.IsFalse(SpendRequestDetailCanWrite, 'The caller must not have direct detail write permission.'); + VerifyTravelRequestAmounts(SpendRequest, SpendRequestDetail, 10); + end; + + [Test] + procedure ReleasedTravelRequestDetailAmountCannotBeUpdatedIndirectly() + var + SpendRequest: Record "Spend Request"; + SpendRequestDetail: Record "Spend Request Detail"; + TravelRequestSubform: TestPage "Travel Request Subform"; + ValidationErrorCode: Text; + ValidationErrorText: Text; + begin + // [SCENARIO 646383] Indirect header modification does not bypass the Open status guard. + Initialize(); + + // [GIVEN] A released request "R" with a committed detail "D" worth 10. + LibraryExpense.CreateSpendRequest(SpendRequest); + LibraryExpense.CreateSpendRequestDetail(SpendRequestDetail, SpendRequest."No.", 10); + VerifyTravelRequestAmounts(SpendRequest, SpendRequestDetail, 10); + LibraryExpense.SetSpendRequestStatus(SpendRequest, SpendRequest.Status::Released); + Commit(); + LibraryLowerPermissions.StartLoggingNAVPermissions(); + LibraryLowerPermissions.SetExactPermissionSet(ExpenseAgentPermissionSetTok); + TravelRequestSubform.OpenEdit(); + TravelRequestSubform.GoToRecord(SpendRequestDetail); + + // [WHEN] The caller changes the amount through the public page. + asserterror TravelRequestSubform.Amount.SetValue(20); + ValidationErrorCode := GetLastErrorCode(); + ValidationErrorText := GetLastErrorText(); + TravelRequestSubform.Close(); + RestoreFullPermissions(); + LibraryLowerPermissions.StopLoggingNAVPermissions(); + + // [THEN] The status guard rejects the change and the released request retains both amounts. + VerifyCapturedPageError(ValidationErrorCode, ValidationErrorText, + StrSubstNo(RequestMustBeOpenErr, SpendRequest.GetDocumentTypeDescription(), SpendRequest."No.", SpendRequest.Status::Open)); + VerifyTravelRequestAmounts(SpendRequest, SpendRequestDetail, 10); + SpendRequest.Get(SpendRequest."No."); + Assert.AreEqual(SpendRequest.Status::Released, SpendRequest.Status, 'The denied amount change must preserve the Released status.'); + end; + [Test] procedure D365BasicCanInsertActivityIndirectly() begin @@ -139,20 +227,29 @@ codeunit 148338 "Expense Permissions Test" ExpenseUser: Record "Expense User"; Approver: Record "Expense User"; TravelRequestApproval: Codeunit "Travel Request Approval"; + ExpenseUserCanRead: Boolean; + PermissionErrorCode: Text; + PermissionErrorText: Text; begin // [SCENARIO] An employee-only caller cannot approve requests without access to Expense User data. Initialize(); CreateTravelRequestApprovalScenario(SpendRequest, ExpenseUser, Approver); + // Preserve the fixture for the post-denial checks when asserterror rolls back. Commit(); LibraryLowerPermissions.StartLoggingNAVPermissions(); - SetCallerPermissions(EmployeeOnlyPermissionSetTok, ExpenseUser); + LibraryLowerPermissions.SetExactPermissionSet(EmployeeOnlyPermissionSetTok); + ExpenseUserCanRead := ExpenseUser.ReadPermission(); asserterror TravelRequestApproval.Approve(SpendRequest, Approver."No."); - Assert.ExpectedErrorCode('DB:ClientReadDenied'); - Assert.ExpectedError(ExpenseUser.TableCaption()); + // Capture the denial before permission cleanup can change the last-error state. + PermissionErrorCode := GetLastErrorCode(); + PermissionErrorText := GetLastErrorText(); RestoreFullPermissions(); LibraryLowerPermissions.StopLoggingNAVPermissions(); + Assert.AreEqual('DB:ClientReadDenied', PermissionErrorCode, 'Approval must fail because Expense User read access is denied.'); + Assert.ExpectedMessage(ExpenseUser.TableCaption(), PermissionErrorText); + Assert.IsFalse(ExpenseUserCanRead, 'The caller must not have direct access to Expense User.'); SpendRequest.Get(SpendRequest."No."); Assert.AreEqual(SpendRequest.Status::Released, SpendRequest.Status, 'A denied approval must preserve the request status.'); ExpenseReportHeader.SetRange("Spend Request No.", SpendRequest."No."); @@ -563,8 +660,7 @@ codeunit 148338 "Expense Permissions Test" SpendRequestDetail: Record "Spend Request Detail"; TravelRequestSubform: TestPage "Travel Request Subform"; begin - // [SCENARIO] Editing a detail through its page can update both the line and its header total. - Initialize(); + // [GIVEN] An open request "R" with a detail "D" worth 10. LibraryExpense.CreateSpendRequest(SpendRequest); LibraryExpense.CreateSpendRequestDetail(SpendRequestDetail, SpendRequest."No.", 10); @@ -583,10 +679,41 @@ codeunit 148338 "Expense Permissions Test" LibraryLowerPermissions.StopLoggingNAVPermissions(); // [THEN] Both the line change and the base table's header update are persisted. + VerifyTravelRequestAmounts(SpendRequest, SpendRequestDetail, 20); + + // [GIVEN] The same exact role still has no direct writes after the first update. + LibraryLowerPermissions.StartLoggingNAVPermissions(); + LibraryLowerPermissions.SetExactPermissionSet(PermissionSetId); + Assert.IsFalse(SpendRequest.WritePermission(), 'The caller must not have direct request write permission.'); + Assert.IsFalse(SpendRequestDetail.WritePermission(), 'The caller must not have direct detail write permission.'); + + // [WHEN] The persisted detail amount is increased again from 20 to 30. + Clear(TravelRequestSubform); + TravelRequestSubform.OpenEdit(); + TravelRequestSubform.GoToRecord(SpendRequestDetail); + TravelRequestSubform.Amount.SetValue(30); + TravelRequestSubform.Close(); + RestoreFullPermissions(); + LibraryLowerPermissions.StopLoggingNAVPermissions(); + + // [THEN] The second update applies only its delta, not the entire new amount. + VerifyTravelRequestAmounts(SpendRequest, SpendRequestDetail, 30); + end; + + local procedure VerifyTravelRequestAmounts(var SpendRequest: Record "Spend Request"; var SpendRequestDetail: Record "Spend Request Detail"; ExpectedAmount: Decimal) + begin SpendRequestDetail.Get(SpendRequestDetail."Spend Request No.", SpendRequestDetail."Line No."); SpendRequest.Get(SpendRequest."No."); - Assert.AreEqual(20, SpendRequestDetail."Expected Amount", 'The detail amount must be updated through indirect permissions.'); - Assert.AreEqual(20, SpendRequest."Total Expected Amount (LCY)", 'The detail update must also update the header total.'); + Assert.AreEqual(ExpectedAmount, SpendRequestDetail."Expected Amount", 'The detail amount must match the page operation.'); + Assert.AreEqual(ExpectedAmount, SpendRequestDetail."Expected Amount (LCY)", 'The LCY detail amount must match the page operation.'); + Assert.AreEqual(ExpectedAmount, SpendRequest."Total Expected Amount", 'The request amount must reflect the detail delta exactly once.'); + Assert.AreEqual(ExpectedAmount, SpendRequest."Total Expected Amount (LCY)", 'The LCY request amount must reflect the detail delta exactly once.'); + end; + + local procedure VerifyCapturedPageError(ErrorCode: Text; ErrorText: Text; ExpectedErrorText: Text) + begin + Assert.AreEqual('TestValidation', ErrorCode, 'The amount field must fail through the TestPage validation wrapper.'); + Assert.ExpectedMessage(ExpectedErrorText, ErrorText); end; local procedure VerifyCompanyEmailSynchronization(PermissionSetId: Code[20]) diff --git a/src/Apps/W1/ExpenseAgent/test/src/Helper/ExpenseAPITestAuthHelper.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/Helper/ExpenseAPITestAuthHelper.Codeunit.al deleted file mode 100644 index 4e34344be7a..00000000000 --- a/src/Apps/W1/ExpenseAgent/test/src/Helper/ExpenseAPITestAuthHelper.Codeunit.al +++ /dev/null @@ -1,61 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ -namespace Microsoft.Test.ExpenseAgent; - -using System.Azure.KeyVault; -using System.Environment; -using System.Integration; -using System.Security.AccessControl; - -/// -/// Test-only authentication helper for the API test codeunits in this app. -/// -codeunit 148332 "Expense API Test Auth Helper" -{ - Access = Internal; - EventSubscriberInstance = Manual; - - var - NavServerUserPasswordKeyTok: Label 'NavServerUserPassword', Locked = true; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"Library - Graph Mgt", OnAfterInitializeWebRequestWithURL, '', false, false)] - local procedure OnAfterInitializeWebRequest(var HttpWebRequestMgt: Codeunit "Http Web Request Mgt.") - var - Password: SecretText; - begin - if not ShouldInjectBasicAuth() then - exit; - if not TryGetPassword(Password) then - exit; - HttpWebRequestMgt.AddBasicAuthentication(UserId(), Password); - end; - - local procedure ShouldInjectBasicAuth(): Boolean - var - User: Record User; - EnvironmentInfo: Codeunit "Environment Information"; - begin - if EnvironmentInfo.IsSaaSInfrastructure() then - exit(false); - - // If the current user authenticates via Windows - if not User.Get(UserSecurityId()) then - exit(false); - if User."Windows Security ID" <> '' then - exit(false); - - // Inject Basic auth when using username password authentication. - exit(true); - end; - - [TryFunction] - local procedure TryGetPassword(var Password: SecretText) - var - AzureKeyVault: Codeunit "Azure Key Vault"; - begin - AzureKeyVault.GetAzureKeyVaultSecret(NavServerUserPasswordKeyTok, Password); - end; -} - diff --git a/src/Apps/W1/ExpenseAgent/test/src/Permissions/ExpDetailTest.PermissionSet.al b/src/Apps/W1/ExpenseAgent/test/src/Permissions/ExpDetailTest.PermissionSet.al new file mode 100644 index 00000000000..9b2f1c33517 --- /dev/null +++ b/src/Apps/W1/ExpenseAgent/test/src/Permissions/ExpDetailTest.PermissionSet.al @@ -0,0 +1,20 @@ +// ------------------------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// ------------------------------------------------------------------------------------------------ +namespace Microsoft.Test.ExpenseAgent; + +using Microsoft.Finance.SpendRequest; +using System.Security.AccessControl; + +permissionset 148303 "Exp. Detail Test" +{ + Access = Internal; + Assignable = false; + IncludedPermissionSets = "D365 READ"; + + // Keep the header read-only, while allowing the page to modify a detail indirectly. + Permissions = tabledata "Spend Request Detail" = m, + codeunit Assert = X, + codeunit "Library - Lower Permissions" = X; +} diff --git a/src/Apps/W1/ExpenseAgent/test/src/SpendRequestTest.Codeunit.al b/src/Apps/W1/ExpenseAgent/test/src/SpendRequestTest.Codeunit.al index b18c4701d05..c93fa9338d1 100644 --- a/src/Apps/W1/ExpenseAgent/test/src/SpendRequestTest.Codeunit.al +++ b/src/Apps/W1/ExpenseAgent/test/src/SpendRequestTest.Codeunit.al @@ -62,6 +62,8 @@ codeunit 148339 "Spend Request Test" UnassignedTravelRequestHiddenMsg: Label 'The approver should not see a travel request assigned to another approver.'; DefaultTravelRequestVisibleMsg: Label 'The default approver should see travel requests without an assigned approver.'; ApproverWithoutRequestsMsg: Label 'An approver without assigned travel requests should receive an empty result.'; + ApproverFilterExpectedRequestErr: Label '%1 Requested For filter: %2. Expected request: %3.', Comment = '%1 = assertion message, %2 = Requested For filter, %3 = expected request number'; + ApproverFilterUnexpectedRequestErr: Label '%1 Requested For filter: %2. Expected request: %3. Unauthorized request: %4.', Comment = '%1 = assertion message, %2 = Requested For filter, %3 = expected request number, %4 = unauthorized request number'; SpendReqNoSetMsg: Label 'The Spend Request No. should be assigned to the expense report line.'; HeaderSpendReqNoSetMsg: Label 'The Spend Request No. should be assigned to the expense report header.'; HeaderCloseFlagMsg: Label 'The header should store the confirmed close flag.'; @@ -1877,21 +1879,108 @@ codeunit 148339 "Spend Request Test" procedure ApproverFilterReturnsDefaultApproverTravelRequests() begin // [SCENARIO] The default approver sees requests without an explicit approval assignment. - VerifyDefaultApproverFilter('', ''); + Initialize(); + + VerifyDefaultApproverFilter('', '', true); end; [Test] procedure DefaultApproverFilterQuotesWildcardUserNo() begin // [SCENARIO] A literal wildcard user number must not expose another approver's requests. - VerifyDefaultApproverFilter('*', 'TR-OTHER'); + Initialize(); + + VerifyDefaultApproverFilter('*', 'TR-OTHER', true); end; [Test] procedure DefaultApproverFilterQuotesPipeUserNo() begin // [SCENARIO] A pipe in a user number must not become an OR filter for other users. - VerifyDefaultApproverFilter('TR-A|TR-B', 'TR-A'); + Initialize(); + + VerifyDefaultApproverFilter('TR-A|TR-B', 'TR-A', true); + end; + + [Test] + procedure ApproverFilterQuotesExplicitWildcardUserNo() + begin + // [SCENARIO] An explicitly assigned literal wildcard user must not expose another approver's requests. + Initialize(); + + VerifyDefaultApproverFilter('*', 'TR-OTHER', false); + end; + + [Test] + procedure ApproverFilterQuotesExplicitPipeUserNo() + begin + // [SCENARIO] An explicitly assigned user with a pipe in its number must not expose another approver's requests. + Initialize(); + + VerifyDefaultApproverFilter('TR-A|TR-B', 'TR-A', false); + end; + + [Test] + procedure ApproverFilterDoesNotIncludeUnassignedUserBetweenAssignedUsers() + var + FirstTravelRequest: Record "Spend Request"; + LastTravelRequest: Record "Spend Request"; + UnassignedTravelRequest: Record "Spend Request"; + FilteredTravelRequest: Record "Spend Request"; + FirstExpenseUser: Record "Expense User"; + LastExpenseUser: Record "Expense User"; + UnassignedExpenseUser: Record "Expense User"; + AssignedApprover: Record "Expense User"; + DefaultApprover: Record "Expense User"; + ExpenseApprovalSetup: Record "Expense Approval Setup"; + TravelRequestApproval: Codeunit "Travel Request Approval"; + begin + // [SCENARIO] Adjacent approval setups must not expose a user between them who belongs to another default approver. + Initialize(); + + // [GIVEN] Approver "A" and default approver "B", with their user numbers outside the tested range. + ExpenseApprovalSetup.DeleteAll(); + LibraryExpense.UpdateEnableAgentInAgentSetup(true); + CreateApprover(AssignedApprover); + AssignedApprover.Rename('FILTER-APP-A'); + CreateApprover(DefaultApprover); + DefaultApprover.Rename('FILTER-APP-B'); + SetDefaultApprover(DefaultApprover."No."); + + // [GIVEN] Released requests for "TR-A" and "TR-C" explicitly assigned to "A". + CreateReleasableSpendRequest(FirstTravelRequest, FirstExpenseUser); + FirstExpenseUser.Rename('TR-A'); + FirstTravelRequest.Get(FirstTravelRequest."No."); + LibraryExpense.SetSpendRequestStatus(FirstTravelRequest, FirstTravelRequest.Status::Released); + ExpenseApprovalSetup.Get(FirstExpenseUser."No."); + ExpenseApprovalSetup.Validate("Approver No.", AssignedApprover."No."); + ExpenseApprovalSetup.Modify(true); + CreateReleasableSpendRequest(LastTravelRequest, LastExpenseUser); + LastExpenseUser.Rename('TR-C'); + LastTravelRequest.Get(LastTravelRequest."No."); + LibraryExpense.SetSpendRequestStatus(LastTravelRequest, LastTravelRequest.Status::Released); + ExpenseApprovalSetup.Get(LastExpenseUser."No."); + ExpenseApprovalSetup.Validate("Approver No.", AssignedApprover."No."); + ExpenseApprovalSetup.Modify(true); + + // [GIVEN] A released request for "TR-B" with no setup, so it belongs to default approver "B". + CreateReleasableSpendRequest(UnassignedTravelRequest, UnassignedExpenseUser); + UnassignedExpenseUser.Rename('TR-B'); + UnassignedTravelRequest.Get(UnassignedTravelRequest."No."); + LibraryExpense.SetSpendRequestStatus(UnassignedTravelRequest, UnassignedTravelRequest.Status::Released); + ExpenseApprovalSetup.Get(UnassignedExpenseUser."No."); + ExpenseApprovalSetup.Delete(true); + VerifyApproverFilterRangeGapSetup( + FirstTravelRequest, LastTravelRequest, UnassignedTravelRequest, AssignedApprover."No.", DefaultApprover."No."); + + // [WHEN] "A"'s filter is applied to pending travel requests. + FilteredTravelRequest.SetRange("Document Type", FilteredTravelRequest."Document Type"::"Travel Request"); + FilteredTravelRequest.SetRange(Status, FilteredTravelRequest.Status::Released); + TravelRequestApproval.ApplyApproverFilter(FilteredTravelRequest, AssignedApprover.SystemId); + + // [THEN] The requests for "TR-A" and "TR-C" are visible, but the request for "TR-B" is hidden. + VerifyApproverFilterRangeGapResults( + FilteredTravelRequest, FirstTravelRequest."No.", LastTravelRequest."No.", UnassignedTravelRequest."No."); end; [Test] @@ -3173,7 +3262,7 @@ codeunit 148339 "Spend Request Test" ExpenseAgentSetup.Modify(true); end; - local procedure VerifyDefaultApproverFilter(DefaultExpenseUserNo: Code[20]; OtherExpenseUserNo: Code[20]) + local procedure VerifyDefaultApproverFilter(DefaultExpenseUserNo: Code[20]; OtherExpenseUserNo: Code[20]; UseDefaultFallback: Boolean) var DefaultTravelRequest: Record "Spend Request"; OtherTravelRequest: Record "Spend Request"; @@ -3182,11 +3271,13 @@ codeunit 148339 "Spend Request Test" OtherExpenseUser: Record "Expense User"; DefaultApprover: Record "Expense User"; OtherApprover: Record "Expense User"; + ExpenseApprovalSetup: Record "Expense Approval Setup"; TravelRequestApproval: Codeunit "Travel Request Approval"; + ExpectedApproverNo: Code[20]; begin - Initialize(); - - // [GIVEN] A default approver, an unassigned request, and a request assigned to another approver. + // [GIVEN] Default approver "A", a request for "U", and another request assigned to approver "B". + // Initialize deletes expense users without their OnDelete trigger, leaving approval setups behind. + ExpenseApprovalSetup.DeleteAll(); LibraryExpense.UpdateEnableAgentInAgentSetup(true); CreateApprover(DefaultApprover); SetDefaultApprover(DefaultApprover."No."); @@ -3194,28 +3285,93 @@ codeunit 148339 "Spend Request Test" if DefaultExpenseUserNo <> '' then begin DefaultExpenseUser.Rename(DefaultExpenseUserNo); DefaultTravelRequest.Get(DefaultTravelRequest."No."); - DefaultTravelRequest.TestField("Requested For", DefaultExpenseUserNo); + Assert.AreEqual(DefaultExpenseUserNo, DefaultTravelRequest."Requested For", 'The request must retain the literal renamed user number.'); end; LibraryExpense.SetSpendRequestStatus(DefaultTravelRequest, DefaultTravelRequest.Status::Released); CreateReleasableSpendRequest(OtherTravelRequest, OtherExpenseUser); if OtherExpenseUserNo <> '' then begin OtherExpenseUser.Rename(OtherExpenseUserNo); OtherTravelRequest.Get(OtherTravelRequest."No."); - OtherTravelRequest.TestField("Requested For", OtherExpenseUserNo); + Assert.AreEqual(OtherExpenseUserNo, OtherTravelRequest."Requested For", 'The other request must retain the literal renamed user number.'); end; CreateApproverForExpenseUser(OtherApprover, OtherExpenseUser); LibraryExpense.SetSpendRequestStatus(OtherTravelRequest, OtherTravelRequest.Status::Released); + // [GIVEN] "U" is either explicitly assigned to "A" or has no setup and must use the default fallback. + // Both setting the default approver and inserting expense users create explicit assignments. + ExpenseApprovalSetup.Get(DefaultExpenseUser."No."); + Assert.AreEqual(DefaultApprover."No.", ExpenseApprovalSetup."Approver No.", 'The initial fixture must exercise the explicit-assignment path.'); + ExpectedApproverNo := DefaultApprover."No."; + if UseDefaultFallback then begin + ExpenseApprovalSetup.Delete(true); + ExpectedApproverNo := ''; + end; + DefaultExpenseUser.CalcFields("Approver No."); + Assert.AreEqual(ExpectedApproverNo, DefaultExpenseUser."Approver No.", 'The fixture must select the intended explicit-assignment or default-fallback path.'); + ExpenseApprovalSetup.Get(OtherExpenseUser."No."); + Assert.AreEqual(OtherApprover."No.", ExpenseApprovalSetup."Approver No.", 'The other request must remain explicitly assigned to another approver.'); + // [WHEN] The default approver's filter is applied to pending travel requests. FilteredTravelRequest.SetRange("Document Type", FilteredTravelRequest."Document Type"::"Travel Request"); FilteredTravelRequest.SetRange(Status, FilteredTravelRequest.Status::Released); TravelRequestApproval.ApplyApproverFilter(FilteredTravelRequest, DefaultApprover.SystemId); - // [THEN] Only the literal unassigned user's request is visible, not the other approver's request. + // [THEN] Only "U"'s literal request is visible, not the request assigned to "B". FilteredTravelRequest.SetRange("No.", DefaultTravelRequest."No."); - Assert.IsFalse(FilteredTravelRequest.IsEmpty(), DefaultTravelRequestVisibleMsg); + Assert.IsFalse( + FilteredTravelRequest.IsEmpty(), + StrSubstNo(ApproverFilterExpectedRequestErr, + DefaultTravelRequestVisibleMsg, FilteredTravelRequest.GetFilter("Requested For"), DefaultTravelRequest."No.")); FilteredTravelRequest.SetRange("No.", OtherTravelRequest."No."); - Assert.IsTrue(FilteredTravelRequest.IsEmpty(), UnassignedTravelRequestHiddenMsg); + Assert.IsTrue( + FilteredTravelRequest.IsEmpty(), + StrSubstNo(ApproverFilterUnexpectedRequestErr, + UnassignedTravelRequestHiddenMsg, FilteredTravelRequest.GetFilter("Requested For"), + DefaultTravelRequest."No.", OtherTravelRequest."No.")); + end; + + local procedure VerifyApproverFilterRangeGapSetup(FirstTravelRequest: Record "Spend Request"; LastTravelRequest: Record "Spend Request"; UnassignedTravelRequest: Record "Spend Request"; AssignedApproverNo: Code[20]; DefaultApproverNo: Code[20]) + var + ExpenseApprovalSetup: Record "Expense Approval Setup"; + ExpenseAgentSetup: Record "Expense Agent Setup"; + ExpenseUser: Record "Expense User"; + begin + Assert.AreEqual('TR-A', FirstTravelRequest."Requested For", 'The first request must use the lower range endpoint.'); + Assert.AreEqual('TR-C', LastTravelRequest."Requested For", 'The last request must use the upper range endpoint.'); + Assert.AreEqual('TR-B', UnassignedTravelRequest."Requested For", 'The unassigned request must lie between the assigned users.'); + ExpenseApprovalSetup.Get(FirstTravelRequest."Requested For"); + Assert.AreEqual(AssignedApproverNo, ExpenseApprovalSetup."Approver No.", 'The first user must be explicitly assigned.'); + ExpenseApprovalSetup.Get(LastTravelRequest."Requested For"); + Assert.AreEqual(AssignedApproverNo, ExpenseApprovalSetup."Approver No.", 'The last user must have the same explicit approver.'); + Assert.IsFalse(ExpenseApprovalSetup.Get(UnassignedTravelRequest."Requested For"), 'The middle user must have no approval setup row.'); + ExpenseUser.Get(UnassignedTravelRequest."Requested For"); + ExpenseUser.CalcFields("Approver No."); + Assert.AreEqual('', ExpenseUser."Approver No.", 'The middle user must use the default approver fallback.'); + ExpenseAgentSetup.Get(); + Assert.AreEqual(DefaultApproverNo, ExpenseAgentSetup."Default Approver No.", 'The middle user must belong to the other default approver.'); + Assert.AreNotEqual(AssignedApproverNo, DefaultApproverNo, 'The explicit and default approvers must differ.'); + ExpenseApprovalSetup.SetRange("Expense User No.", FirstTravelRequest."Requested For", LastTravelRequest."Requested For"); + Assert.AreEqual(2, ExpenseApprovalSetup.Count(), 'Only the two assigned setup rows may exist in the tested range.'); + end; + + local procedure VerifyApproverFilterRangeGapResults(var FilteredTravelRequest: Record "Spend Request"; FirstTravelRequestNo: Code[20]; LastTravelRequestNo: Code[20]; UnassignedTravelRequestNo: Code[20]) + begin + FilteredTravelRequest.SetRange("No.", FirstTravelRequestNo); + Assert.IsFalse( + FilteredTravelRequest.IsEmpty(), + StrSubstNo(ApproverFilterExpectedRequestErr, + AssignedTravelRequestVisibleMsg, FilteredTravelRequest.GetFilter("Requested For"), FirstTravelRequestNo)); + FilteredTravelRequest.SetRange("No.", LastTravelRequestNo); + Assert.IsFalse( + FilteredTravelRequest.IsEmpty(), + StrSubstNo(ApproverFilterExpectedRequestErr, + AssignedTravelRequestVisibleMsg, FilteredTravelRequest.GetFilter("Requested For"), LastTravelRequestNo)); + FilteredTravelRequest.SetRange("No.", UnassignedTravelRequestNo); + Assert.IsTrue( + FilteredTravelRequest.IsEmpty(), + StrSubstNo(ApproverFilterUnexpectedRequestErr, + UnassignedTravelRequestHiddenMsg, FilteredTravelRequest.GetFilter("Requested For"), + FirstTravelRequestNo, UnassignedTravelRequestNo)); end; local procedure VerifyPostedTravelRequestHistory(SpendRequest: Record "Spend Request"; ExpectedPostedExpenseReportHeader: Record "Posted Expense Report Header") diff --git a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIFinanceTest.Codeunit.al b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIFinanceTest.Codeunit.al index c3d532f3176..2eb389b3835 100644 --- a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIFinanceTest.Codeunit.al +++ b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIFinanceTest.Codeunit.al @@ -49,6 +49,10 @@ codeunit 139876 "E2E PowerBI Finance Test" PowerBIAPIEndpoints: Enum "PowerBI API Endpoints"; ResponseEmptyErr: Label 'Response should not be empty.'; + local procedure Initialize() + begin + end; + [Test] procedure TestGetVendorLedgerEntry() var @@ -61,6 +65,8 @@ codeunit 139876 "E2E PowerBI Finance Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A purchase invoice is posted with vendor ledger entry and detailed vendor ledger entry LibPurch.CreatePurchaseInvoice(PurchHeader); PurchInvHeader.Get(LibPurch.PostPurchaseDocument(PurchHeader, true, true)); @@ -150,6 +156,8 @@ codeunit 139876 "E2E PowerBI Finance Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A sales invoice is posted with customer ledger entry and detailed customer ledger entry LibSales.CreateSalesInvoice(SalesHeader); SalesInvHeader.Get(LibSales.PostSalesDocument(SalesHeader, true, true)); @@ -235,6 +243,8 @@ codeunit 139876 "E2E PowerBI Finance Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A G/L account is created LibERM.CreateGLAccount(GLAccount); Commit(); @@ -273,6 +283,8 @@ codeunit 139876 "E2E PowerBI Finance Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A G/L account category is created LibERM.CreateGLAccountCategory(GLAccountCategory); Commit(); @@ -308,6 +320,8 @@ codeunit 139876 "E2E PowerBI Finance Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A G/L budget is created LibERM.CreateGLBudgetName(GLBudgetName); @@ -343,6 +357,8 @@ codeunit 139876 "E2E PowerBI Finance Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] G/L budget entries are created LibERM.CreateGLBudgetName(GLBudgetName); LibERM.CreateGLBudgetEntry(GLBudgetEntry, WorkDate(), LibERM.CreateGLAccountNo(), GLBudgetName.Name); @@ -393,6 +409,8 @@ codeunit 139876 "E2E PowerBI Finance Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] General journal lines for income statement account is posted, with one line outside the date range PowerBICoreTest.AssignAdminPermissionSet(); if not PBISetup.Get() then begin @@ -442,6 +460,8 @@ codeunit 139876 "E2E PowerBI Finance Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] General journal lines for account is posted CreateGeneralJournalBatch(GenJournalBatch, GLAccount); GLAccount."Income/Balance" := GLAccount."Income/Balance"::"Balance Sheet"; @@ -478,6 +498,8 @@ codeunit 139876 "E2E PowerBI Finance Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] G/L Account and Entry outside of the query filter are created GLAccount.Init(); GLAccount."No." := LibUtility.GenerateRandomCode20(GLAccount.FieldNo("No."), Database::"G/L Account"); diff --git a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIInventoryTest.Codeunit.al b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIInventoryTest.Codeunit.al index 4260437c799..c36ed1d5ffb 100644 --- a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIInventoryTest.Codeunit.al +++ b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIInventoryTest.Codeunit.al @@ -67,6 +67,10 @@ codeunit 139877 "E2E PowerBI Inventory Test" PowerBIAPIEndpoints: Enum "PowerBI API Endpoints"; ResponseEmptyErr: Label 'Response should not be empty.'; + local procedure Initialize() + begin + end; + [Test] procedure TestGetZones() var @@ -76,6 +80,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A location with multiple zones is created LibWhse.CreateFullWMSLocation(Location, 1); Zone.SetRange("Location Code", Location.Code); @@ -116,6 +122,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A bin is created LibWhse.CreateLocation(Location); LibWhse.CreateBin(Bin, Location.Code, '', '', ''); @@ -160,6 +168,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A sales order is created with multiple types of sales lines LibSales.CreateSalesOrder(SalesHeader); LibInv.CreateItemWithUnitPriceAndUnitCost( @@ -216,6 +226,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Sales lines exists outside of the query filter SalesLine.Init(); SalesLine."Type" := SalesLine.Type::Item; @@ -256,6 +268,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A purchase order is created with multiple types of purchase lines LibPurch.CreatePurchaseOrder(PurchHeader); LibInv.CreateItemWithUnitPriceAndUnitCost( @@ -312,6 +326,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Purchase lines exists outside of the query filter PurchLine.Init(); PurchLine."Type" := PurchLine.Type::Item; @@ -356,6 +372,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + UpdateSalesReceivablesSetup(); // [GIVEN] Multiple items which require replenishment, and requisition lines are created @@ -464,6 +482,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A transfer order is posted LibInv.CreateTransferHeader(TransferHeader); LibInv.CreateItem(Item); @@ -514,6 +534,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Transfer lines exists outside of the query filter TransferLine.Init(); TransferLine."Document No." := LibUtility.GenerateRandomCode20(TransferLine.FieldNo("Document No."), Database::"Transfer Line"); @@ -545,6 +567,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A service order is created with service lines LibService.CreateServiceDocumentWithItemServiceLine(ServiceHeader, ServiceHeader."Document Type"::Order); LibService.CreateServiceItem(ServiceItem, ServiceHeader."Bill-to Customer No."); @@ -595,6 +619,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Service lines exists outside of the query filter ServiceLine.Init(); ServiceLine."Document No." := LibUtility.GenerateRandomCode20(ServiceLine.FieldNo("Document No."), Database::"Service Line"); @@ -636,6 +662,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Sales and purchase documents are created and posted with item ledgers LibSales.CreateSalesOrder(SalesHeader); SalesLine.SetRange("Document Type", SalesHeader."Document Type"); @@ -714,6 +742,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Wrehouse activity lines are created LibInv.CreateItem(Item); PostWarehouseActivity(Item."No."); @@ -771,6 +801,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Warehouse entries are created; LibInv.CreateItem(Item); PostWarehouseActivity(Item."No."); @@ -854,6 +886,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Warehouse journal lines are created LibInv.CreateItem(Item1); LibInv.CreateItem(Item2); @@ -903,6 +937,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Warehouse journal lines are created LibInv.CreateItem(Item1); LibInv.CreateItem(Item2); @@ -983,6 +1019,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Value entry are posted LibInv.CreateItem(Item); LibPurch.CreatePurchHeader(PurchHeader, PurchHeader."Document Type"::Order, LibPurch.CreateVendorNo()); @@ -1040,6 +1078,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Value entry exists outside of the query filter PermissionsMock.Assign('SUPER'); if ValueEntry.FindLast() then; @@ -1071,6 +1111,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Assembly headers are created LibAssembly.CreateAssemblyOrder(AssemblyHeader, CalcDate('<+1M>', WorkDate()), '', 1); LibAssembly.CreateAssemblyOrder(AssemblyHeader2, CalcDate('<+1M>', WorkDate()), '', 1); @@ -1119,6 +1161,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Assembly header exists outside of the query filter AssemblyHeader.Init(); AssemblyHeader."Document Type" := AssemblyHeader."Document Type"::Quote; @@ -1147,6 +1191,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Assembly lines are created LibAssembly.CreateAssemblyOrder(AssemblyHeader, CalcDate('<+1M>', WorkDate()), '', LibRandom.RandIntInRange(2, 5)); AssemblyLine.SetRange("Document Type", AssemblyHeader."Document Type"::Order); @@ -1192,6 +1238,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Assembly lines exist outside of the query filter AssemblyHeader.Init(); AssemblyHeader."Document Type" := AssemblyHeader."Document Type"::Order; @@ -1229,6 +1277,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Job planning lines are created LibInv.CreateItem(Item1); LibInv.CreateItem(Item2); @@ -1281,6 +1331,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Job planning line exists outside of the query filter JobPlanningLine.Init(); @@ -1325,6 +1377,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Production order lines are created LibManufacturing.CreateItemManufacturing( Item, @@ -1388,6 +1442,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Production order line exists outside of the query filter ProdOrderLine.Init(); ProdOrderLine.Status := ProdOrderLine.Status::Finished; @@ -1420,6 +1476,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Production order component lines are created LibManufacturing.CreateItemManufacturing( Item, @@ -1486,6 +1544,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Production order component line exists outside of the query filter ProdOrderComp.Init(); ProdOrderComp.Status := ProdOrderComp.Status::Finished; @@ -1519,6 +1579,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Planning component lines are created #pragma warning disable AA0210 ReqWkshTemplate.SetRange(Type, ReqWkshTemplate.Type::"Req."); @@ -1573,6 +1635,8 @@ codeunit 139877 "E2E PowerBI Inventory Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Planning component line exists outside of the query filter PlanningComponent.Init(); PlanningComponent."Worksheet Template Name" := LibUtility.GenerateRandomCode(PlanningComponent.FieldNo("Worksheet Template Name"), Database::"Planning Component"); diff --git a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIManufacturingTest.Codeunit.al b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIManufacturingTest.Codeunit.al index 33ae983a5bb..04c98763bb6 100644 --- a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIManufacturingTest.Codeunit.al +++ b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIManufacturingTest.Codeunit.al @@ -51,6 +51,10 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" PowerBIAPIEndpoints: Enum "PowerBI API Endpoints"; ResponseEmptyErr: Label 'Response should not be empty.'; + local procedure Initialize() + begin + end; + [Test] procedure TestInventoryAdjmtEntries() var @@ -62,6 +66,7 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" Response: Text; Index: Integer; begin + Initialize(); // [GIVEN] Inventory Adjmt. entries are created @@ -131,6 +136,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" Response: Text; Index: Integer; begin + Initialize(); + // [GIVEN] Calendar entries are created LibManufacturing.CreateWorkCenterWithCalendar(WorkCenter); CalendarEntry.SetRange("No.", WorkCenter."No."); @@ -178,6 +185,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Machine centers are created LibManufacturing.CreateWorkCenter(WorkCenter); LibManufacturing.CreateMachineCenter(MachineCenter, WorkCenter."No.", 1); @@ -220,6 +229,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Work centers are created LibManufacturing.CreateWorkCenterGroup(WorkCenterGroup); LibManufacturing.CreateWorkCenter(WorkCenter); @@ -268,6 +279,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Production order lines are created LibManufacturing.CreateItemManufacturing( Item, @@ -342,6 +355,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Production order components are created LibManufacturing.CreateItemManufacturing( Item, @@ -416,6 +431,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Production order routing lines are created LibInv.CreateItem(Item); CreateRoutingForItem(Item); @@ -496,6 +513,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Item is created with production BOM and routing LibManufacturing.CreateItemManufacturing( Item, @@ -569,6 +588,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Item ledger entries exist outside of the query filter PermissionsMock.Assign('SUPER'); if ItemLedgerEntry.FindLast() then; @@ -612,6 +633,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Item is created with routing LibManufacturing.CreateItemManufacturing( Item, @@ -702,6 +725,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" Response: Text; Index: Integer; begin + Initialize(); + // [GIVEN] Item is created with routing LibManufacturing.CreateItemManufacturing( Item, @@ -839,6 +864,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] "Show Capacity In" is set in Manufacturing Setup LibManufacturing.CreateCapacityUnitOfMeasure(CapacityUnitOfMeasure, Enum::"Capacity Unit of Measure"::Minutes); ManufacturingSetup.Get(); @@ -877,6 +904,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Production orders are created LibManufacturing.CreateItemManufacturing( Item, @@ -937,6 +966,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Routing links are created LibManufacturing.CreateRoutingLink(RoutingLink); @@ -974,6 +1005,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Routing headers are created LibManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Parallel); LibManufacturing.CreateRoutingHeader(RoutingHeader, RoutingHeader.Type::Serial); @@ -1014,6 +1047,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Work center groups are created LibManufacturing.CreateWorkCenterGroup(WorkCenterGroup); LibManufacturing.CreateWorkCenterGroup(WorkCenterGroup); @@ -1059,6 +1094,8 @@ codeunit 139878 "E2E PowerBI Manufacturing Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Manufacturing value entries are created LibManufacturing.CreateItemManufacturing( Item, diff --git a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIProjectTest.Codeunit.al b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIProjectTest.Codeunit.al index 5a71e714459..b4e0f26f78c 100644 --- a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIProjectTest.Codeunit.al +++ b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIProjectTest.Codeunit.al @@ -38,6 +38,10 @@ codeunit 139879 "E2E PowerBI Project Test" PowerBIEndpoints: Enum "PowerBI API Endpoints"; ResponseEmptyErr: Label 'Response should not be empty.'; + local procedure Initialize() + begin + end; + [Test] procedure TestGetJobs() var @@ -47,6 +51,8 @@ codeunit 139879 "E2E PowerBI Project Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Jobs are created LibJob.CreateJob(Job); Job.Validate("Starting Date", WorkDate()); @@ -108,6 +114,8 @@ codeunit 139879 "E2E PowerBI Project Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Job tasks are created LibJob.CreateJob(Job); LibJob.CreateJobTask(Job, JobTask); @@ -154,6 +162,8 @@ codeunit 139879 "E2E PowerBI Project Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Job planning lines are created LibJob.CreateJob(Job); LibJob.CreateJobTask(Job, JobTask); @@ -217,6 +227,8 @@ codeunit 139879 "E2E PowerBI Project Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Job ledger entries are posted LibJob.CreateJob(Job); LibJob.CreateJobTask(Job, JobTask); @@ -283,6 +295,8 @@ codeunit 139879 "E2E PowerBI Project Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Purchase order is created with outstanding lines LibJob.CreateJob(Job); CreatePOWithJob(PurchHeader, Job); @@ -335,6 +349,8 @@ codeunit 139879 "E2E PowerBI Project Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Purchase lines exist outside of the query filter PurchHeader.Init(); PurchHeader."Document Type" := PurchHeader."Document Type"::Invoice; @@ -399,6 +415,8 @@ codeunit 139879 "E2E PowerBI Project Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Purchase order is created with received not invoiced lines LibJob.CreateJob(Job); CreatePOWithJob(PurchHeader, Job); diff --git a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIPurchasesTest.Codeunit.al b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIPurchasesTest.Codeunit.al index 51e3fa3b43f..7391e5e0582 100644 --- a/src/Apps/W1/PowerBIReports/Test/E2EPowerBIPurchasesTest.Codeunit.al +++ b/src/Apps/W1/PowerBIReports/Test/E2EPowerBIPurchasesTest.Codeunit.al @@ -43,6 +43,10 @@ codeunit 139880 "E2E PowerBI Purchases Test" PowerBIAPIEndpoints: Enum "PowerBI API Endpoints"; ResponseEmptyErr: Label 'Response should not be empty.'; + local procedure Initialize() + begin + end; + [Test] procedure TestGetOutstandingPurchOrderLine() var @@ -53,6 +57,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] An outstanding purchase order with multiple lines exists LibPurch.CreatePurchaseOrder(PurchHeader); LibInv.CreateItemWithUnitPriceAndUnitCost( @@ -88,6 +94,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Purchase lines exist outside of the query filter PurchHeader."Document Type" := PurchHeader."Document Type"::Invoice; PurchHeader."No." := LibUtility.GenerateRandomCode20(PurchHeader.FieldNo("No."), Database::"Purchase Header"); @@ -151,6 +159,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] An item budget entry exists LibERM.CreateItemBudgetName(ItemBudgetName, "Analysis Area Type"::Purchase); LibInv.CreateItemBudgetEntry( @@ -198,6 +208,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Item budget entries exist outside of the query filter if ItemBudgetEntry.FindLast() then; ItemBudgetEntry."Entry No." += 1; @@ -228,6 +240,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A purchase order is posted with item ledger entry and value entry LibPurch.CreatePurchaseOrder(PurchaseHeader); PurchaseHeader.Validate("Payment Discount %", 3); @@ -289,6 +303,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Value entries exist outside of the query filter PermissionsMock.Assign('SUPER'); if ItemLedgerEntry.FindLast() then; @@ -330,6 +346,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] A purchase order with multiple lines is received but not invoiced LibPurch.CreatePurchaseOrder(PurchaseHeader); LibInv.CreateItemWithUnitPriceAndUnitCost( @@ -386,6 +404,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Purchase lines exist outside of the query filter PurchaseHeader."Document Type" := PurchaseHeader."Document Type"::Invoice; PurchaseHeader."No." := LibUtility.GenerateRandomCode20(PurchaseHeader.FieldNo("No."), Database::"Purchase Header"); @@ -457,6 +477,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" Response: Text; GLAccountCode: Code[20]; begin + Initialize(); + // [GIVEN] A purchase order with multiple lines for item, G/L account & resource. LibPurch.CreatePurchaseOrder(PurchaseHeader); PurchaseHeader."Posting Date" := WorkDate(); @@ -557,6 +579,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" GLAccountCode: Code[20]; PurchInvoiceNo: Code[20]; begin + Initialize(); + // [GIVEN] A purchase invoice with multiple lines for G/L and Resource LibPurch.CreatePurchaseInvoice(PurchaseHeader); @@ -634,6 +658,8 @@ codeunit 139880 "E2E PowerBI Purchases Test" GLAccountCode: Code[20]; PurchCrMemoNo: Code[20]; begin + Initialize(); + // [GIVEN] A purchase credit memo with multiple lines for G/L and Resource LibPurch.CreatePurchaseCreditMemo(PurchaseHeader); diff --git a/src/Apps/W1/Sustainability/test/src/PowerBISustainabilityTest.Codeunit.al b/src/Apps/W1/Sustainability/test/src/PowerBISustainabilityTest.Codeunit.al index e91d24174c6..0a6fd321d52 100644 --- a/src/Apps/W1/Sustainability/test/src/PowerBISustainabilityTest.Codeunit.al +++ b/src/Apps/W1/Sustainability/test/src/PowerBISustainabilityTest.Codeunit.al @@ -31,6 +31,10 @@ codeunit 148215 "PowerBI Sustainability Test" FieldHiddenMsg: Label '''%1'' field should be hidden.', Comment = '%1 - field caption'; FieldShownMsg: Label '''%1'' field should be shown.', Comment = '%1 - field caption'; + local procedure Initialize() + begin + end; + [Test] procedure TestSustainLedgerEntry() var @@ -38,6 +42,8 @@ codeunit 148215 "PowerBI Sustainability Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Insert a Sustainability Ledger Entry SustainabilityLedgerEntry.Init(); SustainabilityLedgerEntry."Account No." := LibUtility.GenerateGUID(); @@ -103,6 +109,8 @@ codeunit 148215 "PowerBI Sustainability Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Insert a Sustainability Ledger Entry EmployeeLedgerEntry.Init(); DetailEmployLedgEntry.Init(); @@ -159,6 +167,8 @@ codeunit 148215 "PowerBI Sustainability Test" TargetURL: Text; Response: Text; begin + Initialize(); + // [GIVEN] Insert a Sustainability Goal if not UserSetup.Get(UserId()) then begin diff --git a/src/DisabledTests/E-Document_Core_Tests/E-Document Core Tests.DisabledTest.json b/src/DisabledTests/E-Document_Core_Tests/E-Document Core Tests.DisabledTest.json index 2a0b6b498c3..dbb3c63a8cc 100644 --- a/src/DisabledTests/E-Document_Core_Tests/E-Document Core Tests.DisabledTest.json +++ b/src/DisabledTests/E-Document_Core_Tests/E-Document Core Tests.DisabledTest.json @@ -314,11 +314,6 @@ "codeunitName": "EDocCopilotPOGeneralHarms", "method": "*" }, - { - "codeunitId": 135575, - "codeunitName": "E-Doc. API Test", - "method": "*" - }, { "codeunitId": 139235, "codeunitName": "PEPPOL30 Management Tests", @@ -758,4 +753,4 @@ "codeunitName": "E-Doc Process Test", "method": "SuccessfulImportWithAdditionalFieldsHasNoErrors" } -] \ No newline at end of file +] diff --git a/src/DisabledTests/Expense_Agent_Tests/Expense_Agent_Tests.DisabledTest.json b/src/DisabledTests/Expense_Agent_Tests/Expense_Agent_Tests.DisabledTest.json index b23129476de..02c2392f10b 100644 --- a/src/DisabledTests/Expense_Agent_Tests/Expense_Agent_Tests.DisabledTest.json +++ b/src/DisabledTests/Expense_Agent_Tests/Expense_Agent_Tests.DisabledTest.json @@ -1,254 +1,4 @@ [ - { - "codeunitId": 148315, - "codeunitName": "Expense Users API Test", - "method": "EmployeesAPICanFilterExpenseUsers" - }, - { - "codeunitId": 148315, - "codeunitName": "Expense Users API Test", - "method": "UnlinkedExpenseUserIsHiddenFromAPI" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelersAPIMapsEmployeeNumberToExpenseUser" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelersAPIRejectsEmployeeWithoutExpenseUser" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "CreateExpenseReportActionRecreatesDeletedReport" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "ApproveTravelRequestActionCreatesExpenseReport" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelRequestsAPINormalizesCurrency" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelRequestDetailsAPINormalizesCurrency" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelRequestsAPIPreservesAndUpdatesDates" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelRequestsAreScopedByEmployeeNumber" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "ExpenseReportAPIExposesLinkedTravelRequest" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelRequestDetailsAPIExposesTypeAndCategory" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "ApproverViewReturnsOnlyAssignedTravelRequests" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelRequestsAPIAllowsOwnerOnInsertAndUnchangedPatch" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelRequestsAPIRejectsLifecycleFieldChanges" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "TravelRequestsAPIRejectsRequestedForChange" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "LegacySpendRequestsAPIAllowsUnchangedOwner" - }, - { - "codeunitId": 148347, - "codeunitName": "Travel Requests API Test", - "method": "LegacySpendRequestsAPIRejectsTravelRequestOwnerChange" - }, - { - "codeunitId": 148318, - "codeunitName": "Expense Capabilities API Test", - "method": "CapabilitiesProjectsEnabledViaAPI" - }, - { - "codeunitId": 148318, - "codeunitName": "Expense Capabilities API Test", - "method": "CapabilitiesProjectsDisabledViaAPI" - }, - { - "codeunitId": 148318, - "codeunitName": "Expense Capabilities API Test", - "method": "CapabilitiesConsolidatedProjectsFollowsProjectFieldsViaAPI" - }, - { - "codeunitId": 148318, - "codeunitName": "Expense Capabilities API Test", - "method": "ActivityLogCapabilityEnabledViaAPI" - }, - { - "codeunitId": 148318, - "codeunitName": "Expense Capabilities API Test", - "method": "TravelRequestCapabilityEnabledViaAPI" - }, - { - "codeunitId": 148343, - "codeunitName": "Expense Activity Log API Test", - "method": "ActivityLogEntryIsExposedThroughReadOnlyAPI" - }, - { - "codeunitId": 148343, - "codeunitName": "Expense Activity Log API Test", - "method": "ActivityLogAPIRejectsWrites" - }, - { - "codeunitId": 148343, - "codeunitName": "Expense Activity Log API Test", - "method": "NonSnapshotActivityDoesNotExposeCurrencies" - }, - { - "codeunitId": 148343, - "codeunitName": "Expense Activity Log API Test", - "method": "UnscopedActivityAPIHidesEntries" - }, - { - "codeunitId": 148343, - "codeunitName": "Expense Activity Log API Test", - "method": "SubmitterHistoryReturnsCompleteTimelinesForSubmittedReports" - }, - { - "codeunitId": 148343, - "codeunitName": "Expense Activity Log API Test", - "method": "ApproverHistoryReturnsCompleteTimelinesForActedOnReports" - }, - { - "codeunitId": 148343, - "codeunitName": "Expense Activity Log API Test", - "method": "E2EActivityLogScenario" - }, - { - "codeunitId": 148333, - "codeunitName": "Expense Agent Setup API Test", - "method": "EmailAddressFieldIsExposedThroughAPI" - }, - { - "codeunitId": 148349, - "codeunitName": "Expense PerDiem Locations Test", - "method": "PerDiemLocationsReturnsLinkedLocationViaAPI" - }, - { - "codeunitId": 148349, - "codeunitName": "Expense PerDiem Locations Test", - "method": "PerDiemLocationsExcludesNonPerDiemCategoryViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "AssignedByPersonResponsibleReturnsWholeProjectViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "AssignedByProjectManagerReturnsWholeProjectViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "AssignedByProjectLevelResourceReturnsWholeProjectViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "AssignedByTaskLevelResourceReturnsOnlyThatTaskViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "AssignedByPlanningLineReturnsOnlyThatTaskViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "WholeProjectSignalSupersedesTaskLevelViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "OverlappingSignalsForSameResourceAreDeduplicatedViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "CompletedProjectExcludedEvenWhenAssignedViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "EmptyResourceUserMatchesNothingViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "BlankUserIdDoesNotMatchBlankProjectManagerViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "ProjectManagerMatchWithBlankResourceReturnsProjectViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "TasklessProjectExcludedViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "WholeProjectAndTaskLevelAcrossProjectsNoLeakageViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "AllProjectsVisibilityReturnsAllProjectsViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "AllProjectsVisibilityIncludesActiveStatusesAndPostingTasksViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "AssignedProjectsRequiresScopeFilterViaAPI" - }, - { - "codeunitId": 148331, - "codeunitName": "Expense Projects API Test", - "method": "AssignedProjectsBlockedWhenProjectFieldsDisabledViaAPI" - }, { "codeunitId": 148305, "codeunitName": "Expense Test", @@ -293,10 +43,5 @@ "codeunitId": 148319, "codeunitName": "Cancel Posted Exp. Report Test", "method": "CancelMultiLineReportGeneratesNewTransactionNoForReversedLines" - }, - { - "codeunitId": 148348, - "codeunitName": "Expense VAT Spec. API Test", - "method": "AgentVATSpecificationIsInsertedThroughAPI" } ] diff --git a/src/DisabledTests/_Exclude_APIV1__Tests/_Exclude_APIV1__Tests.DisabledTest.json b/src/DisabledTests/_Exclude_APIV1__Tests/_Exclude_APIV1__Tests.DisabledTest.json index ad692000a56..fe51488c706 100644 --- a/src/DisabledTests/_Exclude_APIV1__Tests/_Exclude_APIV1__Tests.DisabledTest.json +++ b/src/DisabledTests/_Exclude_APIV1__Tests/_Exclude_APIV1__Tests.DisabledTest.json @@ -1,1457 +1 @@ -[ - { - "codeunitId": 139701, - "codeunitName": "APIV1 - Accounts E2E", - "method": "TestGetAccounts" - }, - { - "codeunitId": 139704, - "codeunitName": "APIV1 - Payment Terms E2E", - "method": "TestGetPaymentTerms" - }, - { - "codeunitId": 139705, - "codeunitName": "APIV1 - Shipment Methods E2E", - "method": "TestGetShipmentMethods" - }, - { - "codeunitId": 139706, - "codeunitName": "APIV1 - Company Info. E2E", - "method": "TestGetCompanyInformationWithComplexType" - }, - { - "codeunitId": 139706, - "codeunitName": "APIV1 - Company Info. E2E", - "method": "TestModifyCompanyInformation" - }, - { - "codeunitId": 139706, - "codeunitName": "APIV1 - Company Info. E2E", - "method": "TestModifyCompanyInformationWithComplexType" - }, - { - "codeunitId": 139706, - "codeunitName": "APIV1 - Company Info. E2E", - "method": "TestRemoveComplexTypeFromCompanyInformation" - }, - { - "codeunitId": 139707, - "codeunitName": "APIV1 - Item Categories E2E", - "method": "TestCreateItemCategory" - }, - { - "codeunitId": 139707, - "codeunitName": "APIV1 - Item Categories E2E", - "method": "TestDeleteItemCategory" - }, - { - "codeunitId": 139707, - "codeunitName": "APIV1 - Item Categories E2E", - "method": "TestGetItemCategories" - }, - { - "codeunitId": 139707, - "codeunitName": "APIV1 - Item Categories E2E", - "method": "TestModifyItemCategory" - }, - { - "codeunitId": 139708, - "codeunitName": "Tax Groups E2E", - "method": "TestCreateTaxGroup" - }, - { - "codeunitId": 139708, - "codeunitName": "Tax Groups E2E", - "method": "TestDeleteTaxGroup" - }, - { - "codeunitId": 139708, - "codeunitName": "Tax Groups E2E", - "method": "TestGetTaxGroup" - }, - { - "codeunitId": 139708, - "codeunitName": "Tax Groups E2E", - "method": "TestGetTaxGroups" - }, - { - "codeunitId": 139708, - "codeunitName": "Tax Groups E2E", - "method": "TestModifyTaxGroup" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestActionCancelAndSendInvoice" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestActionCancelInvoice" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestActionMakeCorrectiveCreditMemo" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestActionPostAndSendInvoice" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestActionPostInvoice" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestActionSendCancelledInvoice" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestActionSendDraftInvoice" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestActionSendPostedInvoice" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestCreateInvoiceThroughPageAndAPI" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestDeleteInvoice" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestEmptyModifyInvoices" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestGetInvoices" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestGetInvoicesAppliesDiscountPct" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestGetInvoicesRedistributesDiscountAmt" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestModifyingWithBlankIdEmptiesTheCodeAndTheId" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestModifyInvoiceNumberForDraftInvoice" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestModifyInvoices" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestModifyInvoiceSetManualDiscount" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestPartialModifyInvoices" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestPostInvoices" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestPostInvoiceWithCurrency" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestPostInvoiceWithDates" - }, - { - "codeunitId": 139709, - "codeunitName": "Sales Invoices E2E", - "method": "TestPostInvoiceWithEmail" - }, - { - "codeunitId": 139710, - "codeunitName": "Countries/Regions E2E", - "method": "TestCreateCountriesRegions" - }, - { - "codeunitId": 139710, - "codeunitName": "Countries/Regions E2E", - "method": "TestDeleteCountriesRegions" - }, - { - "codeunitId": 139710, - "codeunitName": "Countries/Regions E2E", - "method": "TestGetCountriesRegions" - }, - { - "codeunitId": 139710, - "codeunitName": "Countries/Regions E2E", - "method": "TestModifyCountriesRegions" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestActionShipAndInvoice" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestCreateOrderThroughPageAndAPI" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestDeleteOrders" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestEmptyModifyOrders" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestGetOrders" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestGetOrdersAppliesDiscountPct" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestGetOrdersRedistributesDiscountAmt" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestModifyOrders" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestModifyOrderSetManualDiscount" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestPartialModifyOrders" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestPostOrderForCustomerWithLocationCode" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestPostOrders" - }, - { - "codeunitId": 139711, - "codeunitName": "APIV1 - Sales Orders E2E", - "method": "TestPostOrderWithCurrency" - }, - { - "codeunitId": 139712, - "codeunitName": "APIV1 - UofM E2E", - "method": "TestDeleteUnitOfMeasure" - }, - { - "codeunitId": 139712, - "codeunitName": "APIV1 - UofM E2E", - "method": "TestGetUnitOfMeasure" - }, - { - "codeunitId": 139712, - "codeunitName": "APIV1 - UofM E2E", - "method": "TestInsertUnitOfMeasure" - }, - { - "codeunitId": 139712, - "codeunitName": "APIV1 - UofM E2E", - "method": "TestModifyUnitOfMeasure" - }, - { - "codeunitId": 139713, - "codeunitName": "APIV1 - Currencies E2E", - "method": "TestCreateCurrency" - }, - { - "codeunitId": 139713, - "codeunitName": "APIV1 - Currencies E2E", - "method": "TestDeleteCurrency" - }, - { - "codeunitId": 139713, - "codeunitName": "APIV1 - Currencies E2E", - "method": "TestGetCurrencies" - }, - { - "codeunitId": 139713, - "codeunitName": "APIV1 - Currencies E2E", - "method": "TestModifyCurrency" - }, - { - "codeunitId": 139714, - "codeunitName": "Payment Methods E2E", - "method": "TestCreatePaymentMethods" - }, - { - "codeunitId": 139714, - "codeunitName": "Payment Methods E2E", - "method": "TestDeletePaymentMethods" - }, - { - "codeunitId": 139714, - "codeunitName": "Payment Methods E2E", - "method": "TestGetPaymentMethods" - }, - { - "codeunitId": 139714, - "codeunitName": "Payment Methods E2E", - "method": "TestModifyPaymentMethods" - }, - { - "codeunitId": 139715, - "codeunitName": "APIV1 - Balance Sheet E2E", - "method": "TestGetBalanceSheetRecords" - }, - { - "codeunitId": 139716, - "codeunitName": "APIV1 - Income Statement E2E", - "method": "TestGetIncomeStatementRecords" - }, - { - "codeunitId": 139717, - "codeunitName": "APIV1 - CashFlow Statement E2E", - "method": "TestGetCashFlowRecords" - }, - { - "codeunitId": 139718, - "codeunitName": "APIV1 - Trial Balance E2E", - "method": "TestGetTrialBalanceRecords" - }, - { - "codeunitId": 139719, - "codeunitName": "APIV1 - Aged AP E2E", - "method": "TestGetAgedAPRecords" - }, - { - "codeunitId": 139720, - "codeunitName": "APIV1 - Aged AR E2E", - "method": "TestGetAgedARRecords" - }, - { - "codeunitId": 139721, - "codeunitName": "APIV1 - Ret. Earnings E2E", - "method": "TestRetainedEarningsStatementRecords" - }, - { - "codeunitId": 139722, - "codeunitName": "APIV1 - Employees E2E", - "method": "TestCreateEmployee" - }, - { - "codeunitId": 139722, - "codeunitName": "APIV1 - Employees E2E", - "method": "TestDeleteEmployee" - }, - { - "codeunitId": 139722, - "codeunitName": "APIV1 - Employees E2E", - "method": "TestGetEmployee" - }, - { - "codeunitId": 139722, - "codeunitName": "APIV1 - Employees E2E", - "method": "TestModifyEmployee" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestActionMakeInvoiceFromQuote" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestActionMakeOrderFromQuote" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestActionSendQuote" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestCreateQuoteThroughPageAndAPI" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestDeleteQuotes" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestEmptyModifyQuotes" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestGetQuotes" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestGetQuotesAppliesDiscountPct" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestGetQuotesRedistributesDiscountAmt" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestModifyQuotes" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestModifyQuoteSetManualDiscount" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestPartialModifyQuotes" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestPostQuotes" - }, - { - "codeunitId": 139723, - "codeunitName": "APIV1 - Sales Quotes E2E", - "method": "TestPostQuoteWithCurrency" - }, - { - "codeunitId": 139724, - "codeunitName": "APIV1 - Dimensions E2E", - "method": "TestGetDimensions" - }, - { - "codeunitId": 139724, - "codeunitName": "APIV1 - Dimensions E2E", - "method": "TestGetDimensionValues" - }, - { - "codeunitId": 139727, - "codeunitName": "APIV1 - Journals E2E", - "method": "TestActionPostGenJournalBatch" - }, - { - "codeunitId": 139727, - "codeunitName": "APIV1 - Journals E2E", - "method": "TestCreateJournal" - }, - { - "codeunitId": 139727, - "codeunitName": "APIV1 - Journals E2E", - "method": "TestDeleteJournal" - }, - { - "codeunitId": 139727, - "codeunitName": "APIV1 - Journals E2E", - "method": "TestGetJournals" - }, - { - "codeunitId": 139727, - "codeunitName": "APIV1 - Journals E2E", - "method": "TestModifyJournal" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestActionCancelAndSendCorrectiveCreditMemo" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestActionCancelCorrectiveCreditMemo" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestActionPostAndSendCreditMemo" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestActionPostCreditMemo" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestActionSendCancelledCreditMemo" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestActionSendPostedCreditMemo" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestCreateCreditMemoThroughPageAndAPI" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestDeleteCreditMemo" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestEmptyModifyCreditMemos" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestGetCreditMemos" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestGetCreditMemosAppliesDiscountPct" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestGetCreditMemosRedistributesDiscountAmt" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestModifyCreditMemos" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestModifyCreditMemoSetManualDiscount" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestPartialModifyCreditMemos" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestPostCreditMemos" - }, - { - "codeunitId": 139728, - "codeunitName": "APIV1 - Sales Credit Memos E2E", - "method": "TestPostCreditMemoWithCurrency" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestActionPostPurchaseInvoice" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestCreateInvoiceThroughPageAndAPI" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestDeleteInvoice" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestEmptyModifyInvoices" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestGetInvoices" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestModifyInvoices" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestPartialModifyInvoices" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestPostInvoices" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestPostPurchaseInvoiceWithCurrency" - }, - { - "codeunitId": 139729, - "codeunitName": "APIV1 - Purchase Invoices E2E", - "method": "TestPurchaseInvoiceWithPaymentDiscount" - }, - { - "codeunitId": 139730, - "codeunitName": "APIV1 - GLEntries E2E", - "method": "TestGetGLEntries" - }, - { - "codeunitId": 139731, - "codeunitName": "APIV1 - Automation RS Package", - "method": "TestApplyRSPackage" - }, - { - "codeunitId": 139731, - "codeunitName": "APIV1 - Automation RS Package", - "method": "TestCreateRSPackage" - }, - { - "codeunitId": 139731, - "codeunitName": "APIV1 - Automation RS Package", - "method": "TestImportRSPackage" - }, - { - "codeunitId": 139731, - "codeunitName": "APIV1 - Automation RS Package", - "method": "TestImportWrongRSPackage" - }, - { - "codeunitId": 139731, - "codeunitName": "APIV1 - Automation RS Package", - "method": "TestUploadRSPackageFile" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestCreateDraftInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestCreateDraftPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestCreateGLEntryAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestCreateJournalLineAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestCreatePostedInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestCreatePostedPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestCreateQuoteAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestDeleteDraftInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestDeleteDraftPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestDeleteGLEntryAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestDeleteJournalLineAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestDeletePostedInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestDeletePostedPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestDeleteQuoteAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetDraftInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetDraftInvoiceAttachments" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetDraftPurchaseInvoiceAttachments" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetGLEntryAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetGLEntryAttachments" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetJournalAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetJournalLineAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetJournalLineAttachments" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetPostedInvoiceAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetPostedInvoiceAttachments" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetPostedPurchaseInvoiceAttachments" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetQuoteAttachment" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestGetQuoteAttachments" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestLinkedAttachmentContentChangeKeepsOtherFieldsUnchanged" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestLinkedAttachmentDocumentIdChangeNotAllowed" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestLinkedAttachmentFileNameChangeKeepsOtherFieldsUnchanged" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestLinkedAttachmentIdChangeNotAllowed" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestTransferAttachmentFromDraftToPostedInvoice" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestTransferAttachmentFromDraftToPostedPurchaseInvoice" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestUpdateGenJournalLineAttachmentBinaryContent" - }, - { - "codeunitId": 139733, - "codeunitName": "APIV1 - Attachments E2E", - "method": "TestUpdateGLEntryAttachmentBinaryContent" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestDeleteInvoiceLine" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestDeletingLineKeepsInvoiceDiscountAmt" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestDeletingLineMovesInvoiceDiscountPct" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestDeletingLineRemovesInvoiceDiscountPct" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestGetInvoiceLineDirectly" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestGetInvoiceLines" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestGetInvoiceLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestGetPostedInvoiceLines" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestGettingLinesWithDifferentTypes" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestInsertingLineUpdatesInvoiceDiscountPct" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestModifyingLineKeepsInvoiceDiscountAmt" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestModifyingLineUpdatesInvoiceDiscountPct" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestModifyInvoiceLine" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestModifyInvoiceLineWithUoM" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestPatchingTheIdToAccountChangesLineType" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestPatchingTheIdToItemChangesLineType" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestPostingBlankLineDefaultsToItemType" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestPostInvoiceLines" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestPostInvoiceLinesWithItemVariant" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestPostInvoiceLinesWithUoM" - }, - { - "codeunitId": 139734, - "codeunitName": "APIV1 - Sales Inv. Lines E2E", - "method": "TestPostInvoiceLineWithSequence" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestDeleteOrderLine" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestDeletingLineKeepsOrderDiscountAmt" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestDeletingLineMovesOrderDiscountPct" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestDeletingLineRemovesOrderDiscountPct" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestGetOrderLineDirectly" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestGetOrderLines" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestGetOrderLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestGettingLinesWithDifferentTypes" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestInsertingLineUpdatesOrderDiscountPct" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestModifyingLineKeepsOrderDiscountAmt" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestModifyingLineUpdatesOrderDiscountPct" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestModifyOrderLines" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestPatchingTheIdToAccountChangesLineType" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestPatchingTheIdToItemChangesLineType" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestPostingBlankLineDefaultsToItemType" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestPostOrderLines" - }, - { - "codeunitId": 139735, - "codeunitName": "APIV1 - Sales Order Lines E2E", - "method": "TestPostOrderLineWithItemVariant" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestDeleteQuoteLine" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestDeletingLineKeepsQuoteDiscountAmt" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestDeletingLineMovesQuoteDiscountPct" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestDeletingLineRemovesQuoteDiscountPct" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestGetQuoteLineDirectly" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestGetQuoteLines" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestGetQuoteLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestInsertingLineKeepsQuoteDiscountAmt" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestInsertingLineUpdatesQuoteDiscountPct" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestModifyingLineKeepsQuoteDiscountAmt" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestModifyingLineUpdatesQuoteDiscountPct" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestModifyQuoteLines" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestPostingBlankLineDefaultsToItemType" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestPostQuoteLines" - }, - { - "codeunitId": 139736, - "codeunitName": "APIV1 - Sales Quote Lines E2E", - "method": "TestPostQuoteLinesWithItemVariant" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestDeleteCreditMemoLine" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestDeletePostedCreditMemoLine" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestDeletingLineKeepsCreditMemoDiscountAmt" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestDeletingLineMovesCreditMemoDiscountPct" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestDeletingLineRemovesCreditMemoDiscountPct" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestGetCreditMemoLineDirectly" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestGetCreditMemoLines" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestGetCreditMemoLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestGetPostedCreditMemoLines" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestGettingLinesWithDifferentTypes" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestInsertingLineUpdatesCreditMemoDiscountPct" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestModifyCreditMemoLines" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestModifyingLineKeepsCreditMemoDiscountAmt" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestModifyingLineUpdatesCreditMemoDiscountPct" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestPatchingTheIdToAccountChangesLineType" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestPatchingTheIdToItemChangesLineType" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestPostCreditMemoLines" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestPostCreditMemoLinesWithItemVariant" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestPostCreditMemoLineWithSequence" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestPostingBlankLineDefaultsToItemType" - }, - { - "codeunitId": 139737, - "codeunitName": "APIV1 - Sales CrMemo Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestDeleteInvoiceLine" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestDeletingLineRemovesInvoiceDiscountPct" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestGetInvoiceLineDirectly" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestGetInvoiceLines" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestGetInvoiceLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestGetPostedInvoiceLines" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestInsertingLineUpdatesInvoiceDiscountPct" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestModifyingLineUpdatesInvoiceDiscountPct" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestModifyInvoiceLines" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestPostingBlankLineDefaultsToItemType" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestPostInvoiceLines" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestPostInvoiceLinesWithItemVariant" - }, - { - "codeunitId": 139738, - "codeunitName": "APIV1 - Purchase Inv Lines E2E", - "method": "TestPostInvoiceLineWithSequence" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestAppliesToInvoiceNoAndIdSync" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestCreateCustomerPayment" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestCreateCustomerPaymentWithInvoiceId" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestCreateCustomerPaymentWithoutDocNo" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestCustomerAutofillDoesNotOverwrite" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestCustomerAutofillWhenGivingInvoiceNumber" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestCustomerNoAndIdSync" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestDeleteCustomerPayment" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestGetCustomerPayment" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestModifyCustomerPayment" - }, - { - "codeunitId": 139743, - "codeunitName": "APIV1 - Customer Payments E2E", - "method": "TestModifyCustomerPaymentWithRandomDocNo" - }, - { - "codeunitId": 139744, - "codeunitName": "APIV1 - PDF Document E2E", - "method": "TestGetPDFPurchaseInvoice" - }, - { - "codeunitId": 139744, - "codeunitName": "APIV1 - PDF Document E2E", - "method": "TestGetPDFSalesCreditMemo" - }, - { - "codeunitId": 139744, - "codeunitName": "APIV1 - PDF Document E2E", - "method": "TestGetPDFSalesInvoice" - }, - { - "codeunitId": 139744, - "codeunitName": "APIV1 - PDF Document E2E", - "method": "TestGetPDFSalesQuote" - }, - { - "codeunitId": 139745, - "codeunitName": "APIV1 - Journal Lines E2E", - "method": "TestCreateJournalLineWithDimensionsOnAccountWithDimensionSetup" - }, - { - "codeunitId": 139745, - "codeunitName": "APIV1 - Journal Lines E2E", - "method": "TestCreateJournalLineWithDisabledCopyVATSetup" - }, - { - "codeunitId": 139745, - "codeunitName": "APIV1 - Journal Lines E2E", - "method": "TestCreateJournalLineWithoutDimensionsOnAccountWithDimensionSetup" - }, - { - "codeunitId": 139745, - "codeunitName": "APIV1 - Journal Lines E2E", - "method": "TestCreateJournalLineWithOverridenDefaultDimension" - } -] +[] diff --git a/src/DisabledTests/_Exclude_APIV2__Tests/_Exclude_APIV2__Tests.DisabledTest.json b/src/DisabledTests/_Exclude_APIV2__Tests/_Exclude_APIV2__Tests.DisabledTest.json index 2a73423912e..9c2c3cacb7a 100644 --- a/src/DisabledTests/_Exclude_APIV2__Tests/_Exclude_APIV2__Tests.DisabledTest.json +++ b/src/DisabledTests/_Exclude_APIV2__Tests/_Exclude_APIV2__Tests.DisabledTest.json @@ -1,3587 +1,7 @@ [ - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestCreateItemWithCategoryCode" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestCreateItemWithCategoryId" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestCreateItemWithTemplate" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestCreateItemWithTemplateIgnoresFieldsSet" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestCreateItemWithUoMCode" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestCreateItemWithUoMId" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestCreateSimpleItem" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestDeleteItem" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestGetItemWithCategory" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestGetRelatedEntities" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestGetSimpleItem" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestModifyItem" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestModifyItemInventory" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestPatchItemWithCategoryCode" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestPatchItemWithCategoryId" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestPatchItemWithGenProdPostingGroup" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestPatchItemWithInventoryPostingGroup" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestUnassignGenProdPostingGroup" - }, - { - "codeunitId": 139800, - "codeunitName": "APIV2 - Items E2E", - "method": "TestUnassignInventoryPostingGroup" - }, - { - "codeunitId": 139801, - "codeunitName": "APIV2 - Accounts E2E", - "method": "TestGetAccounts" - }, - { - "codeunitId": 139804, - "codeunitName": "APIV2 - Payment Terms E2E", - "method": "TestGetPaymentTerms" - }, - { - "codeunitId": 139805, - "codeunitName": "APIV2 - Shipment Methods E2E", - "method": "TestGetShipmentMethods" - }, - { - "codeunitId": 139806, - "codeunitName": "APIV2 - Company Info. E2E", - "method": "TestGetCompanyInformation" - }, { "codeunitId": 139806, "codeunitName": "APIV2 - Company Info. E2E", "method": "TestGetCompanyAndEnvironmentDescriptions" - }, - { - "codeunitId": 139806, - "codeunitName": "APIV2 - Company Info. E2E", - "method": "TestModifyCompanyInformation" - }, - { - "codeunitId": 139806, - "codeunitName": "APIV2 - Company Info. E2E", - "method": "TestModifyInvalidExperinceTier" - }, - { - "codeunitId": 139806, - "codeunitName": "APIV2 - Company Info. E2E", - "method": "TestModifyValidExperinceTier" - }, - { - "codeunitId": 139807, - "codeunitName": "APIV2 - Item Categories E2E", - "method": "TestCreateItemCategory" - }, - { - "codeunitId": 139807, - "codeunitName": "APIV2 - Item Categories E2E", - "method": "TestDeleteItemCategory" - }, - { - "codeunitId": 139807, - "codeunitName": "APIV2 - Item Categories E2E", - "method": "TestGetItemCategories" - }, - { - "codeunitId": 139807, - "codeunitName": "APIV2 - Item Categories E2E", - "method": "TestModifyItemCategory" - }, - { - "codeunitId": 139808, - "codeunitName": "APIV2 - Tax Groups E2E", - "method": "TestCreateTaxGroup" - }, - { - "codeunitId": 139808, - "codeunitName": "APIV2 - Tax Groups E2E", - "method": "TestDeleteTaxGroup" - }, - { - "codeunitId": 139808, - "codeunitName": "APIV2 - Tax Groups E2E", - "method": "TestGetTaxGroup" - }, - { - "codeunitId": 139808, - "codeunitName": "APIV2 - Tax Groups E2E", - "method": "TestGetTaxGroups" - }, - { - "codeunitId": 139808, - "codeunitName": "APIV2 - Tax Groups E2E", - "method": "TestModifyTaxGroup" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestActionCancelAndSendInvoice" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestActionCancelInvoice" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestActionMakeCorrectiveCreditMemo" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestActionPostAndSendInvoice" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestActionPostInvoice" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestActionSendCancelledInvoice" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestActionSendDraftInvoice" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestActionSendPostedInvoice" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestCreateInvoiceThroughPageAndAPI" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestDeleteInvoice" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestEmptyModifyInvoices" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestGetInvoiceFromPostedOrderCorrectOrderIdAndNo" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestGetInvoices" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestGetInvoicesAppliesDiscountPct" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestGetInvoicesRedistributesDiscountAmt" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestGetSalesInvoiceFromDraftId" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestModifyingWithBlankIdEmptiesTheCodeAndTheId" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestModifyInvoiceNumberForDraftInvoice" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestModifyInvoices" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestModifyInvoiceSetManualDiscount" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestPartialModifyInvoices" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestPostInvoices" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestPostInvoiceWithCurrency" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestPostInvoiceWithDates" - }, - { - "codeunitId": 139809, - "codeunitName": "APIV2 - Sales Invoices E2E", - "method": "TestPostInvoiceWithEmail" - }, - { - "codeunitId": 139810, - "codeunitName": "APIV2 - Countries/Regions E2E", - "method": "TestCreateCountriesRegions" - }, - { - "codeunitId": 139810, - "codeunitName": "APIV2 - Countries/Regions E2E", - "method": "TestDeleteCountriesRegions" - }, - { - "codeunitId": 139810, - "codeunitName": "APIV2 - Countries/Regions E2E", - "method": "TestGetCountriesRegions" - }, - { - "codeunitId": 139810, - "codeunitName": "APIV2 - Countries/Regions E2E", - "method": "TestModifyCountriesRegions" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestActionShipAndInvoice" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestCreateOrderThroughPageAndAPI" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestDeleteOrders" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestEmptyModifyOrders" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestGetOrders" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestGetOrdersAppliesDiscountPct" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestGetOrdersRedistributesDiscountAmt" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestModifyOrders" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestModifyOrderSetManualDiscount" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestPartialModifyOrders" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestPostOrderForCustomerWithLocationCode" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestPostOrders" - }, - { - "codeunitId": 139811, - "codeunitName": "APIV2 - Sales Orders E2E", - "method": "TestPostOrderWithCurrency" - }, - { - "codeunitId": 139812, - "codeunitName": "APIV2 - UofM E2E", - "method": "TestDeleteUnitOfMeasure" - }, - { - "codeunitId": 139812, - "codeunitName": "APIV2 - UofM E2E", - "method": "TestGetUnitOfMeasure" - }, - { - "codeunitId": 139812, - "codeunitName": "APIV2 - UofM E2E", - "method": "TestInsertUnitOfMeasure" - }, - { - "codeunitId": 139812, - "codeunitName": "APIV2 - UofM E2E", - "method": "TestModifyUnitOfMeasure" - }, - { - "codeunitId": 139813, - "codeunitName": "APIV2 - Currencies E2E", - "method": "TestCreateCurrency" - }, - { - "codeunitId": 139813, - "codeunitName": "APIV2 - Currencies E2E", - "method": "TestDeleteCurrency" - }, - { - "codeunitId": 139813, - "codeunitName": "APIV2 - Currencies E2E", - "method": "TestGetCurrencies" - }, - { - "codeunitId": 139813, - "codeunitName": "APIV2 - Currencies E2E", - "method": "TestModifyCurrency" - }, - { - "codeunitId": 139814, - "codeunitName": "APIV2 - Payment Methods E2E", - "method": "TestCreatePaymentMethods" - }, - { - "codeunitId": 139814, - "codeunitName": "APIV2 - Payment Methods E2E", - "method": "TestDeletePaymentMethods" - }, - { - "codeunitId": 139814, - "codeunitName": "APIV2 - Payment Methods E2E", - "method": "TestGetPaymentMethods" - }, - { - "codeunitId": 139814, - "codeunitName": "APIV2 - Payment Methods E2E", - "method": "TestModifyPaymentMethods" - }, - { - "codeunitId": 139815, - "codeunitName": "APIV2 - Balance Sheet E2E", - "method": "TestGetBalanceSheetRecords" - }, - { - "codeunitId": 139816, - "codeunitName": "APIV2 - Income Statement E2E", - "method": "TestGetIncomeStatementRecords" - }, - { - "codeunitId": 139817, - "codeunitName": "APIV2 - CashFlow Statement E2E", - "method": "TestGetCashFlowRecords" - }, - { - "codeunitId": 139818, - "codeunitName": "APIV2 - Trial Balance E2E", - "method": "TestGetTrialBalanceRecords" - }, - { - "codeunitId": 139819, - "codeunitName": "APIV2 - Aged AP E2E", - "method": "TestGetAgedAPRecords" - }, - { - "codeunitId": 139820, - "codeunitName": "APIV2 - Aged AR E2E", - "method": "TestGetAgedARRecords" - }, - { - "codeunitId": 139821, - "codeunitName": "APIV2 - Ret. Earnings E2E", - "method": "TestRetainedEarningsStatementRecords" - }, - { - "codeunitId": 139822, - "codeunitName": "APIV2 - Employees E2E", - "method": "TestCreateEmployee" - }, - { - "codeunitId": 139822, - "codeunitName": "APIV2 - Employees E2E", - "method": "TestDeleteEmployee" - }, - { - "codeunitId": 139822, - "codeunitName": "APIV2 - Employees E2E", - "method": "TestGetEmployee" - }, - { - "codeunitId": 139822, - "codeunitName": "APIV2 - Employees E2E", - "method": "TestModifyEmployee" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestActionMakeInvoiceFromQuote" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestActionMakeOrderFromQuote" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestActionSendQuote" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestCreateQuoteThroughPageAndAPI" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestDeleteQuotes" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestEmptyModifyQuotes" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestGetQuotes" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestGetQuotesAppliesDiscountPct" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestGetQuotesRedistributesDiscountAmt" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestModifyQuotes" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestModifyQuoteSetManualDiscount" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestPartialModifyQuotes" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestPostQuotes" - }, - { - "codeunitId": 139823, - "codeunitName": "APIV2 - Sales Quotes E2E", - "method": "TestPostQuoteWithCurrency" - }, - { - "codeunitId": 139824, - "codeunitName": "APIV2 - Dimensions E2E", - "method": "TestGetDimensions" - }, - { - "codeunitId": 139824, - "codeunitName": "APIV2 - Dimensions E2E", - "method": "TestGetDimensionValues" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreateDoesntWorkWithAlreadyExistingCode" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreateJournalLineDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreatePurchaseCrMemoDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreatePurchaseInvoiceDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreatePurchaseOrderDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreateSalesCrMemoDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreateSalesInvoiceDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreateSalesOrderDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreateSalesQuoteDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestCreateTimeRegEntryDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestDeleteDimensionSetLineOfGenJournalLines" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestDeletePurchaseCrMemoDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestDeletePurchaseInvoiceDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestDeletePurchaseOrderDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestDeleteSalesCrMemoDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestDeleteSalesInvoiceDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestDeleteSalesOrderDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestDeleteSalesQuoteDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestDeleteTimeRegEntryDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfGLEntry" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfJournalLines" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfPurchaseCrMemo" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfPurchaseInvoice" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfPurchaseOrder" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfSalesCrMemo" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfSalesInvoice" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfSalesOrder" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfSalesQuote" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestGetDimensionSetLinesOfTimeRegEntry" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifyDimensionSetLineOfGenJournalLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifyDimensionSetLineOfSalesOrder" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifyDimensionSetLineOfSalesQuote" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifyOfDimensionCodeDoesntWork" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifyPurchaseCrMemoDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifyPurchaseInvoiceDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifyPurchaseOrderDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifySalesCrMemoDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifySalesInvoiceDimensionSetLine" - }, - { - "codeunitId": 139825, - "codeunitName": "APIV2 - Dim. Set Lines E2E", - "method": "TestModifyTimeRegEntryDimensionSetLine" - }, - { - "codeunitId": 139827, - "codeunitName": "APIV2 - Journals E2E", - "method": "TestActionPostGenJournalBatch" - }, - { - "codeunitId": 139827, - "codeunitName": "APIV2 - Journals E2E", - "method": "TestCreateJournal" - }, - { - "codeunitId": 139827, - "codeunitName": "APIV2 - Journals E2E", - "method": "TestDeleteJournal" - }, - { - "codeunitId": 139827, - "codeunitName": "APIV2 - Journals E2E", - "method": "TestGetJournals" - }, - { - "codeunitId": 139827, - "codeunitName": "APIV2 - Journals E2E", - "method": "TestModifyJournal" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestActionCancelAndSendCorrectiveCreditMemo" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestActionCancelCorrectiveCreditMemo" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestActionPostAndSendCreditMemo" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestActionPostCreditMemo" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestActionSendCancelledCreditMemo" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestActionSendPostedCreditMemo" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestCreateCreditMemoThroughPageAndAPI" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestDeleteCreditMemo" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestEmptyModifyCreditMemos" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestGetCreditMemos" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestGetCreditMemosAppliesDiscountPct" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestGetCreditMemosRedistributesDiscountAmt" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestModifyCreditMemos" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestModifyCreditMemoSetManualDiscount" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestPartialModifyCreditMemos" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestPostCreditMemos" - }, - { - "codeunitId": 139828, - "codeunitName": "APIV2 - Sales Credit Memos E2E", - "method": "TestPostCreditMemoWithCurrency" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestActionPostPurchaseInvoice" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestCreateInvoiceThroughPageAndAPI" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestDeleteInvoice" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestEmptyModifyInvoices" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestGetInvoiceFromPostedOrderCorrectOrderIdAndNo" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestGetInvoices" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestGetPurchaseInvoiceFromDraftId" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestModifyInvoices" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestPartialModifyInvoices" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestPostInvoices" - }, - { - "codeunitId": 139829, - "codeunitName": "APIV2 - Purchase Invoices E2E", - "method": "TestPostPurchaseInvoiceWithCurrency" - }, - { - "codeunitId": 139830, - "codeunitName": "APIV2 - GLEntries E2E", - "method": "TestGetGLEntries" - }, - { - "codeunitId": 139831, - "codeunitName": "APIV2 - Automation RS Package", - "method": "TestApplyRSPackage" - }, - { - "codeunitId": 139831, - "codeunitName": "APIV2 - Automation RS Package", - "method": "TestCreateRSPackage" - }, - { - "codeunitId": 139831, - "codeunitName": "APIV2 - Automation RS Package", - "method": "TestImportRSPackage" - }, - { - "codeunitId": 139831, - "codeunitName": "APIV2 - Automation RS Package", - "method": "TestImportWrongRSPackage" - }, - { - "codeunitId": 139831, - "codeunitName": "APIV2 - Automation RS Package", - "method": "TestUploadRSPackageFile" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreateDraftInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreateDraftOrderAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreateDraftPurchaseCreditMemoAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreateDraftPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreateDraftPurchaseOrderAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreateGLEntryAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreateJournalLineAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreatePostedInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreatePostedPurchaseCreditMemoAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreatePostedPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestCreateQuoteAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestDeleteDraftInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestDeleteDraftPurchaseCreditMemoAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestDeleteDraftPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestDeleteGLEntryAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestDeleteJournalLineAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestDeletePostedInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestDeletePostedPurchaseCreditMemoAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestDeletePostedPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestDeleteQuoteAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetDraftInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetDraftInvoiceAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetDraftOrderAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetDraftOrderAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetDraftPurchaseCreditMemoAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetDraftPurchaseInvoiceAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetDraftPurchaseOrderAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetGLEntryAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetGLEntryAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetJournalAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetJournalLineAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetJournalLineAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetPostedInvoiceAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetPostedInvoiceAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetPostedPurchaseCreditMemoAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetPostedPurchaseInvoiceAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetQuoteAttachment" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestGetQuoteAttachments" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestLinkedAttachmentContentChangeKeepsOtherFieldsUnchanged" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestLinkedAttachmentDocumentIdChangeNotAllowed" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestLinkedAttachmentFileNameChangeKeepsOtherFieldsUnchanged" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestTransferAttachmentFromDraftToPostedInvoice" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestTransferAttachmentFromDraftToPostedPurchaseCreditMemo" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestTransferAttachmentFromDraftToPostedPurchaseInvoice" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestUpdateGenJournalLineAttachmentBinaryContent" - }, - { - "codeunitId": 139833, - "codeunitName": "APIV2 - Attachments E2E", - "method": "TestUpdateGLEntryAttachmentBinaryContent" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestDeleteInvoiceLine" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestDeletingLineKeepsInvoiceDiscountAmt" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestDeletingLineMovesInvoiceDiscountPct" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestDeletingLineRemovesInvoiceDiscountPct" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestGetInvoiceLineDirectly" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestGetInvoiceLines" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestGetInvoiceLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestGetPostedInvoiceLines" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestGettingLinesWithDifferentTypes" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestInsertingLineKeepsInvoiceDiscountAmt" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestInsertingLineUpdatesInvoiceDiscountPct" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestModifyingLineKeepsInvoiceDiscountAmt" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestModifyingLineUpdatesInvoiceDiscountPct" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestModifyInvoiceLine" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestModifyInvoiceLineWithUoM" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestPatchingTheIdToAccountChangesLineType" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestPatchingTheIdToItemChangesLineType" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestPostingBlankLineDefaultsToCommentType" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestPostInvoiceLines" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestPostInvoiceLinesWithItemVariant" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestPostInvoiceLinesWithUoM" - }, - { - "codeunitId": 139834, - "codeunitName": "APIV2 - Sales Inv. Lines E2E", - "method": "TestPostInvoiceLineWithSequence" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestCreatingOrderLineWithAssemblyBOM" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestDeleteOrderLine" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestDeletingLineKeepsOrderDiscountAmt" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestDeletingLineMovesOrderDiscountPct" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestDeletingLineRemovesOrderDiscountPct" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestExpandReturnsCorrectDocumentLines" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestExpandReturnsCorrectDocumentLinesWithMultipleDocuments" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestGetOrderLineDirectly" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestGetOrderLines" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestGetOrderLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestGettingLinesWithDifferentTypes" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestInsertingLineKeepsOrderDiscountAmt" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestInsertingLineUpdatesOrderDiscountPct" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestModifyingLineKeepsOrderDiscountAmt" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestModifyingLineUpdatesOrderDiscountPct" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestModifyOrderLines" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestPatchingTheIdToAccountChangesLineType" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestPatchingTheIdToItemChangesLineType" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestPostingBlankLineDefaultsToCommentType" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestPostOrderLines" - }, - { - "codeunitId": 139835, - "codeunitName": "APIV2 - Sales Order Lines E2E", - "method": "TestPostOrderLineWithItemVariant" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestDeleteQuoteLine" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestDeletingLineKeepsQuoteDiscountAmt" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestDeletingLineMovesQuoteDiscountPct" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestDeletingLineRemovesQuoteDiscountPct" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestGetQuoteLineDirectly" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestGetQuoteLines" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestGetQuoteLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestInsertingLineKeepsQuoteDiscountAmt" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestInsertingLineUpdatesQuoteDiscountPct" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestModifyingLineKeepsQuoteDiscountAmt" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestModifyingLineUpdatesQuoteDiscountPct" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestModifyQuoteLines" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestPostingBlankLineDefaultsToCommentType" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestPostQuoteLines" - }, - { - "codeunitId": 139836, - "codeunitName": "APIV2 - Sales Quote Lines E2E", - "method": "TestPostQuoteLinesWithItemVariant" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestDeleteCreditMemoLine" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestDeletePostedCreditMemoLine" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestDeletingLineKeepsCreditMemoDiscountAmt" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestDeletingLineMovesCreditMemoDiscountPct" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestDeletingLineRemovesCreditMemoDiscountPct" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestGetCreditMemoLineDirectly" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestGetCreditMemoLines" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestGetCreditMemoLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestGetPostedCreditMemoLines" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestGettingLinesWithDifferentTypes" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestInsertingLineKeepsCreditMemoDiscountAmt" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestInsertingLineUpdatesCreditMemoDiscountPct" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestModifyCreditMemoLines" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestModifyingLineKeepsCreditMemoDiscountAmt" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestModifyingLineUpdatesCreditMemoDiscountPct" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestPatchingTheIdToAccountChangesLineType" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestPatchingTheIdToItemChangesLineType" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestPostCreditMemoLines" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestPostCreditMemoLinesWithItemVariant" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestPostCreditMemoLineWithSequence" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestPostingBlankLineDefaultsToCommentType" - }, - { - "codeunitId": 139837, - "codeunitName": "APIV2 - Sales CrMemo Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestDeleteInvoiceLine" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestDeletingLineRemovesInvoiceDiscountPct" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestGetInvoiceLineDirectly" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestGetInvoiceLines" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestGetInvoiceLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestGetPostedInvoiceLines" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestInsertingLineKeepsInvoiceDiscountAmt" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestInsertingLineUpdatesInvoiceDiscountPct" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestModifyingLineUpdatesInvoiceDiscountPct" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestModifyInvoiceLines" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestPostingBlankLineDefaultsToCommentType" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestPostInvoiceLines" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestPostInvoiceLinesWithItemVariant" - }, - { - "codeunitId": 139838, - "codeunitName": "APIV2 - Purchase Inv Lines E2E", - "method": "TestPostInvoiceLineWithSequence" - }, - { - "codeunitId": 139839, - "codeunitName": "APIV2 - Item Variants E2E", - "method": "TestCreateItemVariantWithItemId" - }, - { - "codeunitId": 139839, - "codeunitName": "APIV2 - Item Variants E2E", - "method": "TestCreateItemVariantWithItemNumber" - }, - { - "codeunitId": 139839, - "codeunitName": "APIV2 - Item Variants E2E", - "method": "TestCreateItemVariantWithItemNumberAndItemId" - }, - { - "codeunitId": 139839, - "codeunitName": "APIV2 - Item Variants E2E", - "method": "TestDeleteInUse" - }, - { - "codeunitId": 139839, - "codeunitName": "APIV2 - Item Variants E2E", - "method": "TestDeleteItemVariant" - }, - { - "codeunitId": 139839, - "codeunitName": "APIV2 - Item Variants E2E", - "method": "TestGetItemVariant" - }, - { - "codeunitId": 139839, - "codeunitName": "APIV2 - Item Variants E2E", - "method": "TestModifyItemVariant" - }, - { - "codeunitId": 139839, - "codeunitName": "APIV2 - Item Variants E2E", - "method": "TestModifyItemVariantItemId" - }, - { - "codeunitId": 139839, - "codeunitName": "APIV2 - Item Variants E2E", - "method": "TestModifyItemVariantItemNumber" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestAppliesToInvoiceNoAndIdSync" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestCreateCustomerPayment" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestCreateCustomerPaymentWithInvoiceId" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestCreateCustomerPaymentWithoutDocNo" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestCustomerAutofillDoesNotOverwrite" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestCustomerAutofillWhenGivingInvoiceNumber" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestCustomerNoAndIdSync" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestDeleteCustomerPayment" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestGetCustomerPayment" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestModifyCustomerPayment" - }, - { - "codeunitId": 139840, - "codeunitName": "APIV2 - Customer Payments E2E", - "method": "TestModifyCustomerPaymentWithRandomDocNo" - }, - { - "codeunitId": 139841, - "codeunitName": "APIV2 - PDF Document E2E", - "method": "TestGetPDFPurchaseCreditMemo" - }, - { - "codeunitId": 139841, - "codeunitName": "APIV2 - PDF Document E2E", - "method": "TestGetPDFPurchaseInvoice" - }, - { - "codeunitId": 139841, - "codeunitName": "APIV2 - PDF Document E2E", - "method": "TestGetPDFSalesCreditMemo" - }, - { - "codeunitId": 139841, - "codeunitName": "APIV2 - PDF Document E2E", - "method": "TestGetPDFSalesInvoice" - }, - { - "codeunitId": 139841, - "codeunitName": "APIV2 - PDF Document E2E", - "method": "TestGetPDFSalesOrder" - }, - { - "codeunitId": 139841, - "codeunitName": "APIV2 - PDF Document E2E", - "method": "TestGetPDFSalesQuote" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadataContact" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadataContactWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadataCustomer" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadataCustomerWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadataEmployee" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadataEmployeeWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadataItem" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadataVendor" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadataVendorWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureMetadatItemWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueContact" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueContactWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueCustomer" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueCustomerWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueEmployee" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueEmployeeWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueItem" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueItemWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueVendor" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestGetPictureValueVendorWithoutPicture" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureDeleteContact" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureDeleteCustomer" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureDeleteEmployee" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureDeleteItem" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureDeleteVendor" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureReplaceContact" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureReplaceCustomer" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureReplaceEmployee" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureReplaceItem" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureReplaceVendor" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureUploadContact" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureUploadCustomer" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureUploadEmployee" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureUploadItem" - }, - { - "codeunitId": 139842, - "codeunitName": "APIV2 - Pictures E2E", - "method": "TestPictureUploadVendor" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestAppliesToInvoiceNoAndIdSync" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestAppliesToInvoiceNumberEmptyForNonInvoiceApplication" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestCreateVendorPayment" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestCreateVendorPaymentWithInvoiceId" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestCreateVendorPaymentWithoutDocNo" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestDeleteVendorPayment" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestGetVendorPayment" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestGetVendorPaymentWithoutInvoiceApplicationIsVisible" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestModifyVendorPayment" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestModifyVendorPaymentWithRandomDocNo" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestVendorAutofillDoesNotOverwrite" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestVendorAutofillWhenGivingInvoiceNumber" - }, - { - "codeunitId": 139843, - "codeunitName": "APIV2 - Vendor Payments E2E", - "method": "TestVendorNoAndIdSync" - }, - { - "codeunitId": 139847, - "codeunitName": "APIV2 - Sales Shipments E2E", - "method": "TestExpandDimensions" - }, - { - "codeunitId": 139847, - "codeunitName": "APIV2 - Sales Shipments E2E", - "method": "TestGetSalesShipments" - }, - { - "codeunitId": 139848, - "codeunitName": "APIV2 - Sales Ship. Lines E2E", - "method": "TestExpandDimensions" - }, - { - "codeunitId": 139848, - "codeunitName": "APIV2 - Sales Ship. Lines E2E", - "method": "TestGetLineDirectly" - }, - { - "codeunitId": 139848, - "codeunitName": "APIV2 - Sales Ship. Lines E2E", - "method": "TestGetShipmentLines" - }, - { - "codeunitId": 139848, - "codeunitName": "APIV2 - Sales Ship. Lines E2E", - "method": "TestGetShipmentLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139849, - "codeunitName": "APIV2 - Purchase Receipts E2E", - "method": "TestExpandDimensions" - }, - { - "codeunitId": 139849, - "codeunitName": "APIV2 - Purchase Receipts E2E", - "method": "TestGetPurchaseReceipts" - }, - { - "codeunitId": 139850, - "codeunitName": "APIV2 - Purch. Rcpt. Lines E2E", - "method": "TestExpandDimensions" - }, - { - "codeunitId": 139850, - "codeunitName": "APIV2 - Purch. Rcpt. Lines E2E", - "method": "TestGetLineDirectly" - }, - { - "codeunitId": 139850, - "codeunitName": "APIV2 - Purch. Rcpt. Lines E2E", - "method": "TestGetReceiptLines" - }, - { - "codeunitId": 139850, - "codeunitName": "APIV2 - Purch. Rcpt. Lines E2E", - "method": "TestGetReceiptLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestActionRecieveAndInvoice" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestCreateOrderThroughPageAndAPI" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestDeleteOrders" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestEmptyModifyOrders" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestGetOrders" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestGetOrdersAppliesDiscountPct" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestGetOrdersRedistributesDiscountAmt" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestModifyOrders" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestModifyOrderSetManualDiscount" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestPartialModifyOrders" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestPostOrderForCustomerWithLocationCode" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestPostOrders" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestPostOrdersWithEmptyShippingAddress" - }, - { - "codeunitId": 139851, - "codeunitName": "APIV2 - Purchase Orders E2E", - "method": "TestPostOrderWithCurrency" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestDeleteOrderLine" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestDeletingLineKeepsOrderDiscountAmt" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestDeletingLineMovesOrderDiscountPct" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestDeletingLineRemovesOrderDiscountPct" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestGetOrderLineDirectly" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestGetOrderLines" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestGetOrderLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestGettingLinesWithDifferentTypes" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestInsertingLineKeepsOrderDiscountAmt" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestInsertingLineUpdatesOrderDiscountPct" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestModifyingLineKeepsOrderDiscountAmt" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestModifyingLineUpdatesOrderDiscountPct" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestModifyOrderLines" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestPatchingTheIdToAccountChangesLineType" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestPatchingTheIdToItemChangesLineType" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestPostingBlankLineDefaultsToCommentType" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestPostOrderLines" - }, - { - "codeunitId": 139852, - "codeunitName": "APIV2 - Purch. Order Lines E2E", - "method": "TestPostOrderLineWithItemVariant" - }, - { - "codeunitId": 139853, - "codeunitName": "APIV2 - Contacts Inf. E2E", - "method": "TestGetCustomerContactInformation" - }, - { - "codeunitId": 139853, - "codeunitName": "APIV2 - Contacts Inf. E2E", - "method": "TestGetCustomerContactsInformation" - }, - { - "codeunitId": 139853, - "codeunitName": "APIV2 - Contacts Inf. E2E", - "method": "TestGetVendorContactInformation" - }, - { - "codeunitId": 139853, - "codeunitName": "APIV2 - Contacts Inf. E2E", - "method": "TestGetVendorContactsInformation" - }, - { - "codeunitId": 139854, - "codeunitName": "APIV2 - Item Ledg. Entries E2E", - "method": "TestGetItemLedgerEntries" - }, - { - "codeunitId": 139855, - "codeunitName": "APIV2 - Opportunities E2E", - "method": "TestCannotPatchContactNoOfWonOpportunity" - }, - { - "codeunitId": 139855, - "codeunitName": "APIV2 - Opportunities E2E", - "method": "TestCannotPatchSPCodeOfWonOpportunity" - }, - { - "codeunitId": 139855, - "codeunitName": "APIV2 - Opportunities E2E", - "method": "TestCreateOpportunity" - }, - { - "codeunitId": 139855, - "codeunitName": "APIV2 - Opportunities E2E", - "method": "TestCreateOpportunityContactNo" - }, - { - "codeunitId": 139855, - "codeunitName": "APIV2 - Opportunities E2E", - "method": "TestGetOpportunities" - }, - { - "codeunitId": 139855, - "codeunitName": "APIV2 - Opportunities E2E", - "method": "TestPatchOpportunity" - }, - { - "codeunitId": 139856, - "codeunitName": "APIV2 - GenProdPostGroup E2E", - "method": "TestGetGenProdPostGroups" - }, - { - "codeunitId": 139857, - "codeunitName": "APIV2 - InventoryPostGroup E2E", - "method": "TestGetInventoryPostGroups" - }, - { - "codeunitId": 139858, - "codeunitName": "APIV2 Currency Exch. Rate E2E", - "method": "TestGetCurrencyExchangeRates" - }, - { - "codeunitId": 139858, - "codeunitName": "APIV2 Currency Exch. Rate E2E", - "method": "TestSingleGetCurrencyExchangeRate" - }, - { - "codeunitId": 139859, - "codeunitName": "APIV2 - Accounting Periods E2E", - "method": "TestGetAccountingPeriods" - }, - { - "codeunitId": 139860, - "codeunitName": "APIV2 - G/L Setup E2E", - "method": "TestGetGLSetup" - }, - { - "codeunitId": 139861, - "codeunitName": "APIV2JobQueueLogEntriesE2E", - "method": "TestGetJobQueueLogEntry" - }, - { - "codeunitId": 139862, - "codeunitName": "APIV2JobQueueEntriesE2E", - "method": "TestGetCorrespondingJobQueueLogEntryFromExpand" - }, - { - "codeunitId": 139862, - "codeunitName": "APIV2JobQueueEntriesE2E", - "method": "TestGetCorrespondingJobQueueLogEntryFromSubPage" - }, - { - "codeunitId": 139862, - "codeunitName": "APIV2JobQueueEntriesE2E", - "method": "TestGetJobQueueEntry" - }, - { - "codeunitId": 139862, - "codeunitName": "APIV2JobQueueEntriesE2E", - "method": "TestRescheduleJobQueueEntry" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestActionCancelCorrectiveCreditMemo" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestActionPostCreditMemo" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestClearingManualDiscounts" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestCreateCreditMemoThroughPageAndAPI" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestDeleteCreditMemo" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestEmptyModifyCreditMemos" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestGetCreditMemos" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestModifyCreditMemos" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestModifyCreditMemoSetManualDiscount" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestPartialModifyCreditMemos" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestPostCreditMemos" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestPostCreditMemoWithCurrency" - }, - { - "codeunitId": 139865, - "codeunitName": "APIV2 - Purch. Cr. Memos E2E", - "method": "TestPostCreditMemoWithVendorCreditMemoNo" - }, - { - "codeunitId": 139866, - "codeunitName": "APIV2 - Contacts E2E", - "method": "TestDeleteContact" - }, - { - "codeunitId": 139866, - "codeunitName": "APIV2 - Contacts E2E", - "method": "TestGetContactWithAddressAndSpecialCharacters" - }, - { - "codeunitId": 139866, - "codeunitName": "APIV2 - Contacts E2E", - "method": "TestGetSimpleContact" - }, - { - "codeunitId": 139866, - "codeunitName": "APIV2 - Contacts E2E", - "method": "TestModifyContactWithAddress" - }, - { - "codeunitId": 139867, - "codeunitName": "APIV2 - Apply Vendor Ent. E2E", - "method": "TestApplyVendorEntryAppliesPayment" - }, - { - "codeunitId": 139867, - "codeunitName": "APIV2 - Apply Vendor Ent. E2E", - "method": "TestGetApplyVendorEntriesFailsWhenNoVendor" - }, - { - "codeunitId": 139867, - "codeunitName": "APIV2 - Apply Vendor Ent. E2E", - "method": "TestGetApplyVendorEntriesReturnsOpenEntries" - }, - { - "codeunitId": 139868, - "codeunitName": "APIV2 - Locations E2E", - "method": "TestCreateLocation" - }, - { - "codeunitId": 139868, - "codeunitName": "APIV2 - Locations E2E", - "method": "TestCreateSalesOrderLineWithLocation" - }, - { - "codeunitId": 139868, - "codeunitName": "APIV2 - Locations E2E", - "method": "TestDeleteLocation" - }, - { - "codeunitId": 139868, - "codeunitName": "APIV2 - Locations E2E", - "method": "TestGetLocation" - }, - { - "codeunitId": 139868, - "codeunitName": "APIV2 - Locations E2E", - "method": "TestModifyLocationWithAddress" - }, - { - "codeunitId": 139869, - "codeunitName": "APIV2 - Cust. Ret. Reasons E2E", - "method": "TestCreateReasonCode" - }, - { - "codeunitId": 139869, - "codeunitName": "APIV2 - Cust. Ret. Reasons E2E", - "method": "TestDeleteReasonCode" - }, - { - "codeunitId": 139869, - "codeunitName": "APIV2 - Cust. Ret. Reasons E2E", - "method": "TestGetReasonCode" - }, - { - "codeunitId": 139869, - "codeunitName": "APIV2 - Cust. Ret. Reasons E2E", - "method": "TestModifyReasonCode" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestCreateLineThroughPageAndAPI" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestDeleteCreditMemoLine" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestDeletePostedCreditMemoLine" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestGetCreditMemoLineDirectly" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestGetCreditMemoLines" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestGetCreditMemoLinesDirectlyWithDocumentIdFilter" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestGetPostedCreditMemoLines" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestGettingLinesWithDifferentTypes" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestModifyCreditMemoLines" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestPatchingTheIdToAccountChangesLineType" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestPatchingTheIdToItemChangesLineType" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestPatchingTheTypeBlanksIds" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestPostCreditMemoLines" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestPostCreditMemoLinesWithItemVariant" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestPostCreditMemoLineWithSequence" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestPostingBlankLineDefaultsToCommentType" - }, - { - "codeunitId": 139874, - "codeunitName": "APIV2 - Purch. Cr.M. Lines E2E", - "method": "TestPostingCommentLine" - }, - { - "codeunitId": 139882, - "codeunitName": "APIV2 - Salesperson/Purch E2E", - "method": "CreateSalespersonPurchaser" - }, - { - "codeunitId": 139882, - "codeunitName": "APIV2 - Salesperson/Purch E2E", - "method": "DeleteSalespersonPurchaser" - }, - { - "codeunitId": 139882, - "codeunitName": "APIV2 - Salesperson/Purch E2E", - "method": "GetSalespersonPurchaser" - }, - { - "codeunitId": 139882, - "codeunitName": "APIV2 - Salesperson/Purch E2E", - "method": "ModifySalespersonPurchaserJobTitle" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreateCustomerAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreateDraftInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreateDraftOrderAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreateDraftPurchaseCreditMemoAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreateDraftPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreateDraftPurchaseOrderAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreatePostedInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreatePostedPurchaseCreditMemoAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreatePostedPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreateQuoteAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestCreateVendorAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeleteDraftInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeleteDraftPurchaseCreditMemoAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeleteDraftPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeleteEmployeeAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeleteJobAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeletePostedInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeletePostedPurchaseCreditMemoAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeletePostedPurchaseInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeleteQuoteAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestDeleteVendorAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetCustomerAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetDraftInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetDraftInvoiceAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetDraftOrderAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetDraftPurchaseCreditMemoAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetDraftPurchaseInvoiceAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetDraftPurchaseOrderAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetEmployeeAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetItemAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetJobAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetPostedInvoiceAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetPostedInvoiceAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetPostedPurchaseCreditMemoAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetPostedPurchaseInvoiceAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetQuoteAttachment" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetQuoteAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestGetVendorAttachments" - }, - { - "codeunitId": 139899, - "codeunitName": "APIV2 - Document Attach. E2E", - "method": "TestUpdateCustomerAttachmentBinaryContent" - }, - { - "codeunitId": 139906, - "codeunitName": "APIV2 - FA Locations E2E", - "method": "TestCreateFALocation" - }, - { - "codeunitId": 139906, - "codeunitName": "APIV2 - FA Locations E2E", - "method": "TestDeleteFALocation" - }, - { - "codeunitId": 139906, - "codeunitName": "APIV2 - FA Locations E2E", - "method": "TestGetFALocation" - }, - { - "codeunitId": 139906, - "codeunitName": "APIV2 - FA Locations E2E", - "method": "TestModifyFALocation" - }, - { - "codeunitId": 139907, - "codeunitName": "APIV2 - Fixed Assets E2E", - "method": "TestCreateFixedAsset" - }, - { - "codeunitId": 139907, - "codeunitName": "APIV2 - Fixed Assets E2E", - "method": "TestDeleteFixedAsset" - }, - { - "codeunitId": 139907, - "codeunitName": "APIV2 - Fixed Assets E2E", - "method": "TestGetFixedAsset" - }, - { - "codeunitId": 139907, - "codeunitName": "APIV2 - Fixed Assets E2E", - "method": "TestModifyFixedAsset" - }, - { - "codeunitId": 139908, - "method": "TestGetBlanketPurchaseOrders", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestGetBlanketPurchaseOrderById", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestGetBlanketSalesOrders", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestGetBlanketSalesOrderById", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139917, - "method": "TestGetApprovalEntries", - "codeunitName": "APIV2 - Approval Entries E2E" - }, - { - "codeunitId": 139918, - "method": "TestGetApprovalUserSetup", - "codeunitName": "APIV2 - Approval UserSetup E2E" - }, - { - "codeunitId": 139919, - "method": "TestGetPostedApprovalEntries", - "codeunitName": "APIV2 PstdApprovalEntries E2E" - }, - { - "codeunitId": 139920, - "method": "TestGetApprovalEntries", - "codeunitName": "APIV2 - Workflow Approvers E2E" - }, - { - "codeunitId": 139921, - "method": "TestGetApprovalEntries", - "codeunitName": "APIV2 - Workflows E2E" - }, - { - "codeunitId": 139922, - "method": "TestGetPurchaseQuotes", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestGetPurchaseQuoteById", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139923, - "method": "TestGetPurchaseReturnOrders", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestGetPurchaseReturnOrderById", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestGetSalesReturnOrders", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestGetSalesReturnOrderById", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestGetAssemblyOrders", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestGetAssemblyOrderById", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestGetTransferOrders", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestGetTransferOrderById", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139927, - "method": "TestGetSalesOrderArchives", - "codeunitName": "APIV2 - Sales Ord. Arch. E2E" - }, - { - "codeunitId": 139927, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Sales Ord. Arch. E2E" - }, - { - "codeunitId": 139927, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Sales Ord. Arch. E2E" - }, - { - "codeunitId": 139927, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Sales Ord. Arch. E2E" - }, - { - "codeunitId": 139928, - "method": "TestGetPurchaseReturnShipments", - "codeunitName": "APIV2 - Purch. Ret. Shpts. E2E" - }, - { - "codeunitId": 139928, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Purch. Ret. Shpts. E2E" - }, - { - "codeunitId": 139928, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Purch. Ret. Shpts. E2E" - }, - { - "codeunitId": 139928, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Purch. Ret. Shpts. E2E" - }, - { - "codeunitId": 139908, - "method": "TestGetBlanketPurchaseOrders", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestGetBlanketPurchaseOrderById", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139908, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Bl. Purch. Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestGetBlanketSalesOrders", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestGetBlanketSalesOrderById", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139909, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Bl. Sales Orders E2E" - }, - { - "codeunitId": 139917, - "method": "TestGetApprovalEntries", - "codeunitName": "APIV2 - Approval Entries E2E" - }, - { - "codeunitId": 139918, - "method": "TestGetApprovalUserSetup", - "codeunitName": "APIV2 - Approval UserSetup E2E" - }, - { - "codeunitId": 139919, - "method": "TestGetPostedApprovalEntries", - "codeunitName": "APIV2 PstdApprovalEntries E2E" - }, - { - "codeunitId": 139920, - "method": "TestGetApprovalEntries", - "codeunitName": "APIV2 - Workflow Approvers E2E" - }, - { - "codeunitId": 139921, - "method": "TestGetApprovalEntries", - "codeunitName": "APIV2 - Workflows E2E" - }, - { - "codeunitId": 139922, - "method": "TestGetPurchaseQuotes", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestGetPurchaseQuoteById", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139922, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Purch. Quotes E2E" - }, - { - "codeunitId": 139923, - "method": "TestGetPurchaseReturnOrders", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestGetPurchaseReturnOrderById", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139923, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Purch. Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestGetSalesReturnOrders", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestGetSalesReturnOrderById", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139924, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Sales Ret. Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestGetAssemblyOrders", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestGetAssemblyOrderById", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139925, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Assembly Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestGetTransferOrders", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestGetTransferOrderById", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139926, - "method": "TestExpandLines", - "codeunitName": "APIV2 - Transfer Orders E2E" - }, - { - "codeunitId": 139927, - "method": "TestGetSalesOrderArchives", - "codeunitName": "APIV2 - Sales Ord. Arch. E2E" - }, - { - "codeunitId": 139927, - "method": "TestExpandDimensionSetLines", - "codeunitName": "APIV2 - Sales Ord. Arch. E2E" - }, - { - "codeunitId": 139927, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Sales Ord. Arch. E2E" - }, - { - "codeunitId": 139927, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Sales Ord. Arch. E2E" - }, - { - "codeunitId": 139928, - "method": "TestGetPurchaseReturnShipments", - "codeunitName": "APIV2 - Purch. Ret. Shpts. E2E" - }, - { - "codeunitId": 139928, - "method": "TestExpandAttachments", - "codeunitName": "APIV2 - Purch. Ret. Shpts. E2E" - }, - { - "codeunitId": 139928, - "method": "TestExpandDocumentAttachments", - "codeunitName": "APIV2 - Purch. Ret. Shpts. E2E" - }, - { - "codeunitId": 139928, - "method": "TestExpandPdfDocument", - "codeunitName": "APIV2 - Purch. Ret. Shpts. E2E" } ] diff --git a/src/Layers/APAC/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/APAC/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index 707e6a229cd..c067400bcea 100644 --- a/src/Layers/APAC/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/APAC/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7574,4 +7574,3 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } - diff --git a/src/Layers/APAC/Tests/Prepayment/ERMPrepaymentII.Codeunit.al b/src/Layers/APAC/Tests/Prepayment/ERMPrepaymentII.Codeunit.al index be7ad2bb239..514e712534e 100644 --- a/src/Layers/APAC/Tests/Prepayment/ERMPrepaymentII.Codeunit.al +++ b/src/Layers/APAC/Tests/Prepayment/ERMPrepaymentII.Codeunit.al @@ -2694,7 +2694,6 @@ codeunit 134101 "ERM Prepayment II" GenJournalLine.Modify(true); LibraryERM.PostGeneralJnlLine(GenJournalLine); end; - local procedure SelectGenJournalBatch(var GenJournalBatch: Record "Gen. Journal Batch") begin // Select General Journal Batch and clear General Journal Lines to make sure that no line exist before creating diff --git a/src/Layers/CH/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/CH/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index c81c9d60800..b3452ad5d49 100644 --- a/src/Layers/CH/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/CH/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7372,4 +7372,3 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } - diff --git a/src/Layers/CZ/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/CZ/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index 4ed0a80f174..667c49a4ce0 100644 --- a/src/Layers/CZ/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/CZ/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7578,4 +7578,3 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } - diff --git a/src/Layers/ES/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/ES/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index 0f00c3467cc..e0c84c365c5 100644 --- a/src/Layers/ES/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/ES/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7607,4 +7607,3 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } - diff --git a/src/Layers/IT/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/IT/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index 0044783f068..f8af226c9fe 100644 --- a/src/Layers/IT/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/IT/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7573,4 +7573,3 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } - diff --git a/src/Layers/NA/Tests/Prepayment/ERMPrepaymentII.Codeunit.al b/src/Layers/NA/Tests/Prepayment/ERMPrepaymentII.Codeunit.al index e514b0407b0..6cc9605ec93 100644 --- a/src/Layers/NA/Tests/Prepayment/ERMPrepaymentII.Codeunit.al +++ b/src/Layers/NA/Tests/Prepayment/ERMPrepaymentII.Codeunit.al @@ -2632,7 +2632,6 @@ codeunit 134101 "ERM Prepayment II" GenJournalLine.Modify(true); LibraryERM.PostGeneralJnlLine(GenJournalLine); end; - local procedure SelectGenJournalBatch(var GenJournalBatch: Record "Gen. Journal Batch") begin // Select General Journal Batch and clear General Journal Lines to make sure that no line exist before creating diff --git a/src/Layers/W1/BaseApp/Purchases/eServices/EDocument/ReturnShptPDFDocHandler.Codeunit.al b/src/Layers/W1/BaseApp/Purchases/eServices/EDocument/ReturnShptPDFDocHandler.Codeunit.al index 22cc094eec4..d9a2ed5f429 100644 --- a/src/Layers/W1/BaseApp/Purchases/eServices/EDocument/ReturnShptPDFDocHandler.Codeunit.al +++ b/src/Layers/W1/BaseApp/Purchases/eServices/EDocument/ReturnShptPDFDocHandler.Codeunit.al @@ -36,7 +36,7 @@ codeunit 4999 "Return Shpt. PDF Doc.Handler" implements IPdfDocumentHandler exit(false); ReturnShipment.SetRange("No.", ReturnShipment."No."); - ReportUsage := "Report Selection Usage"::"P.Return"; + ReportUsage := "Report Selection Usage"::"P.Ret.Shpt."; ReportSelections.GetPdfReportForVend(TempBlob, ReportUsage, ReturnShipment, ReturnShipment."Buy-from Vendor No."); DocumentMailing.GetAttachmentFileName(Name, ReturnShipment."No.", ReturnShipmentLbl, ReportUsage.AsInteger()); exit(PDFDocumentManagement.AddToTempAttachmentEntityBuffer(DocumentId, DocumentType, TempBlob, Name, TempAttachmentEntityBuffer)); diff --git a/src/Layers/W1/Tests/ERM/SpendRequestTests.Codeunit.al b/src/Layers/W1/Tests/ERM/SpendRequestTests.Codeunit.al index 11f5d08109a..ea889fe6e72 100644 --- a/src/Layers/W1/Tests/ERM/SpendRequestTests.Codeunit.al +++ b/src/Layers/W1/Tests/ERM/SpendRequestTests.Codeunit.al @@ -341,6 +341,37 @@ codeunit 134242 "Spend Request Tests" 'Deleting detail should reduce header total.'); end; + [Test] + procedure DeleteDetailLineDecrementsHeaderTotalExactlyOnce() + var + SpendRequest: Record "Spend Request"; + FirstSpendRequestDetail: Record "Spend Request Detail"; + RemainingSpendRequestDetail: Record "Spend Request Detail"; + begin + // [SCENARIO 646383] Real detail deletion applies each LCY delta exactly once without removing the other detail. + Initialize(); + + // [GIVEN] An open LCY request "R" initially has zero total and two details "D1" and "D2" worth 10 and 30. + CreateSpendRequest(SpendRequest); + VerifyDetailDeletionTotals(SpendRequest."No.", 0, 0); + CreateSpendRequestDetail(FirstSpendRequestDetail, SpendRequest."No.", 10); + CreateSpendRequestDetail(RemainingSpendRequestDetail, SpendRequest."No.", 30); + VerifyDetailDeletionTotals(SpendRequest."No.", 40, 2); + + // [WHEN] Deleting "D1" runs the production table trigger, not a page action or a permission test. + FirstSpendRequestDetail.Delete(true); + + // [THEN] "D2" survives and both its amount and the header total are 30. + RemainingSpendRequestDetail.Get(RemainingSpendRequestDetail."Spend Request No.", RemainingSpendRequestDetail."Line No."); + VerifyDetailDeletionTotals(SpendRequest."No.", 30, 1); + + // [WHEN] The remaining detail "D2" is deleted through its production trigger. + RemainingSpendRequestDetail.Delete(true); + + // [THEN] No details remain and the header total is exactly zero. + VerifyDetailDeletionTotals(SpendRequest."No.", 0, 0); + end; + [Test] [Scope('OnPrem')] procedure CannotInsertDetailOnReleasedRequest() @@ -827,4 +858,21 @@ codeunit 134242 "Spend Request Tests" // [THEN] An error is raised. Assert.ExpectedError('must have the status ' + Format(SpendRequest.Status::Open)); end; + + local procedure VerifyDetailDeletionTotals(SpendRequestNo: Code[20]; ExpectedAmount: Decimal; ExpectedLineCount: Integer) + var + SpendRequest: Record "Spend Request"; + SpendRequestDetail: Record "Spend Request Detail"; + begin + SpendRequest.Get(SpendRequestNo); + Assert.AreEqual(SpendRequest.Status::Open, SpendRequest.Status, 'Detail deletion must preserve the Open status.'); + Assert.AreEqual('', SpendRequest."Currency Code", 'The request must use LCY.'); + Assert.AreEqual(ExpectedAmount, SpendRequest."Total Expected Amount", 'The header amount must reflect each deleted detail exactly once.'); + Assert.AreEqual(ExpectedAmount, SpendRequest."Total Expected Amount (LCY)", 'The LCY header amount must reflect each deleted detail exactly once.'); + SpendRequestDetail.SetRange("Spend Request No.", SpendRequestNo); + Assert.AreEqual(ExpectedLineCount, SpendRequestDetail.Count(), 'Only the intended details must be deleted.'); + SpendRequestDetail.CalcSums("Expected Amount", "Expected Amount (LCY)"); + Assert.AreEqual(ExpectedAmount, SpendRequestDetail."Expected Amount", 'The remaining detail amounts must be unchanged.'); + Assert.AreEqual(ExpectedAmount, SpendRequestDetail."Expected Amount (LCY)", 'The remaining LCY detail amounts must be unchanged.'); + end; } \ No newline at end of file diff --git a/src/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index 0bffda864c6..199d8aac30a 100644 --- a/src/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7573,4 +7573,3 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } - diff --git a/src/Layers/W1/Tests/Graph/IRS1099CodeEntityE2ETest.Codeunit.al b/src/Layers/W1/Tests/Graph/IRS1099CodeEntityE2ETest.Codeunit.al index 80c99fa6f1c..b2ebf6edd01 100644 --- a/src/Layers/W1/Tests/Graph/IRS1099CodeEntityE2ETest.Codeunit.al +++ b/src/Layers/W1/Tests/Graph/IRS1099CodeEntityE2ETest.Codeunit.al @@ -41,4 +41,3 @@ codeunit 135519 "IRS 1099 Code Entity E2E Test" IsInitialized := true; end; } - diff --git a/src/Layers/W1/Tests/Graph/WFWHSubscriptionE2ETests.Codeunit.al b/src/Layers/W1/Tests/Graph/WFWHSubscriptionE2ETests.Codeunit.al index f5b8e0f9859..9a15f918f0d 100644 --- a/src/Layers/W1/Tests/Graph/WFWHSubscriptionE2ETests.Codeunit.al +++ b/src/Layers/W1/Tests/Graph/WFWHSubscriptionE2ETests.Codeunit.al @@ -54,6 +54,7 @@ codeunit 135528 "WFWH Subscription E2E Tests" if IsInitialized then exit; + IsInitialized := true; Commit(); @@ -1454,4 +1455,3 @@ codeunit 135528 "WFWH Subscription E2E Tests" exit(String); end; } - diff --git a/src/Layers/W1/Tests/Integration/ApiRoutesE2E.Codeunit.al b/src/Layers/W1/Tests/Integration/ApiRoutesE2E.Codeunit.al index 6744a7e1cb5..82af76dc468 100644 --- a/src/Layers/W1/Tests/Integration/ApiRoutesE2E.Codeunit.al +++ b/src/Layers/W1/Tests/Integration/ApiRoutesE2E.Codeunit.al @@ -13,6 +13,10 @@ codeunit 135548 "API Routes E2E" LibraryGraphMgt: Codeunit "Library - Graph Mgt"; ApiRoutesTxt: Label 'apiRoutes', Locked = true; + local procedure Initialize() + begin + end; + [Test] [Scope('OnPrem')] procedure TestGetApiRoutesMany() @@ -21,6 +25,8 @@ codeunit 135548 "API Routes E2E" ResponseText: Text; begin // [SCENARIO] GET returns many routes in the payload + Initialize(); + // [GIVEN] apiRoutes URI without filters TargetURL := LibraryGraphMgt.CreateTargetURL('', PAGE::"API Routes", ApiRoutesTxt); @@ -39,6 +45,8 @@ codeunit 135548 "API Routes E2E" ResponseText: Text; begin // [SCENARIO] GET returns a single route in the payload + Initialize(); + // [GIVEN] apiRoutes URI for a single route TargetURL := LibraryGraphMgt.CreateTargetURL('''beta''', PAGE::"API Routes", ApiRoutesTxt); @@ -57,6 +65,8 @@ codeunit 135548 "API Routes E2E" ResponseText: Text; begin // [SCENARIO] POST is not allowed for apiRoutes + Initialize(); + // [GIVEN] apiRoutes URI for a single route TargetURL := LibraryGraphMgt.CreateTargetURL('', PAGE::"API Routes", ApiRoutesTxt); @@ -75,6 +85,8 @@ codeunit 135548 "API Routes E2E" ResponseText: Text; begin // [SCENARIO] PATCH is not allowed for apiRoutes + Initialize(); + // [GIVEN] apiRoutes URI for a single route TargetURL := LibraryGraphMgt.CreateTargetURL('''beta''', PAGE::"API Routes", ApiRoutesTxt); @@ -93,6 +105,8 @@ codeunit 135548 "API Routes E2E" ResponseText: Text; begin // [SCENARIO] DELETE is not allowed for apiRoutes + Initialize(); + // [GIVEN] apiRoutes URI for a single route TargetURL := LibraryGraphMgt.CreateTargetURL('''beta''', PAGE::"API Routes", ApiRoutesTxt); @@ -103,4 +117,3 @@ codeunit 135548 "API Routes E2E" Assert.ExpectedError('400 (BadRequest)'); end; } - diff --git a/src/Layers/W1/Tests/Integration/WebhookLogsE2E.Codeunit.al b/src/Layers/W1/Tests/Integration/WebhookLogsE2E.Codeunit.al index a5aad9c9707..861ad23e8d9 100644 --- a/src/Layers/W1/Tests/Integration/WebhookLogsE2E.Codeunit.al +++ b/src/Layers/W1/Tests/Integration/WebhookLogsE2E.Codeunit.al @@ -153,4 +153,3 @@ codeunit 135547 "Webhook Logs E2E" ActivityLog.DeleteAll(); end; } - diff --git a/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al b/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al index 30a124ae918..d7c2304a0da 100644 --- a/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al +++ b/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al @@ -5,10 +5,14 @@ #pragma warning disable AA0247 +using System.Environment; +using System.Security.AccessControl; + codeunit 139494 "API Test Auth Provider Tests" { EventSubscriberInstance = Manual; Subtype = Test; + RequiredTestIsolation = Disabled; TestPermissions = Disabled; trigger OnRun() @@ -23,6 +27,7 @@ codeunit 139494 "API Test Auth Provider Tests" LibraryGraphMgt: Codeunit "Library - Graph Mgt"; LibraryUtility: Codeunit "Library - Utility"; WebServiceManagement: Codeunit "Web Service Management"; + IdentityManagement: Codeunit "Identity Management"; SecondLibraryGraphMgt: Codeunit "Library - Graph Mgt"; FirstHttpWebRequestMgt: Codeunit "Http Web Request Mgt."; SecondHttpWebRequestMgt: Codeunit "Http Web Request Mgt."; @@ -31,14 +36,138 @@ codeunit 139494 "API Test Auth Provider Tests" ProviderCallTok: Label 'Provider|%1', Locked = true, Comment = '%1 - Provider invocation number'; EventCallTok: Label 'Event', Locked = true; UnexpectedCallErr: Label 'Unexpected authentication call.'; + ForcedRollbackErr: Label 'Roll back the API authentication fixture.'; + + [Test] + [NonDebuggable] + [TransactionModel(TransactionModel::AutoCommit)] + procedure MissingKeyIsCommittedBeforeHttpRequest() + var + TargetURL: Text; + ResponseText: Text; + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO] First-use authentication creates a key visible to the independent HTTP session + Initialize(); + + // [GIVEN] The disposable test user's key is missing at a committed fixture boundary + IdentityManagement.ClearWebServicesKey(UserSecurityId()); + Commit(); + TargetURL := GetUrl(ClientType::ODataV4); + + // [WHEN] A request uses the default provider without explicit selection + LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, TargetURL, 200); + + // [THEN] The request authenticates and only NavUserPassword requires a generated key + VerifyKeyPresenceForServerMode(); + VerifyNextCall(EventCallTok); + VerifyNoRemainingCalls(); + end; + + [Test] + [NonDebuggable] + [TransactionModel(TransactionModel::AutoCommit)] + procedure ExistingKeySurvivesLibraryReset() + var + ExistingKey: Text[80]; + TargetURL: Text; + ResponseText: Text; + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO] A committed non-expiring key is reused across Graph library instances + Initialize(); + + // [GIVEN] The disposable test user has a committed key without an expiry + ExistingKey := IdentityManagement.CreateWebServicesKeyNoExpiry(UserSecurityId()); + Commit(); + TargetURL := GetUrl(ClientType::ODataV4); + + // [WHEN] Two independently initialized library instances authenticate + LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, TargetURL, 200); + Clear(LibraryGraphMgt); + LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, TargetURL, 200); + + // [THEN] Neither the key nor its expiry is changed + VerifyExistingKey(ExistingKey); + Clear(ExistingKey); + VerifyNextCall(EventCallTok); + VerifyNextCall(EventCallTok); + VerifyNoRemainingCalls(); + end; + + [Test] + [NonDebuggable] + [TransactionModel(TransactionModel::AutoCommit)] + procedure MissingKeyDoesNotCommitFixture() + var + CurrentUser: Record User; + OriginalFullName: Text[80]; + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO] Missing-key authentication cannot commit unrelated changes to user U + Initialize(); + + // [GIVEN] User U has no key and an uncommitted fixture change + IdentityManagement.ClearWebServicesKey(UserSecurityId()); + Commit(); + CurrentUser.Get(UserSecurityId()); + OriginalFullName := CurrentUser."Full Name"; + CurrentUser."Full Name" := 'API authentication rollback fixture'; + CurrentUser.Modify(); + + // [WHEN] Authentication rejects unsafe first use, or ambient authentication reaches the forced rollback + asserterror InitializeRequestAndFail(); + + // [THEN] The expected error leaves neither a committed fixture nor a newly created key + Assert.ExpectedError(GetExpectedFixtureError()); + Assert.ExpectedErrorCode('Dialog'); + CurrentUser.Get(UserSecurityId()); + Assert.IsTrue(CurrentUser."Full Name" = OriginalFullName, 'Authentication must not commit the user fixture.'); + Assert.IsTrue(GetCurrentWebServiceKey() = '', 'Unsafe first use must not create a key.'); + VerifyFixtureRequestCalls(); + VerifyNoRemainingCalls(); + end; + + [Test] + [TransactionModel(TransactionModel::None)] + procedure DefaultAuthenticationRespectsServerAuthMode() + var + EnvironmentInfo: Codeunit "Environment Information"; + TargetURL: Text; + ResponseText: Text; + begin + // [FEATURE] [AI test 1.0] + // [SCENARIO] Default authentication uses the current user's committed key or ambient Windows credentials + Initialize(); + + // [GIVEN] An OnPrem service and a read-only test method with no fixture transaction to commit + Assert.IsFalse(EnvironmentInfo.IsSaaSInfrastructure(), 'This HTTP scenario requires an OnPrem test environment.'); + TargetURL := GetUrl(ClientType::ODataV4); + + // [WHEN] The default provider sends a request without explicit provider selection + LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, TargetURL, 200); + + // [THEN] Authentication completes before the independent HTTP session reads the key + VerifyNextCall(EventCallTok); + + // [WHEN] A fresh library instance sends another request + Clear(LibraryGraphMgt); + LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, TargetURL, 200); + + // [THEN] Authentication does not depend on an instance-local credential cache + VerifyNextCall(EventCallTok); + VerifyNoRemainingCalls(); + end; [Test] - procedure DefaultAuthenticationDoesNotConfigureRequest() + procedure ExplicitNoneDoesNotConfigureRequest() begin - // [SCENARIO] The default API test authentication does not configure the request + // [FEATURE] [AI test 1.0] + // [SCENARIO] Explicit None retains ambient authentication without resolving the default provider Initialize(); - // [GIVEN] A Graph library instance without an explicitly selected provider + // [GIVEN] A Graph library instance with authentication explicitly disabled + LibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::None); // [WHEN] A web request is initialized LibraryGraphMgt.InitializeWebRequestWithURL(FirstHttpWebRequestMgt, TargetURLTok); @@ -95,8 +224,9 @@ codeunit 139494 "API Test Auth Provider Tests" // [SCENARIO] Authentication provider selection is scoped to a Graph library instance Initialize(); - // [GIVEN] Two Graph library instances where only the first uses the mock provider + // [GIVEN] Two Graph library instances with different explicit providers LibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::Mock); + SecondLibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::None); // [WHEN] Each Graph library instance initializes a web request LibraryGraphMgt.InitializeWebRequestWithURL(FirstHttpWebRequestMgt, TargetURLTok); @@ -275,6 +405,51 @@ codeunit 139494 "API Test Auth Provider Tests" exit(LibraryGraphMgt.CreateTargetURL('', Page::"Customer List", '')); end; + [NonDebuggable] + local procedure GetCurrentWebServiceKey(): Text[80] + var + WebServiceKey: Text[80]; + begin + ClearLastError(); + WebServiceKey := IdentityManagement.GetWebServicesKey(UserSecurityId()); + Assert.IsTrue(GetLastErrorText() = '', 'The current user key must be readable.'); + exit(WebServiceKey); + end; + + [NonDebuggable] + local procedure VerifyKeyPresenceForServerMode() + begin + Assert.AreEqual( + IdentityManagement.IsUserNamePasswordAuthentication(), GetCurrentWebServiceKey() <> '', + 'Only NavUserPassword authentication should provision a key for the request.'); + end; + + [NonDebuggable] + local procedure VerifyExistingKey(ExistingKey: Text[80]) + begin + Assert.IsTrue(ExistingKey = GetCurrentWebServiceKey(), 'Authentication must not rotate an existing key.'); + Assert.AreEqual(0DT, IdentityManagement.GetWebServiceExpiryDate(UserSecurityId()), 'A non-expiring key must stay non-expiring.'); + end; + + local procedure InitializeRequestAndFail() + begin + LibraryGraphMgt.InitializeWebRequestWithURL(FirstHttpWebRequestMgt, TargetURLTok); + Error(ForcedRollbackErr); + end; + + local procedure GetExpectedFixtureError(): Text + begin + if IdentityManagement.IsUserNamePasswordAuthentication() then + exit('The API test web service key is missing and cannot be created while the caller has uncommitted writes.'); + exit(ForcedRollbackErr); + end; + + local procedure VerifyFixtureRequestCalls() + begin + if not IdentityManagement.IsUserNamePasswordAuthentication() then + VerifyNextCall(EventCallTok); + end; + local procedure VerifyNextCall(ExpectedCall: Text) begin APITestAuthProviderTests.VerifyRecordedCall(ExpectedCall); diff --git a/src/Layers/W1/Tests/Prepayment/ERMPrepaymentII.Codeunit.al b/src/Layers/W1/Tests/Prepayment/ERMPrepaymentII.Codeunit.al index 27e8b022b74..ac9aa24db4e 100644 --- a/src/Layers/W1/Tests/Prepayment/ERMPrepaymentII.Codeunit.al +++ b/src/Layers/W1/Tests/Prepayment/ERMPrepaymentII.Codeunit.al @@ -2575,7 +2575,6 @@ codeunit 134101 "ERM Prepayment II" GenJournalLine.Modify(true); LibraryERM.PostGeneralJnlLine(GenJournalLine); end; - local procedure SelectGenJournalBatch(var GenJournalBatch: Record "Gen. Journal Batch") begin // Select General Journal Batch and clear General Journal Lines to make sure that no line exist before creating @@ -3145,4 +3144,3 @@ codeunit 134101 "ERM Prepayment II" PurchaseHeader.TestField(Status, ExpectedStatus); end; } - diff --git a/src/Layers/W1/Tests/TestLibraries/LibraryGraphDocumentTools.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/LibraryGraphDocumentTools.Codeunit.al index cc281f04818..33c9bb8c8f0 100644 --- a/src/Layers/W1/Tests/TestLibraries/LibraryGraphDocumentTools.Codeunit.al +++ b/src/Layers/W1/Tests/TestLibraries/LibraryGraphDocumentTools.Codeunit.al @@ -1,10 +1,6 @@ codeunit 130619 "Library - Graph Document Tools" { - trigger OnRun() - begin - end; - var LibraryApplicationArea: Codeunit "Library - Application Area"; LibrarySales: Codeunit "Library - Sales"; @@ -582,17 +578,16 @@ codeunit 130619 "Library - Graph Document Tools" VATBusinessPostingGroup: Record "VAT Business Posting Group"; FixedAsset: Record "Fixed Asset"; GLAccount: Record "G/L Account"; - VATPostingSetup: Record "VAT Posting Setup"; begin LibraryInventory.CreateItemCharge(ItemCharge); + EnsureVATPostingSetupExists( + SalesHeader."VAT Bus. Posting Group", ItemCharge."VAT Prod. Posting Group"); LibrarySales.CreateSalesLine(SalesLineCharge, SalesHeader, SalesLineCharge.Type::"Charge (Item)", ItemCharge."No.", 1); LibraryERM.FindVATBusinessPostingGroup(VATBusinessPostingGroup); LibraryResource.CreateResource(Resource, VATBusinessPostingGroup.Code); - VATPostingSetup.SetRange("VAT Bus. Posting Group", SalesHeader."VAT Bus. Posting Group"); - VATPostingSetup.SetRange("VAT Prod. Posting Group", Resource."VAT Prod. Posting Group"); - if not VATPostingSetup.FINDFIRST() then - LibraryERM.CreateVATPostingSetup(VATPostingSetup, SalesHeader."VAT Bus. Posting Group", Resource."VAT Prod. Posting Group"); + EnsureVATPostingSetupExists( + SalesHeader."VAT Bus. Posting Group", Resource."VAT Prod. Posting Group"); LibrarySales.CreateSalesLine(SalesLineResource, SalesHeader, SalesLineResource.Type::Resource, Resource."No.", 1); LibraryFixedAsset.CreateFixedAsset(FixedAsset); @@ -619,6 +614,8 @@ codeunit 130619 "Library - Graph Document Tools" GLAccount: Record "G/L Account"; begin LibraryInventory.CreateItemCharge(ItemCharge); + EnsureVATPostingSetupExists( + PurchaseHeader."VAT Bus. Posting Group", ItemCharge."VAT Prod. Posting Group"); LibraryPurchase.CreatePurchaseLine( PurchaseLineCharge, PurchaseHeader, PurchaseLineCharge.Type::"Charge (Item)", ItemCharge."No.", 1); @@ -636,10 +633,27 @@ codeunit 130619 "Library - Graph Document Tools" GLAccount.SetRange("Direct Posting", true); #pragma warning restore AA0210 GLAccount.FindFirst(); + EnsureVATPostingSetupExists( + PurchaseHeader."VAT Bus. Posting Group", GLAccount."VAT Prod. Posting Group"); LibraryPurchase.CreatePurchaseLine( PurchaseLineGLAccount, PurchaseHeader, PurchaseLineGLAccount.Type::"G/L Account", GLAccount."No.", 1); end; + /// Creates VAT posting setup when the specified posting-group combination does not exist. + /// VAT business posting group. + /// VAT product posting group. + procedure EnsureVATPostingSetupExists(VATBusPostingGroup: Code[20]; VATProdPostingGroup: Code[20]) + var + VATPostingSetup: Record "VAT Posting Setup"; + begin + if (VATBusPostingGroup = '') and (VATProdPostingGroup = '') then + exit; + if VATPostingSetup.Get(VATBusPostingGroup, VATProdPostingGroup) then + exit; + + LibraryERM.CreateVATPostingSetup(VATPostingSetup, VATBusPostingGroup, VATProdPostingGroup); + end; + [Scope('OnPrem')] procedure VerifySalesObjectTxtDescription(SalesLine: Record "Sales Line"; JObjectTxt: Text) var @@ -895,4 +909,3 @@ codeunit 130619 "Library - Graph Document Tools" Assert.AreEqual(ExpectedDiscountAmount, ActualInvoiceDiscountAmount, 'Invoice discount amount was not set'); end; } - diff --git a/src/Layers/W1/Tests/TestLibraries/LibraryGraphJournalLines.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/LibraryGraphJournalLines.Codeunit.al index ea303197684..0dd713743fc 100644 --- a/src/Layers/W1/Tests/TestLibraries/LibraryGraphJournalLines.Codeunit.al +++ b/src/Layers/W1/Tests/TestLibraries/LibraryGraphJournalLines.Codeunit.al @@ -1,10 +1,6 @@ codeunit 130622 "Library - Graph Journal Lines" { - trigger OnRun() - begin - end; - var LibraryERM: Codeunit "Library - ERM"; LibrarySales: Codeunit "Library - Sales"; @@ -235,6 +231,11 @@ codeunit 130622 "Library - Graph Journal Lines" begin JournalName := LibraryUtility.GenerateRandomCode(GenJournalBatch.FieldNo(Name), DATABASE::"Gen. Journal Batch"); LibraryAPIGeneralJournal.EnsureGenJnlBatchExists(GraphMgtJournal.GetDefaultVendorPaymentsTemplateName(), JournalName); + GenJournalBatch.Get(GraphMgtJournal.GetDefaultVendorPaymentsTemplateName(), JournalName); + if GenJournalBatch."No. Series" = '' then begin + GenJournalBatch.Validate("No. Series", LibraryERM.CreateNoSeriesCode()); + GenJournalBatch.Modify(true); + end; exit(JournalName); end; @@ -321,4 +322,3 @@ codeunit 130622 "Library - Graph Journal Lines" Assert.AreEqual(NewDate, GenJournalLine."Posting Date", 'Journal Line ' + PostingDateNameTxt + ' should be changed'); end; } - diff --git a/src/Layers/W1/Tests/TestLibraries/LibraryGraphMgt.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/LibraryGraphMgt.Codeunit.al index 38b8c0f8bf8..8dfabe2d07a 100644 --- a/src/Layers/W1/Tests/TestLibraries/LibraryGraphMgt.Codeunit.al +++ b/src/Layers/W1/Tests/TestLibraries/LibraryGraphMgt.Codeunit.al @@ -16,8 +16,25 @@ codeunit 130618 "Library - Graph Mgt" FailedRequestErr: Label '%1 request failed. Response code is %2 (%3). %4', Comment = '%1 - request method, %2 - response code number, %3 - response code, %4 - error message'; FailedRequestWithUnexpectedResponseCodeErr: Label '%1 request failed. Response code is %2 (%3), expected code is %4. %5', Comment = '%1 - request method, %2 - response code number, %3 - response code, %4 - expected response code, %5 - error message'; + /// Adds a field to the ignored-field buffer when the field exists in the source table. + /// Temporary ignored-field buffer. + /// Source table number. + /// Source field name. + procedure AddFieldToIgnoreIfExists(var TempIgnoredFields: Record 2000000041 temporary; SourceTableNo: Integer; SourceFieldName: Text) + var + RecordField: Record Field; + LibraryUtility: Codeunit "Library - Utility"; + begin + RecordField.SetRange(TableNo, SourceTableNo); + RecordField.SetRange(FieldName, SourceFieldName); + if RecordField.FindFirst() then + LibraryUtility.AddTempField(TempIgnoredFields, RecordField."No.", SourceTableNo); + end; + /// /// Sets the authentication provider used by this library instance. + /// Without an explicit selection, the Microsoft test provider is used. + /// Select None to retain only ambient credentials and the final request event. /// Selecting the same provider preserves its cached state. /// /// The authentication provider to use for subsequent API test requests. @@ -31,6 +48,12 @@ codeunit 130618 "Library - Graph Mgt" AuthenticationProviderResolved := true; end; + /// Sets the work date to November 15 in the current year to stay within test-license date limits. + procedure SetLicenseSafeWorkDate() + begin + WorkDate := DMY2Date(15, 11, Date2DMY(Today, 3)); + end; + procedure EnsureWebServiceExist(ServiceNameTxt: Text[240]; PageNumber: Integer) var WebService: Record "Web Service"; @@ -172,6 +195,7 @@ codeunit 130618 "Library - Graph Mgt" local procedure GetAuthenticationProvider(): Interface "API Test Auth Provider" begin if not AuthenticationProviderResolved then begin + Authentication := Authentication::"Microsoft Test Environment"; AuthenticationProvider := Authentication; AuthenticationProviderResolved := true; end; diff --git a/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al index e0516d38988..579f3767941 100644 --- a/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al +++ b/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al @@ -5,11 +5,9 @@ namespace Microsoft.TestLibraries.ERP; -using System; -using System.Azure.KeyVault; using System.Environment; using System.Security.AccessControl; -using System.Test.Library; +using System.TestTools.TestRunner; /// /// Provides authentication for API tests running in Microsoft test environments. @@ -19,78 +17,137 @@ codeunit 131022 "Microsoft Test Auth Provider" implements "API Test Auth Provide Access = Internal; var - ApiTestPasswordFileTok: Label 'C:\Run\my\ApiTestPassword', Locked = true; - NavServerUserPasswordKeyTok: Label 'NavServerUserPassword', Locked = true; - CachedAuthenticationPassword: SecretText; - ContainerPasswordReadErr: Label 'The API test password could not be read from %1.', Comment = '%1 - Password file path'; - KeyVaultPasswordReadErr: Label 'The API test password could not be retrieved from the %1 secret.', Comment = '%1 - Azure Key Vault secret name'; - PasswordRetrievalFailedErr: Label 'The API test password could not be retrieved.'; + KeyRetrievalFailedErr: Label 'The API test web service key could not be retrieved. Check the current user permissions.'; + ExpiredKeyErr: Label 'The current user web service key has expired. Renew it explicitly before running API tests.'; + EmptyKeyErr: Label 'An empty API test web service key was returned.'; + KeyCreationInWriteTransactionErr: Label 'The API test web service key is missing and cannot be created while the caller has uncommitted writes. Initialize API authentication before fixture writes or use an existing committed fixture boundary.'; + KeyCreationFailedErr: Label 'The API test web service key could not be created in an isolated transaction. Check the current user permissions and test environment.'; /// - /// Configures authentication for API test requests, preserving ambient authentication on Windows and SaaS. + /// Uses the current user's web service key only with NavUserPassword authentication on-premises. + /// Preserves ambient authentication for Windows, SaaS, and other authentication modes. + /// Existing keys are reused without caching; missing keys are created with a 24-hour expiry. + /// First use requires a read-only caller so the isolated key transaction cannot commit fixture data. /// /// The authentication context to configure. procedure ConfigureAuthentication(var Authentication: Codeunit "API Test Auth Context") var EnvironmentInfo: Codeunit "Environment Information"; - SecurityGroup: Codeunit "Security Group"; + IdentityManagement: Codeunit "Identity Management"; begin if EnvironmentInfo.IsSaaSInfrastructure() then exit; - if SecurityGroup.IsWindowsAuthentication() then + if not IdentityManagement.IsUserNamePasswordAuthentication() then exit; - Authentication.SetBasicAuthentication(UserId(), GetAuthenticationPassword()); + Authentication.SetBasicAuthentication(UserId(), GetWebServiceKey()); end; - local procedure GetAuthenticationPassword(): SecretText + [NonDebuggable] + local procedure GetWebServiceKey(): SecretText var - Password: SecretText; + WebServiceKey: SecretText; + ExpiryDate: DateTime; + KeyCreationSucceeded: Boolean; + begin + WebServiceKey := ReadWebServiceKey(ExpiryDate); + if WebServiceKey.IsEmpty() then begin + if Database.IsInWriteTransaction() then + Error(KeyCreationInWriteTransactionErr); + + // Isolated events commit only their subscriber transaction, never caller fixture writes. + OnCreateWebServiceKey(KeyCreationSucceeded); + if not KeyCreationSucceeded then + Error(KeyCreationFailedErr); + + // VAR changes survive subscriber rollback. Never use a credential returned by the event. + WebServiceKey := ReadWebServiceKey(ExpiryDate); + end; + if WebServiceKey.IsEmpty() then + Error(EmptyKeyErr); + if (ExpiryDate <> 0DT) and (ExpiryDate <= CurrentDateTime()) then + Error(ExpiredKeyErr); + exit(WebServiceKey); + end; + + [InternalEvent(false, true)] + local procedure OnCreateWebServiceKey(var Succeeded: Boolean) begin - if not CachedAuthenticationPassword.IsEmpty() then - exit(CachedAuthenticationPassword); - - if ContainerPasswordFileExists() then begin - if not TryGetContainerPassword(Password) then - Error(ContainerPasswordReadErr, ApiTestPasswordFileTok); - end else - if not TryGetNavEnlistmentPassword(Password) then - Error(KeyVaultPasswordReadErr, NavServerUserPasswordKeyTok); - - CachedAuthenticationPassword := Password; - exit(CachedAuthenticationPassword); end; - [Scope('OnPrem')] - local procedure ContainerPasswordFileExists(): Boolean + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Test Runner - Mgt", 'OnBeforeTestMethodRun', '', false, false)] + [NonDebuggable] + local procedure PrepareTestUserWebServiceKey(var CurrentTestMethodLine: Record "Test Method Line"; CodeunitID: Integer; CodeunitName: Text[30]; FunctionName: Text[128]; FunctionTestPermissions: TestPermissions; var Skip: Boolean) var - File: DotNet File; + EnvironmentInfo: Codeunit "Environment Information"; + IdentityManagement: Codeunit "Identity Management"; begin - exit(File.Exists(ApiTestPasswordFileTok)); + if Skip or EnvironmentInfo.IsSaaSInfrastructure() then + exit; + if not IdentityManagement.IsUserNamePasswordAuthentication() then + exit; + + // OnBeforeTestRun commits its own transaction before the test's fixture transaction starts. + EnsureWebServiceKey(); + end; + + [EventSubscriber(ObjectType::Codeunit, Codeunit::"Microsoft Test Auth Provider", 'OnCreateWebServiceKey', '', false, false)] + [NonDebuggable] + [CommitBehavior(CommitBehavior::Error)] + local procedure CreateWebServiceKeyIsolated(var Succeeded: Boolean) + begin + EnsureWebServiceKey(); + Succeeded := true; end; - [TryFunction] [NonDebuggable] - local procedure TryGetContainerPassword(var Password: SecretText) + local procedure EnsureWebServiceKey() var - MockAzureKeyvaultSecretProvider: DotNet MockAzureKeyVaultSecretProvider; + CurrentUser: Record User; + IdentityManagement: Codeunit "Identity Management"; + WebServiceKey: SecretText; + ExpiryDate: DateTime; begin - // Read through a private provider without replacing the session's Azure Key Vault provider or cache. - MockAzureKeyvaultSecretProvider := MockAzureKeyvaultSecretProvider.MockAzureKeyVaultSecretProvider(); - MockAzureKeyvaultSecretProvider.AddSecretMappingFromFile(NavServerUserPasswordKeyTok, ApiTestPasswordFileTok); - Password := MockAzureKeyvaultSecretProvider.GetSecret(NavServerUserPasswordKeyTok); - if Password.IsEmpty() then - Error(PasswordRetrievalFailedErr); + WebServiceKey := ReadWebServiceKey(ExpiryDate); + if not WebServiceKey.IsEmpty() then + exit; + + // Serialize first use for this tenant/user; native key creation otherwise replaces an existing key. + CurrentUser.LockTable(); + CurrentUser.Get(UserSecurityId()); + WebServiceKey := ReadWebServiceKey(ExpiryDate); + if WebServiceKey.IsEmpty() then begin + ExpiryDate := CurrentDateTime() + 24 * 60 * 60 * 1000; + WebServiceKey := IdentityManagement.CreateWebServicesKey(UserSecurityId(), ExpiryDate); + end; + if WebServiceKey.IsEmpty() then + Error(EmptyKeyErr); end; - [TryFunction] - local procedure TryGetNavEnlistmentPassword(var Password: SecretText) + [NonDebuggable] + local procedure ReadWebServiceKey(var ExpiryDate: DateTime): SecretText var - AzureKeyVault: Codeunit "Azure Key Vault"; + IdentityManagement: Codeunit "Identity Management"; + WebServiceKey: Text[80]; + SecretWebServiceKey: SecretText; begin - if not AzureKeyVault.GetAzureKeyVaultSecret(NavServerUserPasswordKeyTok, Password) then - Error(PasswordRetrievalFailedErr); - if Password.IsEmpty() then - Error(PasswordRetrievalFailedErr); + // Identity Management substitutes error text on failure. Check fresh error state, not key format. + ClearLastError(); + WebServiceKey := IdentityManagement.GetWebServicesKey(UserSecurityId()); + if GetLastErrorText() <> '' then begin + Clear(WebServiceKey); + Error(KeyRetrievalFailedErr); + end; + SecretWebServiceKey := WebServiceKey; + Clear(WebServiceKey); + + // The expiry getter also substitutes a value on failure. + ClearLastError(); + ExpiryDate := IdentityManagement.GetWebServiceExpiryDate(UserSecurityId()); + if GetLastErrorText() <> '' then begin + Clear(SecretWebServiceKey); + Error(KeyRetrievalFailedErr); + end; + exit(SecretWebServiceKey); end; } diff --git a/src/Layers/W1/Tests/TestLibraries/app.json b/src/Layers/W1/Tests/TestLibraries/app.json index c7c2a8db600..de739aae611 100644 --- a/src/Layers/W1/Tests/TestLibraries/app.json +++ b/src/Layers/W1/Tests/TestLibraries/app.json @@ -7,6 +7,12 @@ "url": "https://go.microsoft.com/fwlink/?LinkId=724011", "propagateDependencies": true, "dependencies": [ + { + "id": "23de40a6-dfe8-4f80-80db-d70f83ce8caf", + "name": "Test Runner", + "publisher": "Microsoft", + "version": "30.0.0.0" + }, { "id": "9856ae4f-d1a7-46ef-89bb-6ef056398228", "name": "System Application Test Library", From e18d6e1a9dfc91627eb0fe40eddb9088a6c37ce9 Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Fri, 9 Oct 2026 13:57:30 +0200 Subject: [PATCH 2/9] Simplify default API web-service-key authentication Use the enum default, remove the no-op provider and runner coupling, and create keys only when missing or expired. Remove obsolete build-auth tests and AI feature tags; preserve clean-tenant execution. Correct Windows project keys for the bounded validation run. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91 --- .github/AL-Go-Settings.json | 20 +-- LOCAL_DEV_ENV.md | 53 +++----- .../scripts/tests/ApiTestCredential.Test.ps1 | 117 ------------------ .../Misc/APITestAuthProviderTests.Codeunit.al | 92 +++++++------- .../APITestAuthentication.Enum.al | 7 +- .../TestLibraries/LibraryGraphMgt.Codeunit.al | 4 +- .../MicrosoftTestAuthProvider.Codeunit.al | 77 +----------- .../NoAPITestAuthProvider.Codeunit.al | 22 ---- src/Layers/W1/Tests/TestLibraries/app.json | 6 - 9 files changed, 80 insertions(+), 318 deletions(-) delete mode 100644 build/scripts/tests/ApiTestCredential.Test.ps1 delete mode 100644 src/Layers/W1/Tests/TestLibraries/NoAPITestAuthProvider.Codeunit.al diff --git a/.github/AL-Go-Settings.json b/.github/AL-Go-Settings.json index be27f285838..10c0190c1a6 100644 --- a/.github/AL-Go-Settings.json +++ b/.github/AL-Go-Settings.json @@ -31,16 +31,16 @@ ], "settings": { "projects": [ - "build/projects/Apps W1", - "build/projects/Apps DE", - "build/projects/Apps CA", - "build/projects/Apps US", - "build/projects/Apps IT", - "build/projects/Test Apps W1", - "build/projects/Test Apps DE", - "build/projects/Test Apps CA", - "build/projects/Test Apps US", - "build/projects/Test Apps IT" + "build\\projects\\Apps W1", + "build\\projects\\Apps DE", + "build\\projects\\Apps CA", + "build\\projects\\Apps US", + "build\\projects\\Apps IT", + "build\\projects\\Test Apps W1", + "build\\projects\\Test Apps DE", + "build\\projects\\Test Apps CA", + "build\\projects\\Test Apps US", + "build\\projects\\Test Apps IT" ], "maxTestAppReruns": 0 } diff --git a/LOCAL_DEV_ENV.md b/LOCAL_DEV_ENV.md index 488186dbaa6..55e0b00502a 100644 --- a/LOCAL_DEV_ENV.md +++ b/LOCAL_DEV_ENV.md @@ -49,44 +49,25 @@ Key Vault password lookup. Container and test-session credentials are still required to provision and connect to the NST; they are not handed to API requests. On-premises **NavUserPassword** requests use the current user's web service key. -The standard AL test runner prepares a missing key in `OnBeforeTestRun`, whose -transaction finishes before the test method starts. This also supports read-only -API tests using `AutoCommit` or `AutoRollback`, which start a write transaction -even without fixture writes. Preparation applies to the current test user when -`Tests-TestLibraries` is installed, including non-API tests; it does not select -credentials for individual requests or rotate an existing key. No key is -provisioned by the pipeline or extension installation. - -An existing valid key is read on each request without a credential cache. If no -key exists, a read-only caller raises an internal isolated event. Its subscriber -locks and rechecks the current user, then creates a key with a 24-hour expiry. -The platform commits this separate key transaction before returning; the provider -then rereads the key rather than trusting an event output that could survive a -rollback. The lock and recheck prevent competing test sessions for the same -tenant/user from replacing each other's newly created key. - -If the key is missing and the caller has uncommitted writes, authentication fails -explicitly **without committing fixture data**. Initialize authentication before -fixture writes or use the test's existing committed fixture boundary; do not add -a request-side commit to hide an incomplete fixture. Existing valid keys remain -read-only even when the caller has writes. Expired keys fail explicitly rather -than silently rotating credentials used by other clients. - -Isolated events have different semantics during extension install/upgrade; API -test requests belong in normal test execution, not installation/upgrade triggers. -First-use visibility to the separate HTTP session, rollback, and concurrent first -use still require target-server validation; source-contract tests alone do not -establish those runtime results. +The provider reads the key and expiry for each request, reuses a valid key +(including one without an expiry), and creates a key with a 24-hour expiry when +the key is missing or expired. Credentials are not cached or logged. + +There are no authentication event subscribers, test-runner dependencies, or +pipeline key-provisioning steps. The provider does not call `Commit()`. +`Identity Management` may create the key in the caller's existing transaction; +the independent HTTP session requires committed credentials, just as it requires +committed fixture data. First-use visibility at the test's transaction boundary +must therefore be verified on the target server. Concurrent creation by separate +sessions for the same tenant/user is not serialized by this provider. Windows, SaaS, and other authentication modes retain ambient authentication. -Custom enum providers and `SetAuthenticationProvider` remain supported. Explicit -`Enum::"API Test Authentication"::None` still opts out, including on the first -request. The final `OnAfterInitializeWebRequestWithURL` event still runs after the -provider. Event-only custom authentication that must avoid default key acquisition -should explicitly select `None` before creating the request. -This request-level opt-out does not undo the standard runner's test-user key -preparation. Custom runners can prepare the key before starting test transactions, -or use the read-only first-request path. +`API Test Authentication` uses the Microsoft provider as its +`DefaultImplementation`; value zero is `Default`. The explicit +`Microsoft Test Environment` value retains ordinal one. The previous `None` +value and no-op provider are removed. Custom enum providers and +`SetAuthenticationProvider` remain supported, and the final +`OnAfterInitializeWebRequestWithURL` event still runs after the provider. API fixture initializers reapply the existing test-license-compatible work date (November 15 of the current year) before creating date-sensitive data, including diff --git a/build/scripts/tests/ApiTestCredential.Test.ps1 b/build/scripts/tests/ApiTestCredential.Test.ps1 deleted file mode 100644 index 42fee402d84..00000000000 --- a/build/scripts/tests/ApiTestCredential.Test.ps1 +++ /dev/null @@ -1,117 +0,0 @@ -Describe 'API test authentication source contracts' { - BeforeAll { - $script:root = (Resolve-Path (Join-Path $PSScriptRoot '..\..\..')).Path - $libraryRoot = Join-Path $script:root 'src\Layers\W1\Tests\TestLibraries' - $script:provider = Get-Content (Join-Path $libraryRoot 'MicrosoftTestAuthProvider.Codeunit.al') -Raw - $script:graph = Get-Content (Join-Path $libraryRoot 'LibraryGraphMgt.Codeunit.al') -Raw - $script:authentication = Get-Content (Join-Path $libraryRoot 'APITestAuthentication.Enum.al') -Raw - $script:context = Get-Content (Join-Path $libraryRoot 'APITestAuthContext.Codeunit.al') -Raw - $script:container = Get-Content (Join-Path $script:root 'build\scripts\NewBcContainer.ps1') -Raw - } - - It 'defaults only unresolved library instances to Microsoft authentication' { - $script:graph | Should -Match '(?s)local procedure GetAuthenticationProvider\(\).*?if not AuthenticationProviderResolved then begin\s+Authentication := Authentication::"Microsoft Test Environment";' - $script:graph | Should -Match '(?s)procedure SetAuthenticationProvider\(.*?Authentication := NewAuthentication;\s+AuthenticationProvider := Authentication;\s+AuthenticationProviderResolved := true;' - } - - It 'preserves explicit None and unknown enum fallback semantics' { - $script:authentication | Should -Match '(?s)value\(0; None\).*?Implementation = "API Test Auth Provider" = "No API Test Auth Provider";' - $script:authentication | Should -Match 'DefaultImplementation = "API Test Auth Provider" = "No API Test Auth Provider";' - $script:authentication | Should -Match 'Extensible = true;' - } - - It 'preserves custom provider instance state on repeated selection' { - $script:graph | Should -Match '(?s)if AuthenticationProviderResolved and \(Authentication = NewAuthentication\) then\s+exit;' - } - - It 'retains ambient credentials and the final customization event after authentication' { - $script:graph | Should -Match '(?s)SetUseDefaultCredentials\(true\);\s+ApplyAuthentication\(HttpWebRequestMgt\);\s+OnAfterInitializeWebRequestWithURL\(HttpWebRequestMgt\);' - } - - It 'configures keys only on premises with exact username-password authentication' { - $script:provider | Should -Match '(?s)if EnvironmentInfo.IsSaaSInfrastructure\(\) then\s+exit;\s+if not IdentityManagement.IsUserNamePasswordAuthentication\(\) then\s+exit;\s+Authentication.SetBasicAuthentication\(UserId\(\), GetWebServiceKey\(\)\);' - } - - It 'reuses current-user keys and serializes missing-key creation with a recheck' { - $script:provider | Should -Match '(?s)local procedure EnsureWebServiceKey.*?CurrentUser.LockTable\(\);\s+CurrentUser.Get\(UserSecurityId\(\)\);\s+WebServiceKey := ReadWebServiceKey\(ExpiryDate\);\s+if WebServiceKey.IsEmpty\(\) then begin' - $script:provider | Should -Match 'CreateWebServicesKey\(UserSecurityId\(\), ExpiryDate\)' - $script:provider | Should -Not -Match 'CreateWebServicesKeyNoExpiry|ClearWebServicesKey' - } - - It 'prepares the current test user in the independent runner transaction before fixtures' { - $script:provider | Should -Match '\[EventSubscriber\(ObjectType::Codeunit, Codeunit::"Test Runner - Mgt", ''OnBeforeTestMethodRun''' - $script:provider | Should -Match '(?s)local procedure PrepareTestUserWebServiceKey.*?if Skip or EnvironmentInfo.IsSaaSInfrastructure\(\) then\s+exit;.*?if not IdentityManagement.IsUserNamePasswordAuthentication\(\) then\s+exit;.*?EnsureWebServiceKey\(\);' - $script:provider | Should -Match 'using System.TestTools.TestRunner;' - $manifest = Get-Content (Join-Path $script:root 'src\Layers\W1\Tests\TestLibraries\app.json') -Raw | ConvertFrom-Json - @($manifest.dependencies | Where-Object id -eq '23de40a6-dfe8-4f80-80db-d70f83ce8caf').Count | Should -Be 1 - } - - It 'rejects missing-key creation during caller writes before entering isolation' { - $script:provider | Should -Match '(?s)WebServiceKey := ReadWebServiceKey\(ExpiryDate\);\s+if WebServiceKey.IsEmpty\(\) then begin\s+if Database.IsInWriteTransaction\(\) then\s+Error\(KeyCreationInWriteTransactionErr\);.*?OnCreateWebServiceKey\(KeyCreationSucceeded\);' - $requestPath = [regex]::Match($script:provider, '(?s)local procedure GetWebServiceKey\(\).*?(?=\s+\[InternalEvent)').Value - $requestPath | Should -Not -Match 'LockTable|CreateWebServicesKey\(' - } - - It 'uses a platform-owned isolated subscriber transaction without explicit commits' { - $script:provider | Should -Match '(?s)\[InternalEvent\(false, true\)\]\s+local procedure OnCreateWebServiceKey' - $script:provider | Should -Match '\[EventSubscriber\(ObjectType::Codeunit, Codeunit::"Microsoft Test Auth Provider", ''OnCreateWebServiceKey''' - $script:provider | Should -Match '(?s)\[CommitBehavior\(CommitBehavior::Error\)\]\s+local procedure CreateWebServiceKeyIsolated' - } - - It 'rereads persisted credentials after isolation instead of trusting rollback-surviving event output' { - $script:provider | Should -Match '(?s)OnCreateWebServiceKey\(KeyCreationSucceeded\);\s+if not KeyCreationSucceeded then\s+Error\(KeyCreationFailedErr\);.*?WebServiceKey := ReadWebServiceKey\(ExpiryDate\);' - $script:provider | Should -Match 'local procedure OnCreateWebServiceKey\(var Succeeded: Boolean\)' - $script:provider | Should -Not -Match 'OnCreateWebServiceKey\([^)]*SecretText' - } - - It 'creates bounded keys and rejects expired or empty credentials' { - $script:provider | Should -Match 'ExpiryDate := CurrentDateTime\(\) \+ 24 \* 60 \* 60 \* 1000;' - $script:provider | Should -Match '(?s)if WebServiceKey.IsEmpty\(\) then\s+Error\(EmptyKeyErr\);' - $script:provider | Should -Match '(?s)if \(ExpiryDate <> 0DT\) and \(ExpiryDate <= CurrentDateTime\(\)\) then\s+Error\(ExpiredKeyErr\);' - } - - It 'checks fresh error state for both value-returning identity getters' { - $script:provider | Should -Match '(?s)ClearLastError\(\);\s+WebServiceKey := IdentityManagement.GetWebServicesKey\(UserSecurityId\(\)\);\s+if GetLastErrorText\(\) <>' - $script:provider | Should -Match '(?s)ClearLastError\(\);\s+ExpiryDate := IdentityManagement.GetWebServiceExpiryDate\(UserSecurityId\(\)\);\s+if GetLastErrorText\(\) <>' - } - - It 'does not cache, log, or hand off plaintext credentials' { - $script:provider | Should -Not -Match 'Cached|ApiTestPassword|KeyVault|PasswordFile|Message\(|LogMessage\(|Session.Log' - $script:provider | Should -Match '(?s)\[NonDebuggable\]\s+local procedure ReadWebServiceKey' - $script:provider | Should -Match 'SecretWebServiceKey: SecretText;' - $script:provider | Should -Match 'Clear\(WebServiceKey\);' - $script:context | Should -Match 'BasicPassword: SecretText;' - } - - It 'does not commit the caller transaction while configuring a request' { - $script:provider | Should -Not -Match '(?i)\bCommit\s*\(' - $requestPath = [regex]::Match($script:graph, '(?s)procedure InitializeWebRequestWithURL\(.*?(?= procedure PatchToWebServiceAndCheckResponseCode)').Value - $requestPath | Should -Not -BeNullOrEmpty - $requestPath | Should -Not -Match '(?i)\bCommit\s*\(' - } - - It 'retains container credentials for NST provisioning without an API password file' { - $script:container | Should -Match 'New-BcContainer @parameters' - $script:container | Should -Not -Match 'ApiTestCredential|ApiTestPassword' - Test-Path (Join-Path $script:root 'build\scripts\ApiTestCredential.psm1') | Should -BeFalse - Test-Path (Join-Path $script:root 'build\scripts\Remove-ApiTestPassword.ps1') | Should -BeFalse - Test-Path (Join-Path $script:root 'build\scripts\PipelineFinalize.ps1') | Should -BeFalse - @(Get-ChildItem (Join-Path $script:root 'build\projects') -Filter PipelineFinalize.ps1 -Recurse).Count | Should -Be 0 - } - - It 'keeps HTTP regression coverage on the default and instance-reset paths without explicit uptake' { - $tests = Get-Content (Join-Path $script:root 'src\Layers\W1\Tests\Misc\APITestAuthProviderTests.Codeunit.al') -Raw - $tests | Should -Match 'procedure DefaultAuthenticationRespectsServerAuthMode' - $tests | Should -Match '(?s)\[TransactionModel\(TransactionModel::None\)\]\s+procedure DefaultAuthenticationRespectsServerAuthMode' - $tests | Should -Match 'Clear\(LibraryGraphMgt\);' - $tests | Should -Not -Match '"Microsoft Test Environment"' - $tests | Should -Match 'SetAuthenticationProvider\(Enum::"API Test Authentication"::None\)' - $tests | Should -Match 'RequiredTestIsolation = Disabled;' - Test-Path (Join-Path $script:root 'src\Layers\W1\Tests\Misc\APITestAuthHTTPTests.Codeunit.al') | Should -BeFalse - } - - It 'retains a per-test license-safe date helper independent of authentication' { - $script:graph | Should -Match '(?s)procedure SetLicenseSafeWorkDate\(\)\s+begin\s+WorkDate := DMY2Date\(15, 11, Date2DMY\(Today, 3\)\);' - $script:provider | Should -Not -Match 'WorkDate|SetLicenseSafeWorkDate' - } -} diff --git a/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al b/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al index d7c2304a0da..d1c985b5897 100644 --- a/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al +++ b/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al @@ -46,7 +46,6 @@ codeunit 139494 "API Test Auth Provider Tests" TargetURL: Text; ResponseText: Text; begin - // [FEATURE] [AI test 1.0] // [SCENARIO] First-use authentication creates a key visible to the independent HTTP session Initialize(); @@ -73,7 +72,6 @@ codeunit 139494 "API Test Auth Provider Tests" TargetURL: Text; ResponseText: Text; begin - // [FEATURE] [AI test 1.0] // [SCENARIO] A committed non-expiring key is reused across Graph library instances Initialize(); @@ -98,12 +96,36 @@ codeunit 139494 "API Test Auth Provider Tests" [Test] [NonDebuggable] [TransactionModel(TransactionModel::AutoCommit)] - procedure MissingKeyDoesNotCommitFixture() + procedure ExpiredKeyIsRenewedBeforeHttpRequest() + var + ExpiredKey: Text[80]; + ResponseText: Text; + begin + // [SCENARIO] NavUserPassword authentication replaces an expired key before the API request + Initialize(); + + // [GIVEN] The disposable test user has a committed expired key + ExpiredKey := IdentityManagement.CreateWebServicesKey(UserSecurityId(), CurrentDateTime() - 60000); + Commit(); + + // [WHEN] The default provider sends the request + LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, GetUrl(ClientType::ODataV4), 200); + + // [THEN] NavUserPassword renews the key while ambient authentication leaves it untouched + VerifyExpiredKeyForServerMode(ExpiredKey); + Clear(ExpiredKey); + VerifyNextCall(EventCallTok); + VerifyNoRemainingCalls(); + end; + + [Test] + [NonDebuggable] + [TransactionModel(TransactionModel::AutoCommit)] + procedure AuthenticationDoesNotCommitFixture() var CurrentUser: Record User; OriginalFullName: Text[80]; begin - // [FEATURE] [AI test 1.0] // [SCENARIO] Missing-key authentication cannot commit unrelated changes to user U Initialize(); @@ -115,16 +137,15 @@ codeunit 139494 "API Test Auth Provider Tests" CurrentUser."Full Name" := 'API authentication rollback fixture'; CurrentUser.Modify(); - // [WHEN] Authentication rejects unsafe first use, or ambient authentication reaches the forced rollback + // [WHEN] Authentication is configured and the fixture transaction is rolled back asserterror InitializeRequestAndFail(); - // [THEN] The expected error leaves neither a committed fixture nor a newly created key - Assert.ExpectedError(GetExpectedFixtureError()); + // [THEN] Authentication has not committed the unrelated fixture + Assert.ExpectedError(ForcedRollbackErr); Assert.ExpectedErrorCode('Dialog'); CurrentUser.Get(UserSecurityId()); Assert.IsTrue(CurrentUser."Full Name" = OriginalFullName, 'Authentication must not commit the user fixture.'); - Assert.IsTrue(GetCurrentWebServiceKey() = '', 'Unsafe first use must not create a key.'); - VerifyFixtureRequestCalls(); + VerifyNextCall(EventCallTok); VerifyNoRemainingCalls(); end; @@ -136,7 +157,6 @@ codeunit 139494 "API Test Auth Provider Tests" TargetURL: Text; ResponseText: Text; begin - // [FEATURE] [AI test 1.0] // [SCENARIO] Default authentication uses the current user's committed key or ambient Windows credentials Initialize(); @@ -159,24 +179,6 @@ codeunit 139494 "API Test Auth Provider Tests" VerifyNoRemainingCalls(); end; - [Test] - procedure ExplicitNoneDoesNotConfigureRequest() - begin - // [FEATURE] [AI test 1.0] - // [SCENARIO] Explicit None retains ambient authentication without resolving the default provider - Initialize(); - - // [GIVEN] A Graph library instance with authentication explicitly disabled - LibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::None); - - // [WHEN] A web request is initialized - LibraryGraphMgt.InitializeWebRequestWithURL(FirstHttpWebRequestMgt, TargetURLTok); - - // [THEN] Only the final request event is raised - VerifyNextCall(EventCallTok); - VerifyNoRemainingCalls(); - end; - [Test] procedure ExtendedAuthenticationProviderRunsBeforeFinalEvent() begin @@ -224,9 +226,8 @@ codeunit 139494 "API Test Auth Provider Tests" // [SCENARIO] Authentication provider selection is scoped to a Graph library instance Initialize(); - // [GIVEN] Two Graph library instances with different explicit providers + // [GIVEN] One Graph library instance using the mock provider and another using the default LibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::Mock); - SecondLibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::None); // [WHEN] Each Graph library instance initializes a web request LibraryGraphMgt.InitializeWebRequestWithURL(FirstHttpWebRequestMgt, TargetURLTok); @@ -262,17 +263,17 @@ codeunit 139494 "API Test Auth Provider Tests" end; [Test] - procedure SelectingNoneStopsConfiguringRequests() + procedure SelectingDefaultRestoresDefaultAuthentication() begin - // [SCENARIO] Selecting None replaces the previously selected provider + // [SCENARIO] Selecting Default replaces the previously selected mock provider Initialize(); // [GIVEN] A request has used the mock provider LibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::Mock); LibraryGraphMgt.InitializeWebRequestWithURL(FirstHttpWebRequestMgt, TargetURLTok); - // [WHEN] Authentication is deselected before another request - LibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::None); + // [WHEN] Default authentication is selected before another request + LibraryGraphMgt.SetAuthenticationProvider(Enum::"API Test Authentication"::Default); LibraryGraphMgt.InitializeWebRequestWithURL(SecondHttpWebRequestMgt, TargetURLTok); // [THEN] Only the first request invokes the mock provider @@ -431,23 +432,20 @@ codeunit 139494 "API Test Auth Provider Tests" Assert.AreEqual(0DT, IdentityManagement.GetWebServiceExpiryDate(UserSecurityId()), 'A non-expiring key must stay non-expiring.'); end; - local procedure InitializeRequestAndFail() - begin - LibraryGraphMgt.InitializeWebRequestWithURL(FirstHttpWebRequestMgt, TargetURLTok); - Error(ForcedRollbackErr); - end; - - local procedure GetExpectedFixtureError(): Text + [NonDebuggable] + local procedure VerifyExpiredKeyForServerMode(ExpiredKey: Text[80]) begin - if IdentityManagement.IsUserNamePasswordAuthentication() then - exit('The API test web service key is missing and cannot be created while the caller has uncommitted writes.'); - exit(ForcedRollbackErr); + if IdentityManagement.IsUserNamePasswordAuthentication() then begin + Assert.IsTrue(ExpiredKey <> GetCurrentWebServiceKey(), 'An expired key must be replaced.'); + Assert.IsTrue(IdentityManagement.GetWebServiceExpiryDate(UserSecurityId()) > CurrentDateTime(), 'The replacement key must not be expired.'); + end else + Assert.IsTrue(ExpiredKey = GetCurrentWebServiceKey(), 'Ambient authentication must not change the key.'); end; - local procedure VerifyFixtureRequestCalls() + local procedure InitializeRequestAndFail() begin - if not IdentityManagement.IsUserNamePasswordAuthentication() then - VerifyNextCall(EventCallTok); + LibraryGraphMgt.InitializeWebRequestWithURL(FirstHttpWebRequestMgt, TargetURLTok); + Error(ForcedRollbackErr); end; local procedure VerifyNextCall(ExpectedCall: Text) diff --git a/src/Layers/W1/Tests/TestLibraries/APITestAuthentication.Enum.al b/src/Layers/W1/Tests/TestLibraries/APITestAuthentication.Enum.al index c7ad8041b73..e099890d64a 100644 --- a/src/Layers/W1/Tests/TestLibraries/APITestAuthentication.Enum.al +++ b/src/Layers/W1/Tests/TestLibraries/APITestAuthentication.Enum.al @@ -11,12 +11,11 @@ enum 131023 "API Test Authentication" implements "API Test Auth Provider" { Extensible = true; - DefaultImplementation = "API Test Auth Provider" = "No API Test Auth Provider"; + DefaultImplementation = "API Test Auth Provider" = "Microsoft Test Auth Provider"; - value(0; None) + value(0; Default) { - Caption = 'None'; - Implementation = "API Test Auth Provider" = "No API Test Auth Provider"; + Caption = 'Default'; } value(1; "Microsoft Test Environment") { diff --git a/src/Layers/W1/Tests/TestLibraries/LibraryGraphMgt.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/LibraryGraphMgt.Codeunit.al index 8dfabe2d07a..4a563126111 100644 --- a/src/Layers/W1/Tests/TestLibraries/LibraryGraphMgt.Codeunit.al +++ b/src/Layers/W1/Tests/TestLibraries/LibraryGraphMgt.Codeunit.al @@ -33,8 +33,7 @@ codeunit 130618 "Library - Graph Mgt" /// /// Sets the authentication provider used by this library instance. - /// Without an explicit selection, the Microsoft test provider is used. - /// Select None to retain only ambient credentials and the final request event. + /// Without an explicit selection, the enum's default implementation is used. /// Selecting the same provider preserves its cached state. /// /// The authentication provider to use for subsequent API test requests. @@ -195,7 +194,6 @@ codeunit 130618 "Library - Graph Mgt" local procedure GetAuthenticationProvider(): Interface "API Test Auth Provider" begin if not AuthenticationProviderResolved then begin - Authentication := Authentication::"Microsoft Test Environment"; AuthenticationProvider := Authentication; AuthenticationProviderResolved := true; end; diff --git a/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al index 579f3767941..fa8ad65fdf1 100644 --- a/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al +++ b/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al @@ -7,10 +7,9 @@ namespace Microsoft.TestLibraries.ERP; using System.Environment; using System.Security.AccessControl; -using System.TestTools.TestRunner; /// -/// Provides authentication for API tests running in Microsoft test environments. +/// Provides API test authentication using the current user's web service key. /// codeunit 131022 "Microsoft Test Auth Provider" implements "API Test Auth Provider" { @@ -18,16 +17,12 @@ codeunit 131022 "Microsoft Test Auth Provider" implements "API Test Auth Provide var KeyRetrievalFailedErr: Label 'The API test web service key could not be retrieved. Check the current user permissions.'; - ExpiredKeyErr: Label 'The current user web service key has expired. Renew it explicitly before running API tests.'; EmptyKeyErr: Label 'An empty API test web service key was returned.'; - KeyCreationInWriteTransactionErr: Label 'The API test web service key is missing and cannot be created while the caller has uncommitted writes. Initialize API authentication before fixture writes or use an existing committed fixture boundary.'; - KeyCreationFailedErr: Label 'The API test web service key could not be created in an isolated transaction. Check the current user permissions and test environment.'; /// /// Uses the current user's web service key only with NavUserPassword authentication on-premises. /// Preserves ambient authentication for Windows, SaaS, and other authentication modes. - /// Existing keys are reused without caching; missing keys are created with a 24-hour expiry. - /// First use requires a read-only caller so the isolated key transaction cannot commit fixture data. + /// Valid keys are reused; missing or expired keys are created with a 24-hour expiry. /// /// The authentication context to configure. procedure ConfigureAuthentication(var Authentication: Codeunit "API Test Auth Context") @@ -46,82 +41,18 @@ codeunit 131022 "Microsoft Test Auth Provider" implements "API Test Auth Provide [NonDebuggable] local procedure GetWebServiceKey(): SecretText var - WebServiceKey: SecretText; - ExpiryDate: DateTime; - KeyCreationSucceeded: Boolean; - begin - WebServiceKey := ReadWebServiceKey(ExpiryDate); - if WebServiceKey.IsEmpty() then begin - if Database.IsInWriteTransaction() then - Error(KeyCreationInWriteTransactionErr); - - // Isolated events commit only their subscriber transaction, never caller fixture writes. - OnCreateWebServiceKey(KeyCreationSucceeded); - if not KeyCreationSucceeded then - Error(KeyCreationFailedErr); - - // VAR changes survive subscriber rollback. Never use a credential returned by the event. - WebServiceKey := ReadWebServiceKey(ExpiryDate); - end; - if WebServiceKey.IsEmpty() then - Error(EmptyKeyErr); - if (ExpiryDate <> 0DT) and (ExpiryDate <= CurrentDateTime()) then - Error(ExpiredKeyErr); - exit(WebServiceKey); - end; - - [InternalEvent(false, true)] - local procedure OnCreateWebServiceKey(var Succeeded: Boolean) - begin - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"Test Runner - Mgt", 'OnBeforeTestMethodRun', '', false, false)] - [NonDebuggable] - local procedure PrepareTestUserWebServiceKey(var CurrentTestMethodLine: Record "Test Method Line"; CodeunitID: Integer; CodeunitName: Text[30]; FunctionName: Text[128]; FunctionTestPermissions: TestPermissions; var Skip: Boolean) - var - EnvironmentInfo: Codeunit "Environment Information"; - IdentityManagement: Codeunit "Identity Management"; - begin - if Skip or EnvironmentInfo.IsSaaSInfrastructure() then - exit; - if not IdentityManagement.IsUserNamePasswordAuthentication() then - exit; - - // OnBeforeTestRun commits its own transaction before the test's fixture transaction starts. - EnsureWebServiceKey(); - end; - - [EventSubscriber(ObjectType::Codeunit, Codeunit::"Microsoft Test Auth Provider", 'OnCreateWebServiceKey', '', false, false)] - [NonDebuggable] - [CommitBehavior(CommitBehavior::Error)] - local procedure CreateWebServiceKeyIsolated(var Succeeded: Boolean) - begin - EnsureWebServiceKey(); - Succeeded := true; - end; - - [NonDebuggable] - local procedure EnsureWebServiceKey() - var - CurrentUser: Record User; IdentityManagement: Codeunit "Identity Management"; WebServiceKey: SecretText; ExpiryDate: DateTime; begin WebServiceKey := ReadWebServiceKey(ExpiryDate); - if not WebServiceKey.IsEmpty() then - exit; - - // Serialize first use for this tenant/user; native key creation otherwise replaces an existing key. - CurrentUser.LockTable(); - CurrentUser.Get(UserSecurityId()); - WebServiceKey := ReadWebServiceKey(ExpiryDate); - if WebServiceKey.IsEmpty() then begin + if WebServiceKey.IsEmpty() or ((ExpiryDate <> 0DT) and (ExpiryDate <= CurrentDateTime())) then begin ExpiryDate := CurrentDateTime() + 24 * 60 * 60 * 1000; WebServiceKey := IdentityManagement.CreateWebServicesKey(UserSecurityId(), ExpiryDate); end; if WebServiceKey.IsEmpty() then Error(EmptyKeyErr); + exit(WebServiceKey); end; [NonDebuggable] diff --git a/src/Layers/W1/Tests/TestLibraries/NoAPITestAuthProvider.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/NoAPITestAuthProvider.Codeunit.al deleted file mode 100644 index 6b744459e86..00000000000 --- a/src/Layers/W1/Tests/TestLibraries/NoAPITestAuthProvider.Codeunit.al +++ /dev/null @@ -1,22 +0,0 @@ -// ------------------------------------------------------------------------------------------------ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// ------------------------------------------------------------------------------------------------ - -#pragma warning disable AA0247 - -/// -/// Leaves API test requests configured with the library's default authentication behavior (the default credentials of the Business Central service). -/// -codeunit 131024 "No API Test Auth Provider" implements "API Test Auth Provider" -{ - Access = Internal; - - /// - /// Leaves the authentication context unchanged. - /// - /// The authentication context to configure. - procedure ConfigureAuthentication(var Authentication: Codeunit "API Test Auth Context") - begin - end; -} diff --git a/src/Layers/W1/Tests/TestLibraries/app.json b/src/Layers/W1/Tests/TestLibraries/app.json index de739aae611..c7c2a8db600 100644 --- a/src/Layers/W1/Tests/TestLibraries/app.json +++ b/src/Layers/W1/Tests/TestLibraries/app.json @@ -7,12 +7,6 @@ "url": "https://go.microsoft.com/fwlink/?LinkId=724011", "propagateDependencies": true, "dependencies": [ - { - "id": "23de40a6-dfe8-4f80-80db-d70f83ce8caf", - "name": "Test Runner", - "publisher": "Microsoft", - "version": "30.0.0.0" - }, { "id": "9856ae4f-d1a7-46ef-89bb-6ef056398228", "name": "System Application Test Library", From 1df14eadd41297582006face6a320666ecfeb443 Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Fri, 9 Oct 2026 15:01:51 +0200 Subject: [PATCH 3/9] Fix AA0005 and AL0789 compile errors in API test fixes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91 --- .../W1/APIV1/test/src/APIV1CustomerPaymentsE2E.Codeunit.al | 3 +-- src/Apps/W1/APIV2/test/src/APIV2ApplyVendorEntE2E.Codeunit.al | 3 +-- .../W1/APIV2/test/src/APIV2CustomerPaymentsE2E.Codeunit.al | 3 +-- src/Apps/W1/APIV2/test/src/APIV2VendorPaymentsE2E.Codeunit.al | 3 +-- src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al | 3 --- 5 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Apps/W1/APIV1/test/src/APIV1CustomerPaymentsE2E.Codeunit.al b/src/Apps/W1/APIV1/test/src/APIV1CustomerPaymentsE2E.Codeunit.al index 79d8b3eb1f6..643570da46b 100644 --- a/src/Apps/W1/APIV1/test/src/APIV1CustomerPaymentsE2E.Codeunit.al +++ b/src/Apps/W1/APIV1/test/src/APIV1CustomerPaymentsE2E.Codeunit.al @@ -773,9 +773,8 @@ codeunit 139743 "APIV1 - Customer Payments E2E" LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryTestInitialize.OnTestInitialize(Codeunit::"APIV1 - Customer Payments E2E"); - if not isInitialized then begin + if not isInitialized then isInitialized := true; - end; LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"APIV1 - Customer Payments E2E"); end; diff --git a/src/Apps/W1/APIV2/test/src/APIV2ApplyVendorEntE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2ApplyVendorEntE2E.Codeunit.al index 03805dfef6c..443610ddb83 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2ApplyVendorEntE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2ApplyVendorEntE2E.Codeunit.al @@ -175,9 +175,8 @@ codeunit 139867 "APIV2 - Apply Vendor Ent. E2E" LibraryTestInitialize.OnTestInitialize(Codeunit::"APIV2 - Apply Vendor Ent. E2E"); - if not isInitialized then begin + if not isInitialized then isInitialized := true; - end; LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"APIV2 - Apply Vendor Ent. E2E"); end; diff --git a/src/Apps/W1/APIV2/test/src/APIV2CustomerPaymentsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2CustomerPaymentsE2E.Codeunit.al index 1083e5c9a25..5939f7834eb 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2CustomerPaymentsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2CustomerPaymentsE2E.Codeunit.al @@ -773,9 +773,8 @@ codeunit 139840 "APIV2 - Customer Payments E2E" LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryTestInitialize.OnTestInitialize(Codeunit::"APIV2 - Customer Payments E2E"); - if not isInitialized then begin + if not isInitialized then isInitialized := true; - end; LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"APIV2 - Customer Payments E2E"); end; diff --git a/src/Apps/W1/APIV2/test/src/APIV2VendorPaymentsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2VendorPaymentsE2E.Codeunit.al index a5829f148d9..ac23a7d45c1 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2VendorPaymentsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2VendorPaymentsE2E.Codeunit.al @@ -888,9 +888,8 @@ codeunit 139843 "APIV2 - Vendor Payments E2E" LibraryGraphMgt.SetLicenseSafeWorkDate(); LibraryTestInitialize.OnTestInitialize(Codeunit::"APIV2 - Vendor Payments E2E"); - if not isInitialized then begin + if not isInitialized then isInitialized := true; - end; LibraryTestInitialize.OnAfterTestSuiteInitialize(Codeunit::"APIV2 - Vendor Payments E2E"); end; diff --git a/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al b/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al index d1c985b5897..880b22d268b 100644 --- a/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al +++ b/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al @@ -5,9 +5,6 @@ #pragma warning disable AA0247 -using System.Environment; -using System.Security.AccessControl; - codeunit 139494 "API Test Auth Provider Tests" { EventSubscriberInstance = Manual; From 62f9540288de65fd661ba1ae2603a46856bb3063 Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Fri, 9 Oct 2026 15:30:27 +0200 Subject: [PATCH 4/9] Trim API web-key PR to required changes - Remove unused 'Microsoft Test Environment' enum value; default implementation covers it - Restore 12 whitespace-only test files and LOCAL_DEV_ENV.md from main - CU 139494: rename first-use test, drop redundant server-mode and no-commit tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91 --- LOCAL_DEV_ENV.md | 33 --------- .../ERMGeneralJournalUT.Codeunit.al | 1 + .../Prepayment/ERMPrepaymentII.Codeunit.al | 1 + .../ERMGeneralJournalUT.Codeunit.al | 1 + .../ERMGeneralJournalUT.Codeunit.al | 1 + .../ERMGeneralJournalUT.Codeunit.al | 1 + .../ERMGeneralJournalUT.Codeunit.al | 1 + .../Prepayment/ERMPrepaymentII.Codeunit.al | 1 + .../ERMGeneralJournalUT.Codeunit.al | 1 + .../IRS1099CodeEntityE2ETest.Codeunit.al | 1 + .../WFWHSubscriptionE2ETests.Codeunit.al | 2 +- .../Integration/WebhookLogsE2E.Codeunit.al | 1 + .../Misc/APITestAuthProviderTests.Codeunit.al | 70 +------------------ .../Prepayment/ERMPrepaymentII.Codeunit.al | 2 + .../APITestAuthentication.Enum.al | 5 -- 15 files changed, 14 insertions(+), 108 deletions(-) diff --git a/LOCAL_DEV_ENV.md b/LOCAL_DEV_ENV.md index 55e0b00502a..cb724a60b93 100644 --- a/LOCAL_DEV_ENV.md +++ b/LOCAL_DEV_ENV.md @@ -41,39 +41,6 @@ Running the above will * Set up launch.jsons and settings.jsons in your VSCode * Compile and publish all AL apps that match `.\src\System Application\` -## API test authentication - -`Library - Graph Mgt` uses the Microsoft test authentication provider by default. -API tests do not need a `SetAuthenticationProvider` call, a password file, or a -Key Vault password lookup. Container and test-session credentials are still -required to provision and connect to the NST; they are not handed to API requests. - -On-premises **NavUserPassword** requests use the current user's web service key. -The provider reads the key and expiry for each request, reuses a valid key -(including one without an expiry), and creates a key with a 24-hour expiry when -the key is missing or expired. Credentials are not cached or logged. - -There are no authentication event subscribers, test-runner dependencies, or -pipeline key-provisioning steps. The provider does not call `Commit()`. -`Identity Management` may create the key in the caller's existing transaction; -the independent HTTP session requires committed credentials, just as it requires -committed fixture data. First-use visibility at the test's transaction boundary -must therefore be verified on the target server. Concurrent creation by separate -sessions for the same tenant/user is not serialized by this provider. - -Windows, SaaS, and other authentication modes retain ambient authentication. -`API Test Authentication` uses the Microsoft provider as its -`DefaultImplementation`; value zero is `Default`. The explicit -`Microsoft Test Environment` value retains ordinal one. The previous `None` -value and no-op provider are removed. Custom enum providers and -`SetAuthenticationProvider` remain supported, and the final -`OnAfterInitializeWebRequestWithURL` event still runs after the provider. - -API fixture initializers reapply the existing test-license-compatible work date -(November 15 of the current year) before creating date-sensitive data, including -after an initialization guard has previously been set. This controls fixture -dates, not license enforcement or the authentication key's real-time expiry. - ## GDL development (layers and views) Anything that ships in multiple localizations (the **Base Application** and the application layers) lives under `src/Layers`, organized by country/region. Each country's app is composed by overlapping multiple **layers** in order: a `W1` ("worldwide") base, optional regional layers, and the country layer. For example, the `US` app is composed of `W1` + `NA` + `US`, where each layer either introduces new objects or replaces objects from a base layer. diff --git a/src/Layers/APAC/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/APAC/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index c067400bcea..707e6a229cd 100644 --- a/src/Layers/APAC/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/APAC/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7574,3 +7574,4 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } + diff --git a/src/Layers/APAC/Tests/Prepayment/ERMPrepaymentII.Codeunit.al b/src/Layers/APAC/Tests/Prepayment/ERMPrepaymentII.Codeunit.al index 514e712534e..be7ad2bb239 100644 --- a/src/Layers/APAC/Tests/Prepayment/ERMPrepaymentII.Codeunit.al +++ b/src/Layers/APAC/Tests/Prepayment/ERMPrepaymentII.Codeunit.al @@ -2694,6 +2694,7 @@ codeunit 134101 "ERM Prepayment II" GenJournalLine.Modify(true); LibraryERM.PostGeneralJnlLine(GenJournalLine); end; + local procedure SelectGenJournalBatch(var GenJournalBatch: Record "Gen. Journal Batch") begin // Select General Journal Batch and clear General Journal Lines to make sure that no line exist before creating diff --git a/src/Layers/CH/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/CH/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index b3452ad5d49..c81c9d60800 100644 --- a/src/Layers/CH/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/CH/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7372,3 +7372,4 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } + diff --git a/src/Layers/CZ/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/CZ/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index 667c49a4ce0..4ed0a80f174 100644 --- a/src/Layers/CZ/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/CZ/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7578,3 +7578,4 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } + diff --git a/src/Layers/ES/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/ES/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index e0c84c365c5..0f00c3467cc 100644 --- a/src/Layers/ES/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/ES/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7607,3 +7607,4 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } + diff --git a/src/Layers/IT/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/IT/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index f8af226c9fe..0044783f068 100644 --- a/src/Layers/IT/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/IT/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7573,3 +7573,4 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } + diff --git a/src/Layers/NA/Tests/Prepayment/ERMPrepaymentII.Codeunit.al b/src/Layers/NA/Tests/Prepayment/ERMPrepaymentII.Codeunit.al index 6cc9605ec93..e514b0407b0 100644 --- a/src/Layers/NA/Tests/Prepayment/ERMPrepaymentII.Codeunit.al +++ b/src/Layers/NA/Tests/Prepayment/ERMPrepaymentII.Codeunit.al @@ -2632,6 +2632,7 @@ codeunit 134101 "ERM Prepayment II" GenJournalLine.Modify(true); LibraryERM.PostGeneralJnlLine(GenJournalLine); end; + local procedure SelectGenJournalBatch(var GenJournalBatch: Record "Gen. Journal Batch") begin // Select General Journal Batch and clear General Journal Lines to make sure that no line exist before creating diff --git a/src/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al b/src/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al index 199d8aac30a..0bffda864c6 100644 --- a/src/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al +++ b/src/Layers/W1/Tests/General Journal/ERMGeneralJournalUT.Codeunit.al @@ -7573,3 +7573,4 @@ codeunit 134920 "ERM General Journal UT" IsHandled := true; end; } + diff --git a/src/Layers/W1/Tests/Graph/IRS1099CodeEntityE2ETest.Codeunit.al b/src/Layers/W1/Tests/Graph/IRS1099CodeEntityE2ETest.Codeunit.al index b2ebf6edd01..80c99fa6f1c 100644 --- a/src/Layers/W1/Tests/Graph/IRS1099CodeEntityE2ETest.Codeunit.al +++ b/src/Layers/W1/Tests/Graph/IRS1099CodeEntityE2ETest.Codeunit.al @@ -41,3 +41,4 @@ codeunit 135519 "IRS 1099 Code Entity E2E Test" IsInitialized := true; end; } + diff --git a/src/Layers/W1/Tests/Graph/WFWHSubscriptionE2ETests.Codeunit.al b/src/Layers/W1/Tests/Graph/WFWHSubscriptionE2ETests.Codeunit.al index 9a15f918f0d..f5b8e0f9859 100644 --- a/src/Layers/W1/Tests/Graph/WFWHSubscriptionE2ETests.Codeunit.al +++ b/src/Layers/W1/Tests/Graph/WFWHSubscriptionE2ETests.Codeunit.al @@ -54,7 +54,6 @@ codeunit 135528 "WFWH Subscription E2E Tests" if IsInitialized then exit; - IsInitialized := true; Commit(); @@ -1455,3 +1454,4 @@ codeunit 135528 "WFWH Subscription E2E Tests" exit(String); end; } + diff --git a/src/Layers/W1/Tests/Integration/WebhookLogsE2E.Codeunit.al b/src/Layers/W1/Tests/Integration/WebhookLogsE2E.Codeunit.al index 861ad23e8d9..a5aad9c9707 100644 --- a/src/Layers/W1/Tests/Integration/WebhookLogsE2E.Codeunit.al +++ b/src/Layers/W1/Tests/Integration/WebhookLogsE2E.Codeunit.al @@ -153,3 +153,4 @@ codeunit 135547 "Webhook Logs E2E" ActivityLog.DeleteAll(); end; } + diff --git a/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al b/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al index 05627bdb452..176103cdbcd 100644 --- a/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al +++ b/src/Layers/W1/Tests/Misc/APITestAuthProviderTests.Codeunit.al @@ -33,12 +33,11 @@ codeunit 139494 "API Test Auth Provider Tests" ProviderCallTok: Label 'Provider|%1', Locked = true, Comment = '%1 - Provider invocation number'; EventCallTok: Label 'Event', Locked = true; UnexpectedCallErr: Label 'Unexpected authentication call.'; - ForcedRollbackErr: Label 'Roll back the API authentication fixture.'; [Test] [NonDebuggable] [TransactionModel(TransactionModel::AutoCommit)] - procedure MissingKeyIsCommittedBeforeHttpRequest() + procedure MissingKeyIsCreatedForRequest() var TargetURL: Text; ResponseText: Text; @@ -115,67 +114,6 @@ codeunit 139494 "API Test Auth Provider Tests" VerifyNoRemainingCalls(); end; - [Test] - [NonDebuggable] - [TransactionModel(TransactionModel::AutoCommit)] - procedure AuthenticationDoesNotCommitFixture() - var - CurrentUser: Record User; - OriginalFullName: Text[80]; - begin - // [SCENARIO] Missing-key authentication cannot commit unrelated changes to user U - Initialize(); - - // [GIVEN] User U has no key and an uncommitted fixture change - IdentityManagement.ClearWebServicesKey(UserSecurityId()); - Commit(); - CurrentUser.Get(UserSecurityId()); - OriginalFullName := CurrentUser."Full Name"; - CurrentUser."Full Name" := 'API authentication rollback fixture'; - CurrentUser.Modify(); - - // [WHEN] Authentication is configured and the fixture transaction is rolled back - asserterror InitializeRequestAndFail(); - - // [THEN] Authentication has not committed the unrelated fixture - Assert.ExpectedError(ForcedRollbackErr); - Assert.ExpectedErrorCode('Dialog'); - CurrentUser.Get(UserSecurityId()); - Assert.IsTrue(CurrentUser."Full Name" = OriginalFullName, 'Authentication must not commit the user fixture.'); - VerifyNextCall(EventCallTok); - VerifyNoRemainingCalls(); - end; - - [Test] - [TransactionModel(TransactionModel::None)] - procedure DefaultAuthenticationRespectsServerAuthMode() - var - EnvironmentInfo: Codeunit "Environment Information"; - TargetURL: Text; - ResponseText: Text; - begin - // [SCENARIO] Default authentication uses the current user's committed key or ambient Windows credentials - Initialize(); - - // [GIVEN] An OnPrem service and a read-only test method with no fixture transaction to commit - Assert.IsFalse(EnvironmentInfo.IsSaaSInfrastructure(), 'This HTTP scenario requires an OnPrem test environment.'); - TargetURL := GetUrl(ClientType::ODataV4); - - // [WHEN] The default provider sends a request without explicit provider selection - LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, TargetURL, 200); - - // [THEN] Authentication completes before the independent HTTP session reads the key - VerifyNextCall(EventCallTok); - - // [WHEN] A fresh library instance sends another request - Clear(LibraryGraphMgt); - LibraryGraphMgt.GetFromWebServiceAndCheckResponseCode(ResponseText, TargetURL, 200); - - // [THEN] Authentication does not depend on an instance-local credential cache - VerifyNextCall(EventCallTok); - VerifyNoRemainingCalls(); - end; - [Test] procedure ExtendedAuthenticationProviderRunsBeforeFinalEvent() begin @@ -439,12 +377,6 @@ codeunit 139494 "API Test Auth Provider Tests" Assert.IsTrue(ExpiredKey = GetCurrentWebServiceKey(), 'Ambient authentication must not change the key.'); end; - local procedure InitializeRequestAndFail() - begin - LibraryGraphMgt.InitializeWebRequestWithURL(FirstHttpRequestMessage, TargetURLTok); - Error(ForcedRollbackErr); - end; - local procedure VerifyNextCall(ExpectedCall: Text) begin APITestAuthProviderTests.VerifyRecordedCall(ExpectedCall); diff --git a/src/Layers/W1/Tests/Prepayment/ERMPrepaymentII.Codeunit.al b/src/Layers/W1/Tests/Prepayment/ERMPrepaymentII.Codeunit.al index ac9aa24db4e..27e8b022b74 100644 --- a/src/Layers/W1/Tests/Prepayment/ERMPrepaymentII.Codeunit.al +++ b/src/Layers/W1/Tests/Prepayment/ERMPrepaymentII.Codeunit.al @@ -2575,6 +2575,7 @@ codeunit 134101 "ERM Prepayment II" GenJournalLine.Modify(true); LibraryERM.PostGeneralJnlLine(GenJournalLine); end; + local procedure SelectGenJournalBatch(var GenJournalBatch: Record "Gen. Journal Batch") begin // Select General Journal Batch and clear General Journal Lines to make sure that no line exist before creating @@ -3144,3 +3145,4 @@ codeunit 134101 "ERM Prepayment II" PurchaseHeader.TestField(Status, ExpectedStatus); end; } + diff --git a/src/Layers/W1/Tests/TestLibraries/APITestAuthentication.Enum.al b/src/Layers/W1/Tests/TestLibraries/APITestAuthentication.Enum.al index e099890d64a..dac29b63510 100644 --- a/src/Layers/W1/Tests/TestLibraries/APITestAuthentication.Enum.al +++ b/src/Layers/W1/Tests/TestLibraries/APITestAuthentication.Enum.al @@ -17,9 +17,4 @@ enum 131023 "API Test Authentication" implements "API Test Auth Provider" { Caption = 'Default'; } - value(1; "Microsoft Test Environment") - { - Caption = 'Microsoft Test Environment'; - Implementation = "API Test Auth Provider" = "Microsoft Test Auth Provider"; - } } From 7815634073315d8e2ab65e2f8ca3e0b5d802f4e1 Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Fri, 9 Oct 2026 18:40:47 +0200 Subject: [PATCH 5/9] Send API test Basic auth header as plain text over local HTTP After #12323 the API test library uses native HttpClient. The platform refuses to send SecretText headers to non-HTTPS endpoints, so every authenticated request to the local http:// test server failed before sending ('connecting endpoint violates security requirements', status 0). Keep credentials as SecretText and unwrap only the final header value in a NonDebuggable procedure, matching the previous Http Web Request Mgt. behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91 --- .../W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Layers/W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al index a286b51b00b..94f7dfde959 100644 --- a/src/Layers/W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al +++ b/src/Layers/W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al @@ -30,7 +30,11 @@ codeunit 131023 "API Test Auth Context" /// /// Applies the configured authentication to the API test request. /// + /// + /// The test server is reached over plain HTTP, and the platform refuses to send secret headers to non-HTTPS endpoints. + /// /// The request to authenticate. + [NonDebuggable] internal procedure Apply(var HttpRequestMessage: HttpRequestMessage) var Base64Convert: Codeunit "Base64 Convert"; @@ -42,6 +46,6 @@ codeunit 131023 "API Test Auth Context" HttpRequestMessage.GetHeaders(RequestHeaders); if RequestHeaders.Contains('Authorization') or RequestHeaders.ContainsSecret('Authorization') then RequestHeaders.Remove('Authorization'); - RequestHeaders.Add('Authorization', SecretStrSubstNo('Basic %1', Base64Convert.ToBase64(SecretStrSubstNo('%1:%2', BasicUserName, BasicPassword)))); + RequestHeaders.Add('Authorization', SecretStrSubstNo('Basic %1', Base64Convert.ToBase64(SecretStrSubstNo('%1:%2', BasicUserName, BasicPassword))).Unwrap()); end; } From 83b3550a1b97b0daf16c5c28d808fa5f19f39a2e Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Fri, 9 Oct 2026 19:25:37 +0200 Subject: [PATCH 6/9] Disable test isolation for purchase pdfDocument API tests TestExpandPdfDocument in Bl. Purch. Orders, Purch. Quotes and Purch. Ret. Shpts. E2E got 409 Conflict (record in Purchase Header / Return Shipment Header is being updated): under codeunit isolation the fixture lock is still held when the HTTP session's PDF rendering updates the header. Match APIV2 - PDF Document E2E (RequiredTestIsolation = Disabled) so fixture Commit() is effective. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91 --- src/Apps/W1/APIV2/test/src/APIV2BlPurchOrdersE2E.Codeunit.al | 1 + src/Apps/W1/APIV2/test/src/APIV2PurchQuotesE2E.Codeunit.al | 1 + src/Apps/W1/APIV2/test/src/APIV2PurchRetShptsE2E.Codeunit.al | 1 + 3 files changed, 3 insertions(+) diff --git a/src/Apps/W1/APIV2/test/src/APIV2BlPurchOrdersE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2BlPurchOrdersE2E.Codeunit.al index 9cae2a48f2e..00e0c4ae992 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2BlPurchOrdersE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2BlPurchOrdersE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139908 "APIV2 - Bl. Purch. Orders E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchQuotesE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchQuotesE2E.Codeunit.al index 8a6c8f51483..abb43efdf83 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchQuotesE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchQuotesE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139922 "APIV2 - Purch. Quotes E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; diff --git a/src/Apps/W1/APIV2/test/src/APIV2PurchRetShptsE2E.Codeunit.al b/src/Apps/W1/APIV2/test/src/APIV2PurchRetShptsE2E.Codeunit.al index a3c590533b9..b948b7262a0 100644 --- a/src/Apps/W1/APIV2/test/src/APIV2PurchRetShptsE2E.Codeunit.al +++ b/src/Apps/W1/APIV2/test/src/APIV2PurchRetShptsE2E.Codeunit.al @@ -3,6 +3,7 @@ codeunit 139928 "APIV2 - Purch. Ret. Shpts. E2E" // version Test,ERM,W1,All Subtype = Test; + RequiredTestIsolation = Disabled; TestType = Uncategorized; TestPermissions = Disabled; From 21006fcaf83588cceb2ec83515d1377b678da7a6 Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Fri, 9 Oct 2026 21:31:31 +0200 Subject: [PATCH 7/9] Disable anti-SSRF in BCApps test containers for API tests Since #12323 the API test library uses native AL HttpClient, whose anti-SSRF validation blocks calls to local/private addresses. Every API test request to the container's own web services failed with 'connecting endpoint violates security requirements' (status 0). Set NavHttpClientAntiSSRFEnabled=false in the disposable test container, matching NAV Eng/Core/Scripts/RunALTests.ps1. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91 --- build/scripts/NewBcContainer.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/scripts/NewBcContainer.ps1 b/build/scripts/NewBcContainer.ps1 index d6e98d84794..674d6f1faa5 100644 --- a/build/scripts/NewBcContainer.ps1 +++ b/build/scripts/NewBcContainer.ps1 @@ -26,6 +26,8 @@ New-BcContainer @parameters Set-BcContainerServerConfiguration -containerName $parameters.ContainerName -keyName "EnforceUserPathForAlFileOperations" -keyValue "false" Set-BcContainerServerConfiguration -containerName $parameters.ContainerName -keyName "UsePermissionSetsFromExtensions" -keyValue "true" +# API tests call the container's own web services through AL HttpClient, which anti-SSRF blocks for local addresses (same as NAV RunALTests.ps1). +Set-BcContainerServerConfiguration -containerName $parameters.ContainerName -keyName "NavHttpClientAntiSSRFEnabled" -keyValue "false" Restart-BcContainer -containerName $parameters.ContainerName $installedApps = Get-BcContainerAppInfo -containerName $parameters.ContainerName -tenantSpecificProperties -sort DependenciesLast From 79e13b89460505e1f03482dc754c4f9d7cc67e98 Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Fri, 9 Oct 2026 21:31:32 +0200 Subject: [PATCH 8/9] Revert unwrapped Basic auth header The security block was anti-SSRF, not SecretText headers; keep API Test Auth Context identical to main. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91 --- .../W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Layers/W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al index 94f7dfde959..a286b51b00b 100644 --- a/src/Layers/W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al +++ b/src/Layers/W1/Tests/TestLibraries/APITestAuthContext.Codeunit.al @@ -30,11 +30,7 @@ codeunit 131023 "API Test Auth Context" /// /// Applies the configured authentication to the API test request. /// - /// - /// The test server is reached over plain HTTP, and the platform refuses to send secret headers to non-HTTPS endpoints. - /// /// The request to authenticate. - [NonDebuggable] internal procedure Apply(var HttpRequestMessage: HttpRequestMessage) var Base64Convert: Codeunit "Base64 Convert"; @@ -46,6 +42,6 @@ codeunit 131023 "API Test Auth Context" HttpRequestMessage.GetHeaders(RequestHeaders); if RequestHeaders.Contains('Authorization') or RequestHeaders.ContainsSecret('Authorization') then RequestHeaders.Remove('Authorization'); - RequestHeaders.Add('Authorization', SecretStrSubstNo('Basic %1', Base64Convert.ToBase64(SecretStrSubstNo('%1:%2', BasicUserName, BasicPassword))).Unwrap()); + RequestHeaders.Add('Authorization', SecretStrSubstNo('Basic %1', Base64Convert.ToBase64(SecretStrSubstNo('%1:%2', BasicUserName, BasicPassword)))); end; } From 95f7c6f1b40cb7dc16e5a1ba40dc154e11358cba Mon Sep 17 00:00:00 2001 From: Prangshuman Das Date: Sun, 11 Oct 2026 21:15:42 +0200 Subject: [PATCH 9/9] Commit newly created API test web service key before the request The API request is authenticated by a separate server session that only sees committed data, so a key created in the caller's open transaction caused 401 (unknown user) on the first request after creation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3952f078-a881-4da8-ad96-13b727e48a91 --- .../Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al b/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al index fa8ad65fdf1..9a011d2ad80 100644 --- a/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al +++ b/src/Layers/W1/Tests/TestLibraries/MicrosoftTestAuthProvider.Codeunit.al @@ -49,6 +49,8 @@ codeunit 131022 "Microsoft Test Auth Provider" implements "API Test Auth Provide if WebServiceKey.IsEmpty() or ((ExpiryDate <> 0DT) and (ExpiryDate <= CurrentDateTime())) then begin ExpiryDate := CurrentDateTime() + 24 * 60 * 60 * 1000; WebServiceKey := IdentityManagement.CreateWebServicesKey(UserSecurityId(), ExpiryDate); + // The request is authenticated by a separate server session, which only sees committed data. + Commit(); end; if WebServiceKey.IsEmpty() then Error(EmptyKeyErr);