chore: Enhance database debugging setup and expand test mocks for Drizzle queries and Discord API interactions.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/aurora_test"
|
DATABASE_URL="postgresql://auroradev:auroradev123@localhost:5432/aurora_test"
|
||||||
DISCORD_BOT_TOKEN="test_token"
|
DISCORD_BOT_TOKEN="test_token"
|
||||||
DISCORD_CLIENT_ID="123456789"
|
DISCORD_CLIENT_ID="123456789"
|
||||||
DISCORD_GUILD_ID="123456789"
|
DISCORD_GUILD_ID="123456789"
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ mock.module("discord.js", () => ({
|
|||||||
Routes: {
|
Routes: {
|
||||||
applicationGuildCommands: () => 'guild_route',
|
applicationGuildCommands: () => 'guild_route',
|
||||||
applicationCommands: () => 'global_route'
|
applicationCommands: () => 'global_route'
|
||||||
}
|
},
|
||||||
|
MessageFlags: {}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Mock loaders to avoid filesystem access during client init
|
// Mock loaders to avoid filesystem access during client init
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ mock.module("./BotClient", () => ({
|
|||||||
commands: {
|
commands: {
|
||||||
size: 20,
|
size: 20,
|
||||||
},
|
},
|
||||||
|
knownCommands: {
|
||||||
|
size: 20,
|
||||||
|
},
|
||||||
lastCommandTimestamp: 1641481200000,
|
lastCommandTimestamp: 1641481200000,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ services:
|
|||||||
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
||||||
- POSTGRES_DB=${DB_NAME}
|
- POSTGRES_DB=${DB_NAME}
|
||||||
# Uncomment to access DB from host (for debugging/drizzle-kit studio)
|
# Uncomment to access DB from host (for debugging/drizzle-kit studio)
|
||||||
# ports:
|
ports:
|
||||||
# - "127.0.0.1:${DB_PORT}:5432"
|
- "127.0.0.1:${DB_PORT}:5432"
|
||||||
volumes:
|
volumes:
|
||||||
# Host-mounted to preserve existing VPS data
|
# Host-mounted to preserve existing VPS data
|
||||||
- ./shared/db/data:/var/lib/postgresql/data
|
- ./shared/db/data:/var/lib/postgresql/data
|
||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
|
- web
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}" ]
|
test: [ "CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}" ]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
@@ -26,7 +27,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
target: development # Use development stage
|
target: development # Use development stage
|
||||||
working_dir: /app
|
working_dir: /app
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:3000:3000"
|
- "127.0.0.1:3000:3000"
|
||||||
@@ -67,8 +68,7 @@ services:
|
|||||||
extends:
|
extends:
|
||||||
service: app
|
service: app
|
||||||
# Clear inherited ports from app and only expose studio port
|
# Clear inherited ports from app and only expose studio port
|
||||||
ports:
|
ports: !override
|
||||||
!override
|
|
||||||
- "127.0.0.1:4983:4983"
|
- "127.0.0.1:4983:4983"
|
||||||
# Override healthcheck since studio doesn't serve on port 3000
|
# Override healthcheck since studio doesn't serve on port 3000
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ const mockLimit = mock();
|
|||||||
// Helper to support the chained calls in getLeaderboards
|
// Helper to support the chained calls in getLeaderboards
|
||||||
const mockChain = {
|
const mockChain = {
|
||||||
from: () => mockChain,
|
from: () => mockChain,
|
||||||
|
leftJoin: () => mockChain,
|
||||||
|
groupBy: () => mockChain,
|
||||||
orderBy: () => mockChain,
|
orderBy: () => mockChain,
|
||||||
limit: mockLimit
|
limit: mockLimit
|
||||||
};
|
};
|
||||||
@@ -75,7 +77,8 @@ describe("dashboardService", () => {
|
|||||||
// First call is topLevels, second is topWealth
|
// First call is topLevels, second is topWealth
|
||||||
mockLimit
|
mockLimit
|
||||||
.mockResolvedValueOnce(mockTopLevels)
|
.mockResolvedValueOnce(mockTopLevels)
|
||||||
.mockResolvedValueOnce(mockTopWealth);
|
.mockResolvedValueOnce(mockTopWealth)
|
||||||
|
.mockResolvedValueOnce(mockTopWealth); // Mock net worth same as wealth for simplicity
|
||||||
|
|
||||||
const result = await dashboardService.getLeaderboards();
|
const result = await dashboardService.getLeaderboards();
|
||||||
|
|
||||||
@@ -85,7 +88,7 @@ describe("dashboardService", () => {
|
|||||||
expect(result.topWealth[0]!.balance).toBe("1000");
|
expect(result.topWealth[0]!.balance).toBe("1000");
|
||||||
expect(result.topWealth[0]!.username).toBe("Alice");
|
expect(result.topWealth[0]!.username).toBe("Alice");
|
||||||
expect(result.topWealth[1]!.balance).toBe("500");
|
expect(result.topWealth[1]!.balance).toBe("500");
|
||||||
expect(mockLimit).toHaveBeenCalledTimes(2);
|
expect(mockLimit).toHaveBeenCalledTimes(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should handle empty leaderboards", async () => {
|
test("should handle empty leaderboards", async () => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { economyService } from "@shared/modules/economy/economy.service";
|
|||||||
import { users, userTimers, transactions } from "@db/schema";
|
import { users, userTimers, transactions } from "@db/schema";
|
||||||
|
|
||||||
// Define mock functions
|
// Define mock functions
|
||||||
const mockFindMany = mock();
|
const mockFindMany = mock(() => Promise.resolve([]));
|
||||||
const mockFindFirst = mock();
|
const mockFindFirst = mock();
|
||||||
const mockInsert = mock();
|
const mockInsert = mock();
|
||||||
const mockUpdate = mock();
|
const mockUpdate = mock();
|
||||||
@@ -33,6 +33,7 @@ mock.module("@shared/db/DrizzleClient", () => {
|
|||||||
query: {
|
query: {
|
||||||
users: { findFirst: mockFindFirst },
|
users: { findFirst: mockFindFirst },
|
||||||
userTimers: { findFirst: mockFindFirst },
|
userTimers: { findFirst: mockFindFirst },
|
||||||
|
userQuests: { findMany: mockFindMany },
|
||||||
},
|
},
|
||||||
insert: mockInsert,
|
insert: mockInsert,
|
||||||
update: mockUpdate,
|
update: mockUpdate,
|
||||||
@@ -173,7 +174,7 @@ describe("economyService", () => {
|
|||||||
it("should throw if cooldown is active", async () => {
|
it("should throw if cooldown is active", async () => {
|
||||||
const future = new Date("2023-01-02T12:00:00Z"); // +24h
|
const future = new Date("2023-01-02T12:00:00Z"); // +24h
|
||||||
mockFindFirst.mockResolvedValue({ expiresAt: future });
|
mockFindFirst.mockResolvedValue({ expiresAt: future });
|
||||||
expect(economyService.claimDaily("1")).rejects.toThrow("Daily already claimed");
|
expect(economyService.claimDaily("1")).rejects.toThrow("You have already claimed your daily reward today");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should set cooldown to next UTC midnight", async () => {
|
it("should set cooldown to next UTC midnight", async () => {
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ mock.module("@shared/db/DrizzleClient", () => {
|
|||||||
inventory: { findFirst: mockFindFirst, findMany: mockFindMany },
|
inventory: { findFirst: mockFindFirst, findMany: mockFindMany },
|
||||||
items: { findFirst: mockFindFirst },
|
items: { findFirst: mockFindFirst },
|
||||||
userTimers: { findFirst: mockFindFirst },
|
userTimers: { findFirst: mockFindFirst },
|
||||||
|
userQuests: { findMany: mockFindMany, findFirst: mockFindFirst },
|
||||||
|
quests: { findMany: mockFindMany },
|
||||||
},
|
},
|
||||||
insert: mockInsert,
|
insert: mockInsert,
|
||||||
update: mockUpdate,
|
update: mockUpdate,
|
||||||
@@ -79,6 +81,7 @@ describe("inventoryService", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockFindFirst.mockReset();
|
mockFindFirst.mockReset();
|
||||||
mockFindMany.mockReset();
|
mockFindMany.mockReset();
|
||||||
|
mockFindMany.mockResolvedValue([]);
|
||||||
mockInsert.mockClear();
|
mockInsert.mockClear();
|
||||||
mockUpdate.mockClear();
|
mockUpdate.mockClear();
|
||||||
mockDelete.mockClear();
|
mockDelete.mockClear();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { users, userTimers } from "@db/schema";
|
|||||||
|
|
||||||
// Mock dependencies
|
// Mock dependencies
|
||||||
const mockFindFirst = mock();
|
const mockFindFirst = mock();
|
||||||
|
const mockFindMany = mock(() => Promise.resolve([]));
|
||||||
const mockUpdate = mock();
|
const mockUpdate = mock();
|
||||||
const mockSet = mock();
|
const mockSet = mock();
|
||||||
const mockWhere = mock();
|
const mockWhere = mock();
|
||||||
@@ -24,8 +25,10 @@ mockOnConflictDoUpdate.mockResolvedValue({});
|
|||||||
mock.module("@shared/db/DrizzleClient", () => {
|
mock.module("@shared/db/DrizzleClient", () => {
|
||||||
const createMockTx = () => ({
|
const createMockTx = () => ({
|
||||||
query: {
|
query: {
|
||||||
|
|
||||||
users: { findFirst: mockFindFirst },
|
users: { findFirst: mockFindFirst },
|
||||||
userTimers: { findFirst: mockFindFirst },
|
userTimers: { findFirst: mockFindFirst },
|
||||||
|
userQuests: { findMany: mockFindMany },
|
||||||
},
|
},
|
||||||
update: mockUpdate,
|
update: mockUpdate,
|
||||||
insert: mockInsert,
|
insert: mockInsert,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ mock.module("@shared/lib/config", () => ({
|
|||||||
|
|
||||||
// Mock View
|
// Mock View
|
||||||
const mockGetUserWarningEmbed = mock(() => ({}));
|
const mockGetUserWarningEmbed = mock(() => ({}));
|
||||||
mock.module("./moderation.view", () => ({
|
mock.module("@/modules/moderation/moderation.view", () => ({
|
||||||
getUserWarningEmbed: mockGetUserWarningEmbed
|
getUserWarningEmbed: mockGetUserWarningEmbed
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
16
shared/scripts/debug-db.ts
Normal file
16
shared/scripts/debug-db.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
import postgres from "postgres";
|
||||||
|
|
||||||
|
const connectionString = "postgresql://auroradev:auroradev123@127.0.0.1:5432/aurora_test";
|
||||||
|
console.log("Connecting to:", connectionString);
|
||||||
|
|
||||||
|
const sql = postgres(connectionString);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await sql`SELECT 1 as val`;
|
||||||
|
console.log("Success:", result);
|
||||||
|
await sql.end();
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Connection failed:", e);
|
||||||
|
await sql.end();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user