Compare commits
2 Commits
34347f0c63
...
dd62336571
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd62336571 | ||
|
|
8280111b66 |
@@ -4,9 +4,6 @@ import { inventoryService } from "@/modules/inventory/inventory.service";
|
||||
import { userService } from "@/modules/user/user.service";
|
||||
import { createErrorEmbed } from "@lib/embeds";
|
||||
import { getItemUseResultEmbed } from "@/modules/inventory/inventory.view";
|
||||
import { inventory, items } from "@/db/schema";
|
||||
import { eq, and, like } from "drizzle-orm";
|
||||
import { DrizzleClient } from "@/lib/DrizzleClient";
|
||||
import type { ItemUsageData } from "@/lib/types";
|
||||
import { UserError } from "@/lib/errors";
|
||||
import { config } from "@/lib/config";
|
||||
@@ -75,28 +72,8 @@ export const use = createCommand({
|
||||
const focusedValue = interaction.options.getFocused();
|
||||
const userId = interaction.user.id;
|
||||
|
||||
// Fetch owned items that match the search query
|
||||
// We join with items table to filter by name directly in the database
|
||||
const entries = await DrizzleClient.select({
|
||||
quantity: inventory.quantity,
|
||||
item: items
|
||||
})
|
||||
.from(inventory)
|
||||
.innerJoin(items, eq(inventory.itemId, items.id))
|
||||
.where(and(
|
||||
eq(inventory.userId, BigInt(userId)),
|
||||
like(items.name, `%${focusedValue}%`)
|
||||
))
|
||||
.limit(20); // Fetch up to 20 matching items
|
||||
const results = await inventoryService.getAutocompleteItems(userId, focusedValue);
|
||||
|
||||
const filtered = entries.filter(entry => {
|
||||
const usageData = entry.item.usageData as ItemUsageData | null;
|
||||
const isUsable = usageData && usageData.effects && usageData.effects.length > 0;
|
||||
return isUsable;
|
||||
});
|
||||
|
||||
await interaction.respond(
|
||||
filtered.map(entry => ({ name: `${entry.item.name} (${entry.quantity})`, value: entry.item.id }))
|
||||
);
|
||||
await interaction.respond(results);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -18,6 +18,8 @@ const mockWhere = mock();
|
||||
const mockSelect = mock();
|
||||
const mockFrom = mock();
|
||||
const mockOnConflictDoUpdate = mock();
|
||||
const mockInnerJoin = mock();
|
||||
const mockLimit = mock();
|
||||
|
||||
// Chain setup
|
||||
mockInsert.mockReturnValue({ values: mockValues });
|
||||
@@ -34,7 +36,10 @@ mockWhere.mockReturnValue({ returning: mockReturning });
|
||||
mockDelete.mockReturnValue({ where: mockWhere });
|
||||
|
||||
mockSelect.mockReturnValue({ from: mockFrom });
|
||||
mockFrom.mockReturnValue({ where: mockWhere });
|
||||
mockFrom.mockReturnValue({ where: mockWhere, innerJoin: mockInnerJoin });
|
||||
mockInnerJoin.mockReturnValue({ where: mockWhere });
|
||||
mockWhere.mockReturnValue({ returning: mockReturning, limit: mockLimit });
|
||||
mockLimit.mockResolvedValue([]);
|
||||
|
||||
// Mock DrizzleClient
|
||||
mock.module("@/lib/DrizzleClient", () => {
|
||||
@@ -239,4 +244,39 @@ describe("inventoryService", () => {
|
||||
expect(mockDelete).toHaveBeenCalledWith(inventory); // Consume
|
||||
});
|
||||
});
|
||||
|
||||
describe("getAutocompleteItems", () => {
|
||||
it("should return formatted autocomplete results with rarity", async () => {
|
||||
const mockItems = [
|
||||
{
|
||||
item: { id: 1, name: "Common Sword", rarity: "Common", usageData: { effects: [{}] } },
|
||||
quantity: 5n
|
||||
},
|
||||
{
|
||||
item: { id: 2, name: "Epic Shield", rarity: "Epic", usageData: { effects: [{}] } },
|
||||
quantity: 1n
|
||||
}
|
||||
];
|
||||
|
||||
mockLimit.mockResolvedValue(mockItems);
|
||||
|
||||
// Restore mocks that might have been polluted by other tests
|
||||
mockFrom.mockReturnValue({ where: mockWhere, innerJoin: mockInnerJoin });
|
||||
mockWhere.mockReturnValue({ returning: mockReturning, limit: mockLimit });
|
||||
|
||||
const result = await inventoryService.getAutocompleteItems("1", "Sw");
|
||||
|
||||
expect(mockSelect).toHaveBeenCalled();
|
||||
expect(mockFrom).toHaveBeenCalledWith(inventory);
|
||||
expect(mockInnerJoin).toHaveBeenCalled(); // checks join
|
||||
expect(mockWhere).toHaveBeenCalled(); // checks filters
|
||||
expect(mockLimit).toHaveBeenCalledWith(20);
|
||||
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result[0]?.name).toBe("Common Sword (5) [Common]");
|
||||
expect(result[0]?.value).toBe(1);
|
||||
expect(result[1]?.name).toBe("Epic Shield (1) [Epic]");
|
||||
expect(result[1]?.value).toBe(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { inventory, items, users, userTimers } from "@/db/schema";
|
||||
import { eq, and, sql, count } from "drizzle-orm";
|
||||
import { eq, and, sql, count, ilike } from "drizzle-orm";
|
||||
import { DrizzleClient } from "@/lib/DrizzleClient";
|
||||
import { economyService } from "@/modules/economy/economy.service";
|
||||
import { levelingService } from "@/modules/leveling/leveling.service";
|
||||
@@ -181,5 +181,29 @@ export const inventoryService = {
|
||||
|
||||
return { success: true, results, usageData, item };
|
||||
}, tx);
|
||||
},
|
||||
|
||||
getAutocompleteItems: async (userId: string, query: string) => {
|
||||
const entries = await DrizzleClient.select({
|
||||
quantity: inventory.quantity,
|
||||
item: items
|
||||
})
|
||||
.from(inventory)
|
||||
.innerJoin(items, eq(inventory.itemId, items.id))
|
||||
.where(and(
|
||||
eq(inventory.userId, BigInt(userId)),
|
||||
ilike(items.name, `%${query}%`)
|
||||
))
|
||||
.limit(20);
|
||||
|
||||
const filtered = entries.filter(entry => {
|
||||
const usageData = entry.item.usageData as ItemUsageData | null;
|
||||
return usageData && usageData.effects && usageData.effects.length > 0;
|
||||
});
|
||||
|
||||
return filtered.map(entry => ({
|
||||
name: `${entry.item.name} (${entry.quantity}) [${entry.item.rarity || 'Common'}]`,
|
||||
value: entry.item.id
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user