Skip to content

Bug 638446: Refactor: Split SubcSubcontractingTest into 3 focused codeunits#8225

Open
ChethanT wants to merge 6 commits into
mainfrom
refactor/Subcontracting/SplitTestCodeunit
Open

Bug 638446: Refactor: Split SubcSubcontractingTest into 3 focused codeunits#8225
ChethanT wants to merge 6 commits into
mainfrom
refactor/Subcontracting/SplitTestCodeunit

Conversation

@ChethanT

@ChethanT ChethanT commented May 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Splits the monolithic test codeunit \Subc. Subcontracting Test\ (139989, 42 tests, 3562 lines) into three focused codeunits for better maintainability:

New Codeunits

Codeunit ID Tests Focus
Subc. Transfer Order Test 139990 13 Transfer order creation, location handling, returns, reservations, bin codes
Subc. Purchase Order Test 139991 12 PO creation from routing, posting groups, calculate subcontracts, descriptions
Subc. Subcontracting Test 139989 18 Remaining: setup, factbox, planning, item charge, copy document, dispatching

Motivation

The original codeunit was growing unbounded due to its generic name. This split groups tests by feature area while avoiding over-fragmentation.

Each new codeunit is self-contained with required handlers and helper procedures.

Fixes AB#638446

@github-actions github-actions Bot added the AL: Apps (W1) Add-on apps for W1 label May 20, 2026
Split the monolithic test codeunit (139989, 45 tests, 3816 lines) into
three focused codeunits:

- Subc. Transfer Order Test (139993): 14 tests covering transfer order
  creation, location handling, returns, reservations, bin codes, direct transfer
- Subc. Purchase Order Test (139994): 15 tests covering PO creation from
  routing, posting groups, calculate subcontracts, descriptions, pricing
- Subc. Subcontracting Test (139989): 16 remaining misc tests (setup,
  factbox, planning, copy document, dispatching, component supply method)

Each new codeunit is self-contained with required handlers and helpers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ChethanT ChethanT force-pushed the refactor/Subcontracting/SplitTestCodeunit branch from 8f263c8 to 646987d Compare June 11, 2026 10:36
@ChethanT ChethanT marked this pull request as ready for review June 12, 2026 08:55
@ChethanT ChethanT requested a review from a team as a code owner June 12, 2026 08:55
@ChethanT ChethanT changed the title refactor: Split SubcSubcontractingTest into 3 focused codeunits Bug 638446: Refactor: Split SubcSubcontractingTest into 3 focused codeunits Jun 12, 2026
@github-actions github-actions Bot added this to the Version 29.0 milestone Jun 12, 2026
var
ReservationEntry: Record "Reservation Entry";
begin
ReservationEntry.DeleteAll();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Performance} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Unfiltered DeleteAll wipes all Reservation Entries

ReservationEntry.DeleteAll() is called without any SetRange filter inside MockReservationEntryOnTransferLine, which deletes every reservation entry in the database, not just those belonging to the transfer line under test.

Recommendation:

  • Add SetRange filters scoped to the transfer line before calling DeleteAll so only the relevant reservation entries are removed.
Suggested change
ReservationEntry.DeleteAll();
ReservationEntry.SetRange("Source Type", Database::"Transfer Line");
ReservationEntry.SetRange("Source ID", TransferLine."Document No.");
ReservationEntry.SetRange("Source Ref. No.", TransferLine."Line No.");
ReservationEntry.DeleteAll();

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order);
PurchaseLine.SetRange("Prod. Order No.", ProductionOrder."No.");
PurchaseLine.SetRange("Work Center No.", WorkCenter[2]."No.");
Assert.AreEqual(false, PurchaseLine.IsEmpty(), '');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Assert.AreEqual(false, ...) instead of Assert.IsFalse

Using Assert.AreEqual(false, PurchaseLine.IsEmpty(), '') is semantically correct but harder to read and produces a less descriptive failure message than the idiomatic form.

Recommendation:

  • Replace with Assert.IsFalse and add a meaningful message string.
Suggested change
Assert.AreEqual(false, PurchaseLine.IsEmpty(), '');
Assert.IsFalse(PurchaseLine.IsEmpty(), 'Purchase Line should exist for the production order.');

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

PurchaseLine.SetRange("Document Type", PurchaseLine."Document Type"::Order);
PurchaseLine.SetRange(Type, PurchaseLine.Type::Item);
PurchaseLine.SetRange("No.", ProductionBOMLine."No.");
Assert.AreEqual(false, PurchaseLine.IsEmpty(), '');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Assert.AreEqual(false, ...) instead of Assert.IsFalse

Using Assert.AreEqual(false, PurchaseLine.IsEmpty(), '') with an empty message makes failures impossible to diagnose from the test output alone.

Recommendation:

  • Replace with Assert.IsFalse and supply a meaningful failure message.
Suggested change
Assert.AreEqual(false, PurchaseLine.IsEmpty(), '');
Assert.IsFalse(PurchaseLine.IsEmpty(), 'Purchase Line should exist for the production BOM component.');

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

Vendor."Subc. Location Code" := Location.Code;
LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);
Vendor."Location Code" := Location.Code;
Vendor.Modify();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Vendor.Modify() without trigger in test setup

Vendor.Modify() (without true) is used after directly assigning "Subc. Location Code" and "Location Code", skipping any OnModify event subscribers that synchronize related records.

Recommendation:

  • Use Vendor.Modify(true) to ensure all trigger-driven side effects are applied.
Suggested change
Vendor.Modify();
Vendor.Modify(true);

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

// [GIVEN] Create Subcontracting Purchase Order from Prod. Order Routing
WorkCenter2 := WorkCenter[2];
WorkCenter2."Subcontractor No." := Vendor."No.";
WorkCenter2.Modify();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

WorkCenter2.Modify() without trigger skips OnModify

WorkCenter2."Subcontractor No." := Vendor."No." followed by WorkCenter2.Modify() (without true) does not fire OnModify on the Work Center, potentially missing subcontracting price or linked record updates.

Recommendation:

  • Use WorkCenter2.Modify(true) so OnModify event subscribers execute.
Suggested change
WorkCenter2.Modify();
WorkCenter2.Modify(true);

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

ProdOrderComp.FindFirst();
ExpectedDescription2 := 'TestDescription2_Comp';
ProdOrderComp."Description 2" := ExpectedDescription2;
ProdOrderComp.Modify();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Direct field set and Modify() bypasses OnModify triggers

ProdOrderComp."Description 2" := ... followed by ProdOrderComp.Modify() (without true) writes to the database skipping OnModify, which may miss trigger-driven field propagation relevant to the test scenario.

Recommendation:

  • Use ProdOrderComp.Modify(true) so that any OnModify logic runs consistently.
Suggested change
ProdOrderComp.Modify();
ProdOrderComp.Modify(true);

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

Vendor.Modify();
end;

procedure CreateWorkCenter(var WorkCenterNo: Code[20]; ShopCalendarCode: Code[10]; FlushingMethod: Enum "Flushing Method"; Subcontract: Boolean;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Public helper procedure should be local

procedure CreateWorkCenter(...) is declared without local, making it part of the codeunit's public surface. Test helper procedures should be local to prevent unintended external callers and to clearly express encapsulation intent.

Recommendation:

  • Add the local keyword to this procedure declaration.
Suggested change
procedure CreateWorkCenter(var WorkCenterNo: Code[20]; ShopCalendarCode: Code[10]; FlushingMethod: Enum "Flushing Method"; Subcontract: Boolean;
local procedure CreateWorkCenter(var WorkCenterNo: Code[20]; ShopCalendarCode: Code[10]; FlushingMethod: Enum "Flushing Method"; Subcontract: Boolean;

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why


if Subcontract then begin
LibraryERM.FindVATPostingSetup(VATPostingSetup, VATPostingSetup."VAT Calculation Type"::"Normal VAT");
GenProductPostingGroup.FindFirst();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

FindFirst without filter on GenProductPostingGroup

GenProductPostingGroup.FindFirst() is called inside CreateWorkCenter with no SetRange filter, making the selected posting group non-deterministic and potentially causing tests to silently share or pollute posting group setup across test runs.

Recommendation:

  • Use a specific filter or LibraryERM.FindGenProductPostingGroup to select a predictable posting group, or create a dedicated one for the test.
Suggested change
GenProductPostingGroup.FindFirst();
LibraryERM.FindGenProductPostingGroup(GenProductPostingGroup);

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

ManufacturingSetup.Modify();
end;

procedure SelectRequisitionTemplateName(): Code[10]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Public helper procedure should be local

procedure SelectRequisitionTemplateName() has no local qualifier in a test codeunit, exposing an internal helper as part of the public API without any test or handler purpose.

Recommendation:

  • Declare it as local procedure SelectRequisitionTemplateName().
Suggested change
procedure SelectRequisitionTemplateName(): Code[10]
local procedure SelectRequisitionTemplateName(): Code[10]

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

SubcontractingMgmtLibrary.CreateAndRefreshProductionOrder(
ProductionOrder2, "Production Order Status"::Released, ProductionOrder2."Source Type"::Item, Item."No.", LibraryRandom.RandInt(10) + 5);
SetAllProdOrderTransferComponentLocations(ProductionOrder2."No.", ProductionLocation.Code);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Modify() without trigger after Validate in test setup

ProdOrderComp.Validate("Component Supply Method", ...) updates the record in memory, then ProdOrderComp.Modify() (without true) persists it without running the OnModify trigger. If the OnModify trigger performs location or state updates, those are silently skipped.

Recommendation:

  • Use ProdOrderComp.Modify(true) to also run OnModify triggers, ensuring consistent state.
Suggested change
SetAllProdOrderTransferComponentLocations(ProductionOrder2."No.", ProductionLocation.Code);
ProdOrderComp.Modify(true);

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

ProductionOrder: Record "Production Order";
PurchaseHeader: Record "Purchase Header";
PurchaseLine: Record "Purchase Line";
TransferHeader: Record "Transfer Header";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Empty assertion message hides failure context

Assert.AreEqual(SubPurchaseLineFactbox.SubcontractingPrices.Value, Format(SubcontractorPrice.Count()), '') uses an empty failure message, so any assertion failure in test output provides no context about what was expected.

Recommendation:

  • Add a descriptive message and consider swapping expected/actual order so expected is first.
Suggested change
TransferHeader: Record "Transfer Header";
Assert.AreEqual(Format(SubcontractorPrice.Count()), SubPurchaseLineFactbox.SubcontractingPrices.Value, 'Subcontracting Prices factbox count must match the number of Subcontractor Price records.');

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

#pragma warning restore AA0210
ProdOrderComp.FindFirst();
ProdOrderComp."Location Code" := Location.Code;
ProdOrderComp.Modify();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Direct field set and Modify() bypasses OnModify triggers

ProdOrderComp."Location Code" := Location.Code followed by ProdOrderComp.Modify() (no true) skips OnModify triggers. If those triggers adjust linked transfer lines or planning data, the test will operate on inconsistent state.

Recommendation:

  • Use ProdOrderComp.Modify(true) to execute OnModify triggers.
Suggested change
ProdOrderComp.Modify();
ProdOrderComp.Modify(true);

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

#pragma warning restore AA0210
ProdOrderComp.FindFirst();

Assert.AreEqual(ProdOrderComp."Location Code", LocationCode, '');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Empty assertion messages in location/bin checks

Assert.AreEqual(ProdOrderComp."Location Code", LocationCode, '') and the following BinCode assertion both have empty messages, making it impossible to distinguish which field failed in a test failure report.

Recommendation:

  • Add descriptive failure messages to both assertions.
Suggested change
Assert.AreEqual(ProdOrderComp."Location Code", LocationCode, '');
Assert.AreEqual(ProdOrderComp."Location Code", LocationCode, 'Prod. Order Component Location Code must match the expected location.');
Assert.AreEqual(ProdOrderComp."Bin Code", BinCode, 'Prod. Order Component Bin Code must match the expected bin.');

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

LibraryWarehouse.CreateBin(Bin, Location.Code, '', '', '');
ProdOrderComp."Location Code" := Location.Code;
ProdOrderComp."Bin Code" := Bin.Code;
ProdOrderComp.Modify();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Direct field set and Modify() bypasses OnModify triggers

Setting ProdOrderComp."Location Code" and "Bin Code" directly then calling Modify() (without true) skips OnModify processing. Subcontracting OnModify logic that reacts to location changes will not fire.

Recommendation:

  • Use ProdOrderComp.Modify(true) here and at the similar call on line 1478.
Suggested change
ProdOrderComp.Modify();
ProdOrderComp.Modify(true);

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

Vendor."Subc. Location Code" := Location.Code;
LibraryWarehouse.CreateLocationWithInventoryPostingSetup(Location);
Vendor."Location Code" := Location.Code;
Vendor.Modify();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Vendor.Modify() without trigger skips OnModify

Vendor."Subc. Location Code" is set directly then saved with Vendor.Modify() (no true), bypassing any OnModify event subscribers that might propagate location information to subcontracting records.

Recommendation:

  • Use Vendor.Modify(true) to execute OnModify triggers.
Suggested change
Vendor.Modify();
Vendor.Modify(true);

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

Vendor.Modify();
end;

procedure CreateWorkCenter(var WorkCenterNo: Code[20]; ShopCalendarCode: Code[10]; FlushingMethod: Enum "Flushing Method"; Subcontract: Boolean;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Public helper procedure should be local

procedure CreateWorkCenter(...) is declared without local in a test codeunit, unnecessarily exposing a setup helper as a public method.

Recommendation:

  • Add local to the procedure declaration.
Suggested change
procedure CreateWorkCenter(var WorkCenterNo: Code[20]; ShopCalendarCode: Code[10]; FlushingMethod: Enum "Flushing Method"; Subcontract: Boolean;
local procedure CreateWorkCenter(var WorkCenterNo: Code[20]; ShopCalendarCode: Code[10]; FlushingMethod: Enum "Flushing Method"; Subcontract: Boolean;

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why


if Subcontract then begin
LibraryERM.FindVATPostingSetup(VATPostingSetup, VATPostingSetup."VAT Calculation Type"::"Normal VAT");
GenProductPostingGroup.FindFirst();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

FindFirst without filter on GenProductPostingGroup

The CreateWorkCenter helper calls GenProductPostingGroup.FindFirst() with no filter, producing non-deterministic test behaviour — whichever posting group happens to be first may not have the VAT setup required by the test.

Recommendation:

  • Replace with a filtered or library-assisted lookup so the same posting group is selected reliably across environments.
Suggested change
GenProductPostingGroup.FindFirst();
LibraryERM.FindGenProductPostingGroup(GenProductPostingGroup);

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

ReservationEntry.Insert();
end;

procedure CreateInventory(Item: Record Item; Location: Record Location; Bin: Record Bin; Quantity: Decimal)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Public helper procedure should be local

procedure CreateInventory(...) is not local, exposing an inventory setup helper as a public method from a test codeunit with no need for external access.

Recommendation:

  • Add local to the procedure declaration.
Suggested change
procedure CreateInventory(Item: Record Item; Location: Record Location; Bin: Record Bin; Quantity: Decimal)
local procedure CreateInventory(Item: Record Item; Location: Record Location; Bin: Record Bin; Quantity: Decimal)

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

ProductionOrder: Record "Production Order";
PurchaseHeader: Record "Purchase Header";
PurchaseLine: Record "Purchase Line";
TransferHeader: Record "Transfer Header";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Performance} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Factbox count uses full-table Count()

The assertion compares the factbox value for one purchase line against SubcontractorPrice.Count() with no filters. That performs a full scan and becomes nondeterministic if any other subcontractor prices exist in the test company.

Recommendation:

  • Apply the same item/work center/vendor filters used by the UI context before calling Count().
Suggested change
TransferHeader: Record "Transfer Header";
SubcontractorPrice.SetRange("Work Center No.", WorkCenter[2]."No.");
SubcontractorPrice.SetRange("Item No.", Item."No.");
Assert.AreEqual(SubPurchaseLineFactbox.SubcontractingPrices.Value, Format(SubcontractorPrice.Count()), '');

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

PurchCommentLine.SetRange("No.", PurchaseLine."Document No.");
PurchCommentLine.SetRange("Document Line No.", PurchaseLine."Line No.");

Assert.IsFalse(PurchaseLine.IsEmpty(), 'Purchase Comment Line must be filled');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Comment-line assertion checks wrong record

The test filters Purch. Comment Line but asserts on PurchaseLine.IsEmpty() instead. That assertion is unrelated to the transferred comment and lets the test pass even when no comment line was created.

Recommendation:

  • Assert on PurchCommentLine after applying the filters so the test actually validates comment transfer.
Suggested change
Assert.IsFalse(PurchaseLine.IsEmpty(), 'Purchase Comment Line must be filled');
Assert.IsFalse(PurchCommentLine.IsEmpty(), 'Purchase Comment Line must be filled');

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

WorkCenter[2].Modify(true);

// [GIVEN] Create requisition worksheet
ReqWkshTemplate.DeleteAll(true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Test removes all requisition templates

ReqWkshTemplate.DeleteAll(true) clears every requisition worksheet template, not just data created by this test. That can invalidate shared setup and make unrelated tests fail unpredictably.

Recommendation:

  • Create or reuse a dedicated template for this test instead of deleting the whole table, or at minimum filter deletion to a test-specific template name.
Suggested change
ReqWkshTemplate.DeleteAll(true);
if not ReqWkshTemplate.Get(SelectRequisitionTemplateName()) then begin
ReqWkshTemplate.Init();
ReqWkshTemplate.Validate(Name, SelectRequisitionTemplateName());
ReqWkshTemplate.Insert(true);
end;

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

var
ReservationEntry: Record "Reservation Entry";
begin
ReservationEntry.DeleteAll();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟠\ High\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Mock helper deletes all reservation entries

Calling ReservationEntry.DeleteAll() without filters wipes the entire table for the company. This breaks test isolation and can corrupt other transfer, purchase, or production tests running in the same suite.

Recommendation:

  • Delete only reservation entries that belong to the specific transfer line being mocked.
Suggested change
ReservationEntry.DeleteAll();
ReservationEntry.SetRange("Source Type", Database::"Transfer Line");
ReservationEntry.SetRange("Source ID", TransferLine."Document No.");
ReservationEntry.SetRange("Source Ref. No.", TransferLine."Line No.");
ReservationEntry.DeleteAll();

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

GenProductPostingGroup.Get(WorkCenter[2]."Gen. Prod. Posting Group");
OriginalDefVATProdPostGrp := GenProductPostingGroup."Def. VAT Prod. Posting Group";
GenProductPostingGroup."Def. VAT Prod. Posting Group" := '';
GenProductPostingGroup.Modify();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

$\textbf{🟡\ Medium\ Severity\ —\ Style} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

Shared setup is modified without safe restore

The test persists a blank Def. VAT Prod. Posting Group on a live posting group and only restores it at the end. If any assertion or runtime error occurs before teardown, later tests inherit the broken setup.

Recommendation:

  • Avoid mutating shared setup records directly; use a test-specific posting group or a save/restore helper that guarantees cleanup even on failure.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

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

Labels

AL: Apps (W1) Add-on apps for W1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant