mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-27 15:28:12 +02:00
* docs: add applesauce v5 upgrade plan Comprehensive migration plan covering: - Package updates (add applesauce-common, update to v5) - EventFactory import migration (applesauce-factory → applesauce-core) - Unified event loader setup - ActionHub → ActionRunner migration - useObservableMemo → use$ hook migration - New features: casting system, encrypted content caching - Documentation and skills updates needed * feat: upgrade applesauce libraries to v5 Major upgrade from applesauce v4 to v5 with breaking changes: Package updates: - applesauce-core: ^4.0.0 → ^5.0.0 - applesauce-actions: ^4.0.0 → ^5.0.0 - applesauce-loaders: ^4.0.0 → ^5.0.0 - applesauce-react: ^4.0.0 → ^5.0.0 - applesauce-relay: ^4.0.0 → ^5.0.0 - applesauce-signers: ^4.0.0 → ^5.0.0 - applesauce-accounts: ^4.0.0 → ^5.0.0 - Added new applesauce-common: ^5.0.0 package API migrations: - EventFactory: applesauce-factory → applesauce-core/event-factory - ActionHub → ActionRunner with async function pattern (not generators) - useObservableMemo → use$ hook across all components - Helper imports: article, highlight, threading, zap, comment, lists moved from applesauce-core to applesauce-common - parseCoordinate → parseReplaceableAddress - Subscription options: retries → reconnect - getEventPointerFromETag now returns null instead of throwing New features: - Unified event loader via createEventLoaderForStore - Updated loaders.ts to use v5 unified loader pattern Documentation: - Updated CLAUDE.md with v5 patterns and migration notes - Updated applesauce-core skill for v5 changes - Created new applesauce-common skill Test fixes: - Updated publish-spellbook.test.ts for v5 ActionRunner pattern - Updated publish-spell.test.ts with eventStore mock - Updated relay-selection.test.ts with valid test events - Updated loaders.test.ts with valid 64-char hex event IDs - Added createEventLoaderForStore mock --------- Co-authored-by: Claude <noreply@anthropic.com>
113 lines
2.6 KiB
TypeScript
113 lines
2.6 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
import { PublishSpellAction } from "./publish-spell";
|
|
import accountManager from "@/services/accounts";
|
|
import pool from "@/services/relay-pool";
|
|
import * as spellStorage from "@/services/spell-storage";
|
|
import { LocalSpell } from "@/services/db";
|
|
|
|
// Mock dependencies
|
|
vi.mock("@/services/accounts", () => ({
|
|
default: {
|
|
active: {
|
|
signer: {},
|
|
pubkey: "test-pubkey",
|
|
},
|
|
},
|
|
}));
|
|
|
|
vi.mock("@/services/relay-pool", () => ({
|
|
default: {
|
|
publish: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
vi.mock("@/services/spell-storage", () => ({
|
|
markSpellPublished: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("@/services/relay-list-cache", () => ({
|
|
relayListCache: {
|
|
getOutboxRelays: vi.fn().mockResolvedValue([]),
|
|
},
|
|
}));
|
|
|
|
vi.mock("@/services/event-store", () => ({
|
|
default: {
|
|
add: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
describe("PublishSpellAction", () => {
|
|
let action: PublishSpellAction;
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
action = new PublishSpellAction();
|
|
});
|
|
|
|
it("should fail if no active account", async () => {
|
|
// @ts-expect-error: mocking internal state for test
|
|
accountManager.active = null;
|
|
|
|
const spell: LocalSpell = {
|
|
id: "spell-1",
|
|
command: "req -k 1",
|
|
createdAt: 123,
|
|
isPublished: false,
|
|
};
|
|
|
|
await expect(action.execute(spell)).rejects.toThrow("No active account");
|
|
});
|
|
|
|
it("should publish spell and update storage", async () => {
|
|
const mockSigner = {
|
|
getPublicKey: vi.fn().mockResolvedValue("pubkey"),
|
|
signEvent: vi.fn().mockImplementation((draft) =>
|
|
Promise.resolve({
|
|
...draft,
|
|
id: "event-id",
|
|
pubkey: "pubkey",
|
|
sig: "sig",
|
|
}),
|
|
),
|
|
};
|
|
|
|
// @ts-expect-error: mocking internal state for test
|
|
accountManager.active = {
|
|
signer: mockSigner,
|
|
pubkey: "pubkey",
|
|
};
|
|
|
|
const spell: LocalSpell = {
|
|
id: "local-id",
|
|
command: "req -k 1",
|
|
name: "My Spell",
|
|
description: "Description",
|
|
createdAt: 1234567890,
|
|
isPublished: false,
|
|
};
|
|
|
|
await action.execute(spell);
|
|
|
|
// Check if signer was called
|
|
expect(mockSigner.signEvent).toHaveBeenCalled();
|
|
|
|
// Check if published to pool
|
|
expect(pool.publish).toHaveBeenCalled();
|
|
|
|
// Check if storage updated
|
|
expect(spellStorage.markSpellPublished).toHaveBeenCalledWith(
|
|
"local-id",
|
|
expect.objectContaining({
|
|
kind: 777,
|
|
// We expect tags to contain name and alt (description)
|
|
tags: expect.arrayContaining([
|
|
["name", "My Spell"],
|
|
["alt", expect.stringContaining("Description")],
|
|
["cmd", "REQ"],
|
|
]),
|
|
}),
|
|
);
|
|
});
|
|
});
|