diff --git a/spec/System/TestTradeQuery_spec.lua b/spec/System/TestTradeQuery_spec.lua new file mode 100644 index 0000000000..857d3cb20e --- /dev/null +++ b/spec/System/TestTradeQuery_spec.lua @@ -0,0 +1,57 @@ +describe("TradeQuery", function() + describe("result dropdown tooltipFunc", function() + -- Builds a TradeQuery with the strict minimum needed for + -- PriceItemRowDisplay to construct row 1 without exploding. Only the + -- two itemsTab subtables read by the slot lookup at the top of + -- PriceItemRowDisplay need to be created here; everything else either + -- lives behind a callback we never trigger, or is already initialized + -- by the TradeQuery constructor. + local function newTradeQuery(state) + local tq = new("TradeQuery", { itemsTab = {} }) + tq.itemsTab.activeItemSet = {} + tq.itemsTab.slots = {} + tq.slotTables[1] = { slotName = "Ring 1" } + if state.resultTbl then tq.resultTbl = state.resultTbl end + if state.sortedResultTbl then tq.sortedResultTbl = state.sortedResultTbl end + return tq + end + + -- Builds row 1 of the trader UI and returns the dropdown that owns the + -- tooltipFunc we want to exercise. + local function buildRow1Dropdown(tq) + tq:PriceItemRowDisplay(1, nil, 0, 20) + return tq.controls.resultDropdown1 + end + + it("returns early when sortedResultTbl[row_idx] is missing", function() + -- No sorted results at all -> first guard must short-circuit. + local tq = newTradeQuery({}) + local dropdown = buildRow1Dropdown(tq) + local tooltip = new("Tooltip") + + assert.has_no.errors(function() + dropdown.tooltipFunc(tooltip, "DROP", 1, nil) + end) + assert.are.equal(0, #tooltip.lines) + end) + + it("returns early when the backing result entry has been cleared", function() + -- The dropdown must be built against a valid result so that + -- PriceItemRowDisplay's construction loop succeeds; we wipe + -- resultTbl[1] only afterwards, to simulate a stale tooltip + -- callback firing after the results were invalidated. + local tq = newTradeQuery({ + resultTbl = { [1] = { [1] = { item_string = "Rarity: RARE\nBehemoth Hold\nGold Ring" } } }, + sortedResultTbl = { [1] = { { index = 1 } } }, + }) + local dropdown = buildRow1Dropdown(tq) + tq.resultTbl[1] = {} + local tooltip = new("Tooltip") + + assert.has_no.errors(function() + dropdown.tooltipFunc(tooltip, "DROP", 1, nil) + end) + assert.are.equal(0, #tooltip.lines) + end) + end) +end) diff --git a/src/Classes/TradeQuery.lua b/src/Classes/TradeQuery.lua index 4965c4eec1..7f33b15705 100644 --- a/src/Classes/TradeQuery.lua +++ b/src/Classes/TradeQuery.lua @@ -1009,8 +1009,15 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro end end controls["resultDropdown"..row_idx].tooltipFunc = function(tooltip, dropdown_mode, dropdown_index, dropdown_display_string) - local pb_index = self.sortedResultTbl[row_idx][dropdown_index].index - local result = self.resultTbl[row_idx][pb_index] + local sortedRow = self.sortedResultTbl[row_idx] + if not sortedRow or not sortedRow[dropdown_index] then + return + end + local pb_index = sortedRow[dropdown_index].index + local result = self.resultTbl[row_idx] and self.resultTbl[row_idx][pb_index] + if not result then + return + end local item = new("Item", result.item_string) tooltip:Clear() self.itemsTab:AddItemTooltip(tooltip, item, slotTbl)