Preserve furniture revisions when downloading source assets
This commit is contained in:
1 parent
7880d5d5df
commit
8a919f85b2
5 files changed
+32
-4
No files matched your search
@@ -391,7 +391,7 @@ export const GET = withAdmin(
|
|||||||
type: item.itemType === "i" ? "wallitem" : "flooritem",
|
type: item.itemType === "i" ? "wallitem" : "flooritem",
|
||||||
name: item.name,
|
name: item.name,
|
||||||
description: item.description,
|
description: item.description,
|
||||||
revision: 0,
|
revision: Number(item.revision) || 0,
|
||||||
category: String(item.category ?? ""),
|
category: String(item.category ?? ""),
|
||||||
...presence,
|
...presence,
|
||||||
nitroExists,
|
nitroExists,
|
||||||
|
|||||||
@@ -304,3 +304,14 @@ describe("fetchSourceFurnidata", () => {
|
|||||||
).rejects.toThrow(/Cloudflare challenge/);
|
).rejects.toThrow(/Cloudflare challenge/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("preserves numeric source revisions for asset downloads", () => {
|
||||||
|
const [entry] = parseFurnidata({
|
||||||
|
roomitemtypes: {
|
||||||
|
furnitype: [
|
||||||
|
{ id: 16940, classname: "recycler_kintsugiB", revision: "73706" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(entry.revision).toBe(73706);
|
||||||
|
});
|
||||||
@@ -69,6 +69,10 @@ function toSourceFurni(
|
|||||||
return {
|
return {
|
||||||
...raw,
|
...raw,
|
||||||
id: Number(raw.id ?? 0),
|
id: Number(raw.id ?? 0),
|
||||||
|
revision:
|
||||||
|
Number.isSafeInteger(Number(raw.revision)) && Number(raw.revision) > 0
|
||||||
|
? Number(raw.revision)
|
||||||
|
: 0,
|
||||||
classname: String(raw.classname ?? ""),
|
classname: String(raw.classname ?? ""),
|
||||||
name: String(raw.name ?? raw.classname ?? ""),
|
name: String(raw.name ?? raw.classname ?? ""),
|
||||||
description: String(raw.description ?? ""),
|
description: String(raw.description ?? ""),
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import { MySqlDialect } from "drizzle-orm/mysql-core";
|
|||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
const mocks = vi.hoisted(() => ({
|
const mocks = vi.hoisted(() => ({
|
||||||
|
official: vi.fn(),
|
||||||
|
download: vi.fn(),
|
||||||
execute: vi.fn(),
|
execute: vi.fn(),
|
||||||
select: vi.fn(),
|
select: vi.fn(),
|
||||||
stat: vi.fn(),
|
stat: vi.fn(),
|
||||||
@@ -43,14 +45,14 @@ vi.mock("@/lib/services/furni-data", () => ({
|
|||||||
appendFurniEntry: mocks.append,
|
appendFurniEntry: mocks.append,
|
||||||
}));
|
}));
|
||||||
vi.mock("@/lib/services/habbo-furnidata-cache", () => ({
|
vi.mock("@/lib/services/habbo-furnidata-cache", () => ({
|
||||||
lookupOfficialHabboFurni: async () => null,
|
lookupOfficialHabboFurni: mocks.official,
|
||||||
}));
|
}));
|
||||||
vi.mock("@/lib/services/habbo-gamedata-hotel", () => ({
|
vi.mock("@/lib/services/habbo-gamedata-hotel", () => ({
|
||||||
getHabboGamedataHotel: async () => "it",
|
getHabboGamedataHotel: async () => "it",
|
||||||
}));
|
}));
|
||||||
vi.mock("@/lib/services/import/core/download", () => ({
|
vi.mock("@/lib/services/import/core/download", () => ({
|
||||||
downloadFile: vi.fn(),
|
downloadFile: vi.fn(),
|
||||||
tryDownloadCandidates: async () => false,
|
tryDownloadCandidates: mocks.download,
|
||||||
}));
|
}));
|
||||||
vi.mock("@/lib/services/swf-to-nitro", () => ({
|
vi.mock("@/lib/services/swf-to-nitro", () => ({
|
||||||
parseNitroBundle: () => ({ json: {} }),
|
parseNitroBundle: () => ({ json: {} }),
|
||||||
@@ -76,6 +78,8 @@ function queries() {
|
|||||||
describe("completion of existing furniture", () => {
|
describe("completion of existing furniture", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
|
mocks.official.mockResolvedValue(null);
|
||||||
|
mocks.download.mockResolvedValue(false);
|
||||||
const rows = [
|
const rows = [
|
||||||
[{ id: 2000037257, spriteId: 9001, type: "s" }],
|
[{ id: 2000037257, spriteId: 9001, type: "s" }],
|
||||||
[{ itemName: input.classname }],
|
[{ itemName: input.classname }],
|
||||||
@@ -140,13 +144,22 @@ it("imports recycler_kintsugiB with an allocated ID throughout SQL and furnidata
|
|||||||
return [[{ id: 123, page_id: "15" }], []];
|
return [[{ id: 123, page_id: "15" }], []];
|
||||||
return [[], []];
|
return [[], []];
|
||||||
});
|
});
|
||||||
|
mocks.official.mockResolvedValue({ revision: 73706, xdim: 1, ydim: 1 });
|
||||||
const result = await importSingleFurni({
|
const result = await importSingleFurni({
|
||||||
...input,
|
...input,
|
||||||
|
revision: 0,
|
||||||
id: 16940,
|
id: 16940,
|
||||||
classname: "recycler_kintsugiB",
|
classname: "recycler_kintsugiB",
|
||||||
});
|
});
|
||||||
expect(result.ok).toBe(true);
|
expect(result.ok).toBe(true);
|
||||||
expect(result.itemId).toBe(2000037258);
|
expect(result.itemId).toBe(2000037258);
|
||||||
|
expect(mocks.download).toHaveBeenCalledWith(
|
||||||
|
expect.arrayContaining([
|
||||||
|
"https://images.habbo.com/dcr/hof_furni/73706/recycler_kintsugiB.swf",
|
||||||
|
]),
|
||||||
|
expect.any(String),
|
||||||
|
"swf",
|
||||||
|
);
|
||||||
expect(mocks.build).toHaveBeenCalledWith(
|
expect(mocks.build).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: 2000037258,
|
id: 2000037258,
|
||||||
|
|||||||
@@ -659,7 +659,7 @@ export async function importSingleFurni(params: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ── Derive file-safe names ────────────────────────────────────────
|
// ── Derive file-safe names ────────────────────────────────────────
|
||||||
const rev = revision || 0;
|
const rev = bestRevision;
|
||||||
const assetTargets = await getFurniAssetWriteTargets();
|
const assetTargets = await getFurniAssetWriteTargets();
|
||||||
const { swfDir, iconDir, nitroDir } = assetTargets;
|
const { swfDir, iconDir, nitroDir } = assetTargets;
|
||||||
const starIdx = classname.indexOf("*");
|
const starIdx = classname.indexOf("*");
|
||||||
|
|||||||
Reference in new issue
Block a user