InsuranceController Tests & Minor Changes
- Adds tests for the majority of the methods within InsuranceController. - Simplifies the `InsuranceController.sendMail()` method so that the toDelete parameter is no longer required. - Modifies `InsuranceController.findItemsToDelete()` to only process regular and attachment items when they exist. - Modifies `InsuranceController.rollForDelete()` to return null in the event that the provided Trader can not be found.
This commit is contained in:
parent
1d90a472f2
commit
7f37d48753
@ -129,7 +129,7 @@ export class InsuranceController
|
||||
this.adoptOrphanedItems(insured);
|
||||
|
||||
// Send the mail to the player.
|
||||
this.sendMail(sessionID, insured, insured.items.length === 0);
|
||||
this.sendMail(sessionID, insured);
|
||||
|
||||
// Remove the fully processed insurance package from the profile.
|
||||
this.removeInsurancePackageFromProfile(sessionID, insured.messageContent.systemData);
|
||||
@ -170,11 +170,20 @@ export class InsuranceController
|
||||
const itemsMap = this.populateItemsMap(insured);
|
||||
const parentAttachmentsMap = this.populateParentAttachmentsMap(insured, itemsMap);
|
||||
|
||||
// Process all items that are not attached, attachments. Those are handled separately, by value.
|
||||
this.processRegularItems(insured, toDelete);
|
||||
// Check to see if any regular items are present.
|
||||
const hasRegularItems = Array.from(itemsMap.values()).some(item => !this.itemHelper.isAttachmentAttached(item));
|
||||
|
||||
// Process attached, attachments, by value.
|
||||
this.processAttachments(parentAttachmentsMap, itemsMap, insured.traderId, toDelete);
|
||||
// Process all items that are not attached, attachments. Those are handled separately, by value.
|
||||
if (hasRegularItems)
|
||||
{
|
||||
this.processRegularItems(insured, toDelete);
|
||||
}
|
||||
|
||||
// Process attached, attachments, by value, only if there are any.
|
||||
if (parentAttachmentsMap.size > 0)
|
||||
{
|
||||
this.processAttachments(parentAttachmentsMap, itemsMap, insured.traderId, toDelete);
|
||||
}
|
||||
|
||||
// Log the number of items marked for deletion, if any
|
||||
if (toDelete.size)
|
||||
@ -455,14 +464,13 @@ export class InsuranceController
|
||||
*
|
||||
* @param sessionID The session ID that should receive the insurance message.
|
||||
* @param insurance The context of insurance to use.
|
||||
* @param noItems Whether or not there are any items to return to the player.
|
||||
* @returns void
|
||||
*/
|
||||
protected sendMail(sessionID: string, insurance: Insurance, noItems: boolean): void
|
||||
protected sendMail(sessionID: string, insurance: Insurance): void
|
||||
{
|
||||
// After all of the item filtering that we've done, if there are no items remaining, the insurance has
|
||||
// successfully "failed" to return anything and an appropriate message should be sent to the player.
|
||||
if (noItems)
|
||||
if (insurance.items.length === 0)
|
||||
{
|
||||
const insuranceFailedTemplates = this.databaseServer.getTables().traders[insurance.traderId].dialogue.insuranceFailed;
|
||||
insurance.messageContent.templateId = this.randomUtil.getArrayValue(insuranceFailedTemplates);
|
||||
@ -486,10 +494,16 @@ export class InsuranceController
|
||||
*
|
||||
* @param traderId The ID of the trader who insured the item.
|
||||
* @param insuredItem Optional. The item to roll for. Only used for logging.
|
||||
* @returns true if the insured item should be removed from inventory, false otherwise.
|
||||
* @returns true if the insured item should be removed from inventory, false otherwise, or null on error.
|
||||
*/
|
||||
protected rollForDelete(traderId: string, insuredItem?: Item): boolean
|
||||
protected rollForDelete(traderId: string, insuredItem?: Item): boolean | null
|
||||
{
|
||||
const trader = this.traderHelper.getTraderById(traderId);
|
||||
if (!trader)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
const maxRoll = 9999;
|
||||
const conversionFactor = 100;
|
||||
|
||||
@ -499,7 +513,6 @@ export class InsuranceController
|
||||
|
||||
// Log the roll with as much detail as possible.
|
||||
const itemName = insuredItem ? ` for "${this.itemHelper.getItemName(insuredItem._tpl)}"` : "";
|
||||
const trader = this.traderHelper.getTraderById(traderId);
|
||||
const status = roll ? "Delete" : "Keep";
|
||||
this.logger.debug(`Rolling deletion${itemName} with ${trader} - Return ${traderReturnChance}% - Roll: ${returnChance} - Status: ${status}`);
|
||||
|
||||
|
1057
project/tests/controllers/InsuranceController.test.ts
Normal file
1057
project/tests/controllers/InsuranceController.test.ts
Normal file
@ -0,0 +1,1057 @@
|
||||
import "reflect-metadata";
|
||||
import { container } from "tsyringe";
|
||||
import { vi, beforeAll, afterEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { InsuranceController } from "@spt-aki/controllers/InsuranceController";
|
||||
|
||||
import { MessageType } from "@spt-aki/models/enums/MessageType";
|
||||
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
|
||||
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
|
||||
|
||||
describe("InsuranceController", () =>
|
||||
{
|
||||
let insuranceController: any; // Using "any" to access private/protected methods without type errors.
|
||||
|
||||
beforeAll(() =>
|
||||
{
|
||||
insuranceController = container.resolve<InsuranceController>("InsuranceController");
|
||||
});
|
||||
|
||||
afterEach(() =>
|
||||
{
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("processReturn", () =>
|
||||
{
|
||||
/*
|
||||
it("should process return for all profiles", () =>
|
||||
{
|
||||
const session1 = "session1";
|
||||
const session2 = "session2";
|
||||
const profiles = {
|
||||
[session1]: {},
|
||||
[session2]: {}
|
||||
};
|
||||
const getProfilesSpy = vi.spyOn(insuranceController.saveServer, "getProfiles").mockReturnValue(profiles);
|
||||
const processReturnByProfileSpy = vi.spyOn(insuranceController, "processReturnByProfile");
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.processReturn();
|
||||
|
||||
// Should make a call to get all of the profiles.
|
||||
expect(getProfilesSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Should process each returned profile.
|
||||
expect(processReturnByProfileSpy).toHaveBeenCalledTimes(2);
|
||||
expect(processReturnByProfileSpy).toHaveBeenCalledWith(session1);
|
||||
expect(processReturnByProfileSpy).toHaveBeenCalledWith(session2);
|
||||
});
|
||||
*/
|
||||
|
||||
it("should not attempt to process profiles if no profiles exist", () =>
|
||||
{
|
||||
vi.spyOn(insuranceController.saveServer, "getProfiles").mockReturnValue({});
|
||||
const processReturnByProfileSpy = vi.spyOn(insuranceController, "processReturnByProfile");
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.processReturn();
|
||||
|
||||
// Should not process any profiles.
|
||||
expect(processReturnByProfileSpy).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findItemsToDelete", () =>
|
||||
{
|
||||
it("should handle an empty insured object", () =>
|
||||
{
|
||||
const insured = { items: [] };
|
||||
const result = insuranceController.findItemsToDelete(insured);
|
||||
expect(result.size).toBe(0);
|
||||
});
|
||||
|
||||
it("should handle only regular items", () =>
|
||||
{
|
||||
const mockProcessRegularItems = vi.fn((insured, toDelete) =>
|
||||
{
|
||||
toDelete.add("item1");
|
||||
toDelete.add("item2");
|
||||
});
|
||||
const mockProcessAttachments = vi.fn();
|
||||
|
||||
// Spy and replace the real methods with mocks
|
||||
const mockIsAttachmentAttached = vi.spyOn(insuranceController.itemHelper, "isAttachmentAttached").mockReturnValue(false);
|
||||
vi.spyOn(insuranceController, "processRegularItems").mockImplementation(mockProcessRegularItems);
|
||||
vi.spyOn(insuranceController, "processAttachments").mockImplementation(mockProcessAttachments);
|
||||
|
||||
// Create the insured object with only regular items
|
||||
const insured = {
|
||||
traderId: "some-trader-id",
|
||||
items: [
|
||||
{ _id: "item1", parentId: null },
|
||||
{ _id: "item2", parentId: null },
|
||||
{ _id: "item3", parentId: null }
|
||||
]
|
||||
};
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.findItemsToDelete(insured);
|
||||
|
||||
// Verify that the correct methods were called and that the result is correct.
|
||||
expect(mockIsAttachmentAttached).toHaveBeenCalledTimes(4); // Once to see if any attachments are present, once for each item.
|
||||
expect(mockProcessRegularItems).toHaveBeenCalledWith(insured, expect.any(Set));
|
||||
expect(mockProcessAttachments).not.toHaveBeenCalled();
|
||||
expect(result.size).toBe(2);
|
||||
expect(result).toEqual(new Set(["item1", "item2"]));
|
||||
});
|
||||
|
||||
it("should handle only attachments", () =>
|
||||
{
|
||||
// Mock helper methods to simulate only attachments being present.
|
||||
const mockPopulateItemsMap = vi.fn().mockReturnValue(new Map([
|
||||
["attach1", { _id: "attach1", parentId: "item1" }],
|
||||
["attach2", { _id: "attach2", parentId: "item2" }]
|
||||
]));
|
||||
const mockPopulateParentAttachmentsMap = vi.fn().mockReturnValue(new Map([
|
||||
["item1", [{ _id: "attach1", parentId: "item1" }]],
|
||||
["item2", [{ _id: "attach2", parentId: "item2" }]]
|
||||
]));
|
||||
const mockProcessRegularItems = vi.fn();
|
||||
const mockProcessAttachments = vi.fn((parentAttachmentsMap, itemsMap, traderId, toDelete) =>
|
||||
{
|
||||
toDelete.add("attach1");
|
||||
toDelete.add("attach2");
|
||||
});
|
||||
|
||||
// Spy and replace the real methods with mocks.
|
||||
vi.spyOn(insuranceController, "populateItemsMap").mockImplementation(mockPopulateItemsMap);
|
||||
vi.spyOn(insuranceController, "populateParentAttachmentsMap").mockImplementation(mockPopulateParentAttachmentsMap);
|
||||
vi.spyOn(insuranceController, "processRegularItems").mockImplementation(mockProcessRegularItems);
|
||||
vi.spyOn(insuranceController, "processAttachments").mockImplementation(mockProcessAttachments);
|
||||
|
||||
// Create the insured object with only attachments.
|
||||
const insured = {
|
||||
traderId: "some-trader-id",
|
||||
items: [
|
||||
{ _id: "attach1", parentId: "item1" },
|
||||
{ _id: "attach2", parentId: "item2" }
|
||||
]
|
||||
};
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.findItemsToDelete(insured);
|
||||
|
||||
// Verify that the correct methods were called and that the result is correct.
|
||||
expect(mockPopulateItemsMap).toHaveBeenCalledWith(insured);
|
||||
expect(mockPopulateParentAttachmentsMap).toHaveBeenCalledWith(insured, expect.any(Map));
|
||||
expect(mockProcessRegularItems).not.toHaveBeenCalled();
|
||||
expect(mockProcessAttachments).toHaveBeenCalledWith(expect.any(Map), expect.any(Map), insured.traderId, expect.any(Set));
|
||||
expect(result.size).toBe(2);
|
||||
expect(result).toEqual(new Set(["attach1", "attach2"]));
|
||||
});
|
||||
|
||||
it("should handle a mix of regular items and attachments", () =>
|
||||
{
|
||||
// Mock helper methods to simulate only attachments being present.
|
||||
const mockPopulateItemsMap = vi.fn().mockReturnValue(new Map([
|
||||
["itemId1", { _id: "itemId1", parentId: null }], // Parent
|
||||
["itemId2", { _id: "itemId2", parentId: "itemId1" }] // Attachment
|
||||
]));
|
||||
const mockPopulateParentAttachmentsMap = vi.fn().mockReturnValue(new Map([
|
||||
["itemId1", [{ _id: "itemId2", parentId: "itemId1" }]]
|
||||
]));
|
||||
const mockIsAttachmentAttached = vi.fn().mockReturnValueOnce(false).mockReturnValueOnce(true);
|
||||
const mockProcessRegularItems = vi.fn();
|
||||
const mockProcessAttachments = vi.fn((parentAttachmentsMap, itemsMap, traderId, toDelete) =>
|
||||
{
|
||||
toDelete.add("itemId2");
|
||||
});
|
||||
|
||||
// Spy and replace the real methods with mocks.
|
||||
vi.spyOn(insuranceController, "populateItemsMap").mockImplementation(mockPopulateItemsMap);
|
||||
vi.spyOn(insuranceController, "populateParentAttachmentsMap").mockImplementation(mockPopulateParentAttachmentsMap);
|
||||
vi.spyOn(insuranceController.itemHelper, "isAttachmentAttached").mockImplementation(mockIsAttachmentAttached);
|
||||
vi.spyOn(insuranceController, "processRegularItems").mockImplementation(mockProcessRegularItems);
|
||||
vi.spyOn(insuranceController, "processAttachments").mockImplementation(mockProcessAttachments);
|
||||
|
||||
const insured = {
|
||||
traderId: "some-trader",
|
||||
items: [
|
||||
{ _id: "itemId1", parentId: null },
|
||||
{ _id: "itemId2", parentId: "itemId1" }
|
||||
]
|
||||
};
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.findItemsToDelete(insured);
|
||||
|
||||
// Verify that the correct methods were called and that the result is correct.
|
||||
expect(mockPopulateItemsMap).toHaveBeenCalledWith(insured);
|
||||
expect(mockPopulateParentAttachmentsMap).toHaveBeenCalledWith(insured, expect.any(Map));
|
||||
expect(mockIsAttachmentAttached).toHaveBeenCalledTimes(1);
|
||||
expect(mockProcessRegularItems).toHaveBeenCalledTimes(1);
|
||||
expect(mockProcessAttachments).toHaveBeenCalledTimes(1);
|
||||
expect(result.size).toBe(1);
|
||||
expect(result).toEqual(new Set(["itemId2"]));
|
||||
});
|
||||
|
||||
it("should return an empty set if no items are to be deleted", () =>
|
||||
{
|
||||
const mockIsAttachmentAttached = vi.fn().mockReturnValue(false);
|
||||
vi.spyOn(insuranceController.itemHelper, "isAttachmentAttached").mockImplementation(mockIsAttachmentAttached);
|
||||
|
||||
const insured = {
|
||||
traderId: "some-trader",
|
||||
items: [] // No items
|
||||
};
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.findItemsToDelete(insured);
|
||||
|
||||
// Verify that the result is an empty set.
|
||||
expect(result.size).toBe(0);
|
||||
expect(result).toEqual(new Set());
|
||||
});
|
||||
|
||||
it("should return a set of items to be deleted", () =>
|
||||
{
|
||||
const mockIsAttachmentAttached = vi.fn().mockReturnValue(false);
|
||||
const mockProcessRegularItems = vi.fn((insured, toDelete) =>
|
||||
{
|
||||
toDelete.add("itemId1");
|
||||
});
|
||||
|
||||
vi.spyOn(insuranceController.itemHelper, "isAttachmentAttached").mockImplementation(mockIsAttachmentAttached);
|
||||
vi.spyOn(insuranceController, "processRegularItems").mockImplementation(mockProcessRegularItems);
|
||||
|
||||
const insured = {
|
||||
traderId: "some-trader",
|
||||
items: [
|
||||
{ _id: "itemId1", parentId: null }
|
||||
]
|
||||
};
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.findItemsToDelete(insured);
|
||||
|
||||
// Verify that the result is a set containing the item.
|
||||
expect(result.size).toBe(1);
|
||||
expect(result).toEqual(new Set(["itemId1"]));
|
||||
});
|
||||
|
||||
it("should log the number of items to be deleted", () =>
|
||||
{
|
||||
const mockIsAttachmentAttached = vi.fn().mockReturnValue(false);
|
||||
const mockProcessRegularItems = vi.fn((insured, toDelete) =>
|
||||
{
|
||||
toDelete.add("itemId1").add("itemId2").add("itemId3").add("itemId4");
|
||||
});
|
||||
|
||||
vi.spyOn(insuranceController.itemHelper, "isAttachmentAttached").mockImplementation(mockIsAttachmentAttached);
|
||||
vi.spyOn(insuranceController, "processRegularItems").mockImplementation(mockProcessRegularItems);
|
||||
const loggerDebugSpy = vi.spyOn(insuranceController.logger, "debug");
|
||||
|
||||
const insured = {
|
||||
traderId: "some-trader",
|
||||
items: [
|
||||
{ _id: "itemId1", parentId: null },
|
||||
{ _id: "itemId2", parentId: null },
|
||||
{ _id: "itemId3", parentId: null },
|
||||
{ _id: "itemId4", parentId: null },
|
||||
{ _id: "itemId5", parentId: null }
|
||||
]
|
||||
};
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.findItemsToDelete(insured);
|
||||
|
||||
// Verify that the result is a set containing the item.
|
||||
expect(result.size).toBe(4);
|
||||
expect(loggerDebugSpy).toBeCalledWith("Marked 4 items for deletion from insurance.");
|
||||
});
|
||||
});
|
||||
|
||||
describe("populateParentAttachmentsMap", () =>
|
||||
{
|
||||
it("should correctly populate main parent to attachments map", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "gun", parentId: null, _tpl: "gun_tpl" },
|
||||
{ _id: "scope", parentId: "gun", _tpl: "scope_tpl" },
|
||||
{ _id: "muzzle", parentId: "gun", _tpl: "muzzle_tpl" }
|
||||
]
|
||||
};
|
||||
|
||||
const itemsMap = new Map<string, Item>([
|
||||
["gun", { _id: "gun", parentId: null, _tpl: "gun_tpl" }],
|
||||
["scope", { _id: "scope", parentId: "gun", _tpl: "scope_tpl" }],
|
||||
["muzzle", { _id: "muzzle", parentId: "gun", _tpl: "muzzle_tpl" }]
|
||||
]);
|
||||
|
||||
const isAttachmentAttachedSpy = vi.spyOn(insuranceController.itemHelper, "isAttachmentAttached").mockImplementation((item: Item) =>
|
||||
{
|
||||
return item.parentId !== null;
|
||||
});
|
||||
|
||||
const isRaidModdableSpy = vi.spyOn(insuranceController.itemHelper, "isRaidModdable").mockReturnValue(true);
|
||||
const getAttachmentMainParentSpy = vi.spyOn(insuranceController.itemHelper, "getAttachmentMainParent").mockImplementation((itemId: string, map: Map<string, Item>) =>
|
||||
{
|
||||
return map.get("gun");
|
||||
});
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.populateParentAttachmentsMap(insured, itemsMap);
|
||||
|
||||
// Verify that helper methods are called correctly.
|
||||
expect(isAttachmentAttachedSpy).toHaveBeenCalledTimes(3);
|
||||
expect(isRaidModdableSpy).toHaveBeenCalledTimes(2);
|
||||
expect(getAttachmentMainParentSpy).toHaveBeenCalledTimes(2);
|
||||
|
||||
// Verify that the map is populated correctly.
|
||||
expect(result.size).toBe(1);
|
||||
expect(result.get("gun").length).toBe(2);
|
||||
expect(result.get("gun")[0]._id).toBe("scope");
|
||||
expect(result.get("gun")[1]._id).toBe("muzzle");
|
||||
});
|
||||
|
||||
it("should not map items that don't have a parent", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "item1", parentId: null },
|
||||
{ _id: "item2", parentId: null }
|
||||
]
|
||||
};
|
||||
const itemsMap = new Map();
|
||||
itemsMap.set("item1", insured.items[0]);
|
||||
itemsMap.set("item2", insured.items[1]);
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.populateParentAttachmentsMap(insured, itemsMap);
|
||||
|
||||
// Verify that no items are mapped.
|
||||
expect(result.size).toBe(0);
|
||||
});
|
||||
|
||||
it("should ignore non-raid-moddable items", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "item1", parentId: "parent1" },
|
||||
{ _id: "item2", parentId: "parent1" }
|
||||
]
|
||||
};
|
||||
const itemsMap = new Map();
|
||||
itemsMap.set("item1", insured.items[0]);
|
||||
itemsMap.set("item2", insured.items[1]);
|
||||
|
||||
// Mock isRaidModdable to return false
|
||||
vi.spyOn(insuranceController.itemHelper, "isRaidModdable").mockReturnValue(false);
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.populateParentAttachmentsMap(insured, itemsMap);
|
||||
|
||||
// Verify that no items are mapped.
|
||||
expect(result.size).toBe(0);
|
||||
});
|
||||
|
||||
it("should skip attachments where main parent can't be found", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "item1", parentId: "parent1" },
|
||||
{ _id: "item2", parentId: "parent1" }
|
||||
]
|
||||
};
|
||||
const itemsMap = new Map();
|
||||
itemsMap.set("item1", insured.items[0]);
|
||||
itemsMap.set("item2", insured.items[1]);
|
||||
|
||||
// Mock getAttachmentMainParent to return null.
|
||||
vi.spyOn(insuranceController.itemHelper, "getAttachmentMainParent").mockReturnValue(null);
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.populateParentAttachmentsMap(insured, itemsMap);
|
||||
|
||||
// Verify that no items are mapped.
|
||||
expect(result.size).toBe(0);
|
||||
});
|
||||
|
||||
it("should correctly handle multiple main parents", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "item1", parentId: "parent1" },
|
||||
{ _id: "item2", parentId: "parent1" },
|
||||
{ _id: "item3", parentId: "parent2" },
|
||||
{ _id: "item4", parentId: "parent2" }
|
||||
]
|
||||
};
|
||||
const itemsMap = new Map();
|
||||
itemsMap.set("item1", insured.items[0]);
|
||||
itemsMap.set("item2", insured.items[1]);
|
||||
itemsMap.set("item3", insured.items[2]);
|
||||
itemsMap.set("item4", insured.items[3]);
|
||||
|
||||
// Mock to make all items raid moddable.
|
||||
vi.spyOn(insuranceController.itemHelper, "isRaidModdable").mockReturnValue(true);
|
||||
|
||||
// Mock to make all items attached.
|
||||
vi.spyOn(insuranceController.itemHelper, "isAttachmentAttached").mockReturnValue(true);
|
||||
|
||||
// Mock getAttachmentMainParent to return a corresponding parent for each item.
|
||||
vi.spyOn(insuranceController.itemHelper, "getAttachmentMainParent").mockImplementation((itemId) =>
|
||||
{
|
||||
return itemsMap.get(itemId).parentId === "parent1" ? { _id: "parent1" } : { _id: "parent2" };
|
||||
});
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.populateParentAttachmentsMap(insured, itemsMap);
|
||||
|
||||
// Verify that both main parents ("parent1" and "parent2") are mapped correctly.
|
||||
expect(result.size).toBe(2);
|
||||
expect(result.get("parent1")).toEqual([{ _id: "item1", parentId: "parent1" }, { _id: "item2", parentId: "parent1" }]);
|
||||
expect(result.get("parent2")).toEqual([{ _id: "item3", parentId: "parent2" }, { _id: "item4", parentId: "parent2" }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("processRegularItems", () =>
|
||||
{
|
||||
it("should correctly process regular items and their children", () =>
|
||||
{
|
||||
const insured: { traderId: string, items: unknown } = {
|
||||
traderId: "some-trader-id",
|
||||
items: [
|
||||
{ _id: "item1", parentId: null },
|
||||
{ _id: "item2", parentId: "item1" },
|
||||
{ _id: "item3", parentId: null },
|
||||
{ _id: "item4", parentId: "item3" }
|
||||
] as Item[]
|
||||
};
|
||||
const toDelete = new Set<string>();
|
||||
|
||||
// Mock helper methods and rollForDelete.
|
||||
const isAttachmentAttachedSpy = vi.spyOn(insuranceController.itemHelper, "isAttachmentAttached").mockImplementation((item: Item) =>
|
||||
{
|
||||
return item.parentId !== null;
|
||||
});
|
||||
const findAndReturnChildrenAsItemsSpy = vi.spyOn(insuranceController.itemHelper, "findAndReturnChildrenAsItems").mockImplementation((items: Item[], parentId: string) =>
|
||||
{
|
||||
return items.filter(item => item.parentId === parentId);
|
||||
});
|
||||
const rollForDeleteSpy = vi.spyOn(insuranceController, "rollForDelete").mockReturnValue(true);
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.processRegularItems(insured, toDelete);
|
||||
|
||||
// Verify behavior.
|
||||
expect(isAttachmentAttachedSpy).toHaveBeenCalledTimes(6); // Once for each item, one more for each item with a null parentId.
|
||||
expect(findAndReturnChildrenAsItemsSpy).toHaveBeenCalledTimes(2); // Called only for item1 and item3
|
||||
expect(rollForDeleteSpy).toHaveBeenCalledTimes(2); // Called only for item1 and item3
|
||||
expect(toDelete).toEqual(new Set(["item1", "item2", "item3", "item4"])); // All items should be marked for deletion
|
||||
});
|
||||
});
|
||||
|
||||
describe("processAttachments", () =>
|
||||
{
|
||||
it("should process each set of attachments by their parent items and log parent names", () =>
|
||||
{
|
||||
const attachments1 = [
|
||||
{ _id: "attach1", _tpl: "tpl1" },
|
||||
{ _id: "attach2", _tpl: "tpl2" }
|
||||
];
|
||||
const attachments2 = [
|
||||
{ _id: "attach3", _tpl: "tpl3" },
|
||||
{ _id: "attach4", _tpl: "tpl4" }
|
||||
];
|
||||
const parent1 = { _id: "parent1", _tpl: "parentTpl1" };
|
||||
const parent2 = { _id: "parent2", _tpl: "parentTpl2" };
|
||||
const traderId = "some-trader-id";
|
||||
const toDelete = new Set<string>();
|
||||
|
||||
// Mock helper methods.
|
||||
const processAttachmentByParentSpy = vi.spyOn(insuranceController, "processAttachmentByParent").mockImplementation(() =>
|
||||
{});
|
||||
const itemHelperGetItemNameSpy = vi.spyOn(insuranceController.itemHelper, "getItemName").mockImplementation((_tpl) => _tpl);
|
||||
|
||||
// Create maps.
|
||||
const mainParentToAttachmentsMap = new Map<string, any>();
|
||||
mainParentToAttachmentsMap.set(parent1._id, attachments1);
|
||||
mainParentToAttachmentsMap.set(parent2._id, attachments2);
|
||||
|
||||
const itemsMap = new Map<string, any>();
|
||||
itemsMap.set(parent1._id, parent1);
|
||||
itemsMap.set(parent2._id, parent2);
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.processAttachments(mainParentToAttachmentsMap, itemsMap, traderId, toDelete);
|
||||
|
||||
// Verify that helper methods are called correctly.
|
||||
expect(processAttachmentByParentSpy).toHaveBeenCalledTimes(2);
|
||||
expect(processAttachmentByParentSpy).toHaveBeenCalledWith(attachments1, traderId, toDelete);
|
||||
expect(processAttachmentByParentSpy).toHaveBeenCalledWith(attachments2, traderId, toDelete);
|
||||
|
||||
expect(itemHelperGetItemNameSpy).toHaveBeenCalledTimes(2);
|
||||
expect(itemHelperGetItemNameSpy).toHaveBeenCalledWith(parent1._tpl);
|
||||
expect(itemHelperGetItemNameSpy).toHaveBeenCalledWith(parent2._tpl);
|
||||
});
|
||||
});
|
||||
|
||||
describe("processAttachmentByParent", () =>
|
||||
{
|
||||
it("should process attachments by calling helper methods in sequence", () =>
|
||||
{
|
||||
const attachments = [
|
||||
{ _id: "attach1", _tpl: "tpl1" },
|
||||
{ _id: "attach2", _tpl: "tpl2" }
|
||||
];
|
||||
const traderId = "some-trader-id";
|
||||
const toDelete = new Set<string>();
|
||||
|
||||
// Mock helper methods.
|
||||
const sortAttachmentsByPriceSpy = vi.spyOn(insuranceController, "sortAttachmentsByPrice").mockReturnValue(attachments);
|
||||
const logAttachmentsDetailsSpy = vi.spyOn(insuranceController, "logAttachmentsDetails").mockImplementation(() =>
|
||||
{});
|
||||
const countSuccessfulRollsSpy = vi.spyOn(insuranceController, "countSuccessfulRolls").mockReturnValue(4);
|
||||
const attachmentDeletionByValueSpy = vi.spyOn(insuranceController, "attachmentDeletionByValue").mockImplementation(() =>
|
||||
{});
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.processAttachmentByParent(attachments, traderId, toDelete);
|
||||
|
||||
// Verify that helper methods are called in the correct sequence.
|
||||
expect(sortAttachmentsByPriceSpy).toHaveBeenCalledWith(attachments);
|
||||
expect(logAttachmentsDetailsSpy).toHaveBeenCalledWith(attachments);
|
||||
expect(countSuccessfulRollsSpy).toHaveBeenCalledWith(attachments, traderId);
|
||||
expect(attachmentDeletionByValueSpy).toHaveBeenCalledWith(attachments, 4, toDelete);
|
||||
});
|
||||
});
|
||||
|
||||
describe("sortAttachmentsByPrice", () =>
|
||||
{
|
||||
it("should sort the attachments array by maxPrice in descending order", () =>
|
||||
{
|
||||
const attachments = [
|
||||
{ _id: "item1", _tpl: "tpl1" },
|
||||
{ _id: "item2", _tpl: "tpl2" },
|
||||
{ _id: "item3", _tpl: "tpl3" }
|
||||
];
|
||||
|
||||
const itemHelper = {
|
||||
getItemName: vi.fn((tpl) => `Item Name ${tpl}`),
|
||||
getItemMaxPrice: vi.fn((tpl) =>
|
||||
{
|
||||
if (tpl === "tpl1") return 100;
|
||||
if (tpl === "tpl2") return 200;
|
||||
if (tpl === "tpl3") return 50;
|
||||
return 0;
|
||||
})
|
||||
};
|
||||
|
||||
// Mock the itemHelper methods.
|
||||
vi.spyOn(insuranceController.itemHelper, "getItemName").mockImplementation(itemHelper.getItemName);
|
||||
vi.spyOn(insuranceController.itemHelper, "getItemMaxPrice").mockImplementation(itemHelper.getItemMaxPrice);
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.sortAttachmentsByPrice(attachments);
|
||||
|
||||
// Verify that the array is sorted by maxPrice in descending order.
|
||||
expect(result[0].maxPrice).toBe(200);
|
||||
expect(result[1].maxPrice).toBe(100);
|
||||
expect(result[2].maxPrice).toBe(50);
|
||||
});
|
||||
|
||||
it("should handle null max-price values by sorting them to the bottom", () =>
|
||||
{
|
||||
const attachments = [
|
||||
{ _id: "item1", _tpl: "tpl1" },
|
||||
{ _id: "item2", _tpl: "tpl2" },
|
||||
{ _id: "item3", _tpl: "tpl3" }
|
||||
];
|
||||
|
||||
const itemHelper = {
|
||||
getItemName: vi.fn((tpl) => `Item Name ${tpl}`),
|
||||
getItemMaxPrice: vi.fn((tpl) =>
|
||||
{
|
||||
if (tpl === "tpl1") return null;
|
||||
if (tpl === "tpl2") return 200;
|
||||
if (tpl === "tpl3") return 50;
|
||||
return 0;
|
||||
})
|
||||
};
|
||||
|
||||
// Mock the itemHelper methods.
|
||||
vi.spyOn(insuranceController.itemHelper, "getItemName").mockImplementation(itemHelper.getItemName);
|
||||
vi.spyOn(insuranceController.itemHelper, "getItemMaxPrice").mockImplementation(itemHelper.getItemMaxPrice);
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.sortAttachmentsByPrice(attachments);
|
||||
|
||||
// Verify that the array is sorted by maxPrice in descending order.
|
||||
expect(result[0].maxPrice).toBe(200);
|
||||
expect(result[1].maxPrice).toBe(50);
|
||||
expect(result[2].maxPrice).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("logAttachmentsDetails", () =>
|
||||
{
|
||||
it("should log details for each attachment", () =>
|
||||
{
|
||||
const attachments = [
|
||||
{ _id: "item1", name: "Item 1", maxPrice: 100 },
|
||||
{ _id: "item2", name: "Item 2", maxPrice: 200 }
|
||||
];
|
||||
|
||||
// Mock the logger.debug function.
|
||||
const loggerDebugSpy = vi.spyOn(insuranceController.logger, "debug").mockImplementation(() =>
|
||||
{});
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.logAttachmentsDetails(attachments);
|
||||
|
||||
// Verify that logger.debug was called correctly.
|
||||
expect(loggerDebugSpy).toHaveBeenCalledTimes(2);
|
||||
expect(loggerDebugSpy).toHaveBeenNthCalledWith(1, "Child Item - Name: Item 1, Max Price: 100");
|
||||
expect(loggerDebugSpy).toHaveBeenNthCalledWith(2, "Child Item - Name: Item 2, Max Price: 200");
|
||||
});
|
||||
});
|
||||
|
||||
describe("countSuccessfulRolls", () =>
|
||||
{
|
||||
it("should count the number of successful rolls based on the rollForDelete method", () =>
|
||||
{
|
||||
const attachments = [
|
||||
{ _id: "attach1", name: "Attachment 1" },
|
||||
{ _id: "attach2", name: "Attachment 2" },
|
||||
{ _id: "attach3", name: "Attachment 3" }
|
||||
];
|
||||
const traderId = "some-trader-id";
|
||||
|
||||
// Create a deterministic sequence of "random" values for the test.
|
||||
const randomSequence = [0.6, 0.4, 0.6]; // Two rolls > 0.5 and one roll < 0.5
|
||||
let i = 0;
|
||||
const originalRandom = Math.random;
|
||||
Math.random = vi.fn(() => randomSequence[i++]);
|
||||
|
||||
// Mock rollForDelete to return based on our "random" values.
|
||||
vi.spyOn(insuranceController, "rollForDelete").mockImplementation((id) =>
|
||||
{
|
||||
return id === traderId && Math.random() > 0.5;
|
||||
});
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.countSuccessfulRolls(attachments, traderId);
|
||||
|
||||
// Verify that two successful rolls were counted (first and third items).
|
||||
expect(result).toBe(2);
|
||||
|
||||
// Restore the original Math.random function.
|
||||
Math.random = originalRandom;
|
||||
});
|
||||
|
||||
it("should return zero if there are no successful rolls", () =>
|
||||
{
|
||||
const attachments = [
|
||||
{ _id: "attach1", name: "Attachment 1" }
|
||||
];
|
||||
const traderId = "some-trader-id";
|
||||
|
||||
// Mock rollForDelete to always return false.
|
||||
vi.spyOn(insuranceController, "rollForDelete").mockReturnValue(false);
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.countSuccessfulRolls(attachments, traderId);
|
||||
|
||||
// Verify that zero successful rolls were returned.
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
|
||||
it("should return zero if there are no attachments", () =>
|
||||
{
|
||||
const attachments = [];
|
||||
const traderId = "some-trader-id";
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.countSuccessfulRolls(attachments, traderId);
|
||||
|
||||
// Verify that zero successful rolls were returned.
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("attachmentDeletionByValue", () =>
|
||||
{
|
||||
it("should add attachments to the toDelete set based on successfulRolls", () =>
|
||||
{
|
||||
const attachments = [
|
||||
{ _id: "attach1", name: "Attachment 1", maxPrice: 300 },
|
||||
{ _id: "attach2", name: "Attachment 2", maxPrice: 200 },
|
||||
{ _id: "attach3", name: "Attachment 3", maxPrice: 100 }
|
||||
];
|
||||
const successfulRolls = 2;
|
||||
const toDelete = new Set<string>();
|
||||
|
||||
const loggerDebugSpy = vi.spyOn(insuranceController.logger, "debug").mockImplementation(() =>
|
||||
{});
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.attachmentDeletionByValue(attachments, successfulRolls, toDelete);
|
||||
|
||||
// Should add the first two valuable attachments to the toDelete set.
|
||||
expect(toDelete).toEqual(new Set(["attach1", "attach2"]));
|
||||
|
||||
// Verify that logger.debug was called twice.
|
||||
expect(loggerDebugSpy).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("should not add any attachments to toDelete if successfulRolls is zero", () =>
|
||||
{
|
||||
const attachments = [
|
||||
{ _id: "attach1", name: "Attachment 1", maxPrice: 100 }
|
||||
];
|
||||
const successfulRolls = 0;
|
||||
const toDelete = new Set<string>();
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.attachmentDeletionByValue(attachments, successfulRolls, toDelete);
|
||||
|
||||
// Verify that no attachments are added to the toDelete set.
|
||||
expect(toDelete).toEqual(new Set([]));
|
||||
});
|
||||
|
||||
it("should add all attachments to toDelete if successfulRolls is greater than the number of attachments", () =>
|
||||
{
|
||||
const attachments = [
|
||||
{ _id: "attach1", name: "Attachment 1", maxPrice: 100 },
|
||||
{ _id: "attach2", name: "Attachment 2", maxPrice: 200 }
|
||||
];
|
||||
const successfulRolls = 3;
|
||||
const toDelete = new Set<string>();
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.attachmentDeletionByValue(attachments, successfulRolls, toDelete);
|
||||
|
||||
// Verify that all attachments are added to the toDelete set.
|
||||
expect(toDelete).toEqual(new Set(["attach1", "attach2"]));
|
||||
});
|
||||
});
|
||||
|
||||
describe("removeItemsFromInsurance", () =>
|
||||
{
|
||||
it("should remove items from insurance based on the toDelete set", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "item1" },
|
||||
{ _id: "item2" },
|
||||
{ _id: "item3" }
|
||||
]
|
||||
};
|
||||
const toDelete = new Set<string>(["item1", "item3"]);
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.removeItemsFromInsurance(insured, toDelete);
|
||||
|
||||
// Verify that items with _id "item1" and "item3" are removed
|
||||
expect(insured.items).toEqual([{ _id: "item2" }]);
|
||||
});
|
||||
|
||||
it("should not remove any items if toDelete set is empty", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "item1" },
|
||||
{ _id: "item2" },
|
||||
{ _id: "item3" }
|
||||
]
|
||||
};
|
||||
const toDelete = new Set<string>();
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.removeItemsFromInsurance(insured, toDelete);
|
||||
|
||||
// Verify that no items are removed.
|
||||
expect(insured.items).toEqual([
|
||||
{ _id: "item1" },
|
||||
{ _id: "item2" },
|
||||
{ _id: "item3" }
|
||||
]);
|
||||
});
|
||||
|
||||
it("should leave the insurance items empty if all are to be deleted", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "item1" },
|
||||
{ _id: "item2" }
|
||||
]
|
||||
};
|
||||
const toDelete = new Set<string>(["item1", "item2"]);
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.removeItemsFromInsurance(insured, toDelete);
|
||||
|
||||
// Verify that all items are removed.
|
||||
expect(insured.items).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("adoptOrphanedItems", () =>
|
||||
{
|
||||
it("should adopt orphaned items by resetting them as base-level items", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "1", parentId: "999", slotId: "main" }, // This is orphaned.
|
||||
{ _id: "2", parentId: "1", slotId: "main" }
|
||||
]
|
||||
};
|
||||
const hideoutParentId = "hideout-parent";
|
||||
|
||||
vi.spyOn(insuranceController, "fetchHideoutItemParent").mockReturnValue(hideoutParentId);
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.adoptOrphanedItems(insured);
|
||||
|
||||
// Verify that the item with _id "1" has been adopted.
|
||||
expect(insured.items[0].parentId).toBe(hideoutParentId);
|
||||
expect(insured.items[0].slotId).toBe("hideout");
|
||||
});
|
||||
|
||||
it("should not adopt items that are not orphaned", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "1", parentId: "999", slotId: "main" },
|
||||
{ _id: "2", parentId: "1", slotId: "main" } // This is not orphaned.
|
||||
]
|
||||
};
|
||||
const hideoutParentId = "hideout-parent";
|
||||
|
||||
vi.spyOn(insuranceController, "fetchHideoutItemParent").mockReturnValue(hideoutParentId);
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.adoptOrphanedItems(insured);
|
||||
|
||||
// Verify that the item with _id "2" has not been adopted.
|
||||
expect(insured.items[1].parentId).toBe("1");
|
||||
expect(insured.items[1].slotId).not.toBe("hideout");
|
||||
});
|
||||
|
||||
it("should remove location data from adopted items", () =>
|
||||
{
|
||||
const insured = {
|
||||
items: [
|
||||
{ _id: "1", parentId: "999", slotId: "main", location: "location-value" }, // This is orphaned.
|
||||
{ _id: "2", parentId: "1", slotId: "main", location: "location-value" }
|
||||
]
|
||||
};
|
||||
const hideoutParentId = "hideout-parent";
|
||||
|
||||
vi.spyOn(insuranceController, "fetchHideoutItemParent").mockReturnValue(hideoutParentId);
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.adoptOrphanedItems(insured);
|
||||
|
||||
// Verify that the item with _id "1" has no location data.
|
||||
expect(insured.items[0]).not.toHaveProperty("location", "location-value");
|
||||
});
|
||||
});
|
||||
|
||||
describe("fetchHideoutItemParent", () =>
|
||||
{
|
||||
it("should return the parentId of the hideout item if it exists", () =>
|
||||
{
|
||||
const hideoutId = "hideout_id";
|
||||
const items = [
|
||||
{ id: "1", slotId: "hideout", parentId: hideoutId },
|
||||
{ id: "2", slotId: "main", parentId: "not_hideout_id" }
|
||||
];
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.fetchHideoutItemParent(items);
|
||||
|
||||
// Verify that the hideout item parentId is returned.
|
||||
expect(result).toBe(hideoutId);
|
||||
});
|
||||
|
||||
it("should return an empty string if the hideout item does not exist", () =>
|
||||
{
|
||||
const items = [
|
||||
{ id: "1", slotId: "mod_suppressor", parentId: "not_hideout_id" },
|
||||
{ id: "2", slotId: "main", parentId: "not_hideout_id" }
|
||||
];
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.fetchHideoutItemParent(items);
|
||||
|
||||
// Verify that an empty string is returned.
|
||||
expect(result).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("sendMail", () =>
|
||||
{
|
||||
it("should send insurance failed message when no items are present", () =>
|
||||
{
|
||||
const traderHelper = container.resolve<TraderHelper>("TraderHelper");
|
||||
|
||||
const sessionID = "someSessionId";
|
||||
const insuranceFailedTpl = "failed-message-template";
|
||||
const insurance = {
|
||||
traderId: "54cb57776803fa99248b456e", // Therapist
|
||||
messageContent: {
|
||||
templateId: null,
|
||||
maxStorageTime: 100,
|
||||
systemData: {}
|
||||
},
|
||||
items: []
|
||||
};
|
||||
|
||||
// Mock the randomUtil to return a static failed template string.
|
||||
vi.spyOn(insuranceController.randomUtil, "getArrayValue").mockReturnValue(insuranceFailedTpl);
|
||||
|
||||
// Don't actually send the message.
|
||||
const sendLocalisedNpcMessageToPlayerSpy = vi.spyOn(insuranceController.mailSendService, "sendLocalisedNpcMessageToPlayer").mockImplementation(() =>
|
||||
{});
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.sendMail(sessionID, insurance);
|
||||
|
||||
// Verify that the insurance failed message was sent.
|
||||
expect(sendLocalisedNpcMessageToPlayerSpy).toHaveBeenCalledWith(
|
||||
sessionID,
|
||||
traderHelper.getTraderById(insurance.traderId),
|
||||
MessageType.INSURANCE_RETURN,
|
||||
insuranceFailedTpl,
|
||||
insurance.items,
|
||||
insurance.messageContent.maxStorageTime,
|
||||
insurance.messageContent.systemData
|
||||
);
|
||||
});
|
||||
|
||||
it("should not send insurance failed message when items are present", () =>
|
||||
{
|
||||
const traderHelper = container.resolve<TraderHelper>("TraderHelper");
|
||||
|
||||
const sessionID = "someSessionId";
|
||||
const itemMessageTpl = "item-message-template";
|
||||
const insuranceFailedTpl = "failed-message-template";
|
||||
const insurance = {
|
||||
traderId: "54cb57776803fa99248b456e", // Therapist
|
||||
messageContent: {
|
||||
templateId: itemMessageTpl,
|
||||
maxStorageTime: 100,
|
||||
systemData: {}
|
||||
},
|
||||
items: ["item1", "item2"]
|
||||
};
|
||||
|
||||
// Mock the randomUtil to return a static failed template string.
|
||||
vi.spyOn(insuranceController.randomUtil, "getArrayValue").mockReturnValue(insuranceFailedTpl);
|
||||
|
||||
// Don't actually send the message.
|
||||
const sendLocalisedNpcMessageToPlayerSpy = vi.spyOn(insuranceController.mailSendService, "sendLocalisedNpcMessageToPlayer").mockImplementation(() =>
|
||||
{});
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.sendMail(sessionID, insurance);
|
||||
|
||||
// Verify that the insurance failed message was not sent.
|
||||
expect(sendLocalisedNpcMessageToPlayerSpy).toHaveBeenCalledWith(
|
||||
sessionID,
|
||||
traderHelper.getTraderById(insurance.traderId),
|
||||
MessageType.INSURANCE_RETURN,
|
||||
itemMessageTpl,
|
||||
insurance.items,
|
||||
insurance.messageContent.maxStorageTime,
|
||||
insurance.messageContent.systemData
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rollForDelete", () =>
|
||||
{
|
||||
it("should return true when random roll is equal to trader return chance", () =>
|
||||
{
|
||||
vi.spyOn(insuranceController.randomUtil, "getInt").mockReturnValue(8500); // Our "random" roll.
|
||||
const traderId = "54cb57776803fa99248b456e"; // Therapist (85% return chance)
|
||||
insuranceController.insuranceConfig = {
|
||||
returnChancePercent: {
|
||||
[traderId]: 85 // Force 85% return chance
|
||||
}
|
||||
};
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.rollForDelete(traderId);
|
||||
|
||||
// Verify that the result is true.
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true when random roll is greater than trader return chance", () =>
|
||||
{
|
||||
vi.spyOn(insuranceController.randomUtil, "getInt").mockReturnValue(8501); // Our "random" roll.
|
||||
const traderId = "54cb57776803fa99248b456e"; // Therapist (85% return chance)
|
||||
insuranceController.insuranceConfig = {
|
||||
returnChancePercent: {
|
||||
[traderId]: 85 // Force 85% return chance
|
||||
}
|
||||
};
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.rollForDelete(traderId);
|
||||
|
||||
// Verify that the result is true.
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false when random roll is less than trader return chance", () =>
|
||||
{
|
||||
vi.spyOn(insuranceController.randomUtil, "getInt").mockReturnValue(8499); // Our "random" roll.
|
||||
const traderId = "54cb57776803fa99248b456e"; // Therapist (85% return chance)
|
||||
insuranceController.insuranceConfig = {
|
||||
returnChancePercent: {
|
||||
[traderId]: 85 // Force 85% return chance
|
||||
}
|
||||
};
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.rollForDelete(traderId);
|
||||
|
||||
// Verify that the result is false.
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should log error if trader can not be found", () =>
|
||||
{
|
||||
const traderId = "invalid-trader-id";
|
||||
|
||||
const loggerErrorSpy = vi.spyOn(insuranceController.logger, "error").mockImplementation(() =>
|
||||
{});
|
||||
|
||||
// Execute the method.
|
||||
insuranceController.rollForDelete(traderId);
|
||||
|
||||
// Verify that the logger.error method was called.
|
||||
expect(loggerErrorSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should return null if trader can not be found", () =>
|
||||
{
|
||||
const traderId = "invalid-trader-id";
|
||||
|
||||
vi.spyOn(insuranceController.logger, "error").mockImplementation(() =>
|
||||
{});
|
||||
|
||||
// Execute the method.
|
||||
const result = insuranceController.rollForDelete(traderId);
|
||||
|
||||
// Verify that the result is null.
|
||||
expect(result).toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user