Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions core/src/events/content-tagger.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { describe, expect, it } from "vitest";
import { generateContentTags } from "./content-tagger";
import type { ContentTaggingOptions, NDKEvent, NDKTag } from "./index.js";

Expand Down Expand Up @@ -199,7 +200,7 @@ describe("await generateContentTags", () => {
]);
});

it("copies p-tags from target event when copyPTagsFromTarget is true", async () => {
it("do not copy p-tags from target event when copyPTagsFromTarget is true but pubkeys are invalid", async () => {
const content = "Reply to event";
const opts: ContentTaggingOptions = { copyPTagsFromTarget: true };
const mockEvent = {
Expand All @@ -216,9 +217,29 @@ describe("await generateContentTags", () => {

const { tags: processedTags } = await generateContentTags(content, [], opts, mockEvent);

expect(processedTags).toEqual([]);
});

it("copies p-tags from target event when copyPTagsFromTarget is true and pubkeys are valid", async () => {
const content = "Reply to event";
const opts: ContentTaggingOptions = { copyPTagsFromTarget: true };
const mockEvent = {
getMatchingTags: (tag: string) => {
if (tag === "p") {
return [
["p", "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],
["p", "b190175cef407c593f17c155480eda1a2ee7f6c84378eef0e97353f87ee59300"],
];
}
return [];
},
} as unknown as NDKEvent;

const { tags: processedTags } = await generateContentTags(content, [], opts, mockEvent);

expect(processedTags).toEqual([
["p", "pubkey1"],
["p", "pubkey2"],
["p", "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],
["p", "b190175cef407c593f17c155480eda1a2ee7f6c84378eef0e97353f87ee59300"],
]);
});

Expand Down
16 changes: 7 additions & 9 deletions core/src/events/encryption.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ class MockCacheAdapter implements NDKCacheAdapter {
return Promise.resolve();
}

getDecryptedEvent(eventId: string): NDKEvent | null {
return this.decryptedEvents.get(eventId) || null;
getDecryptedEvent(wrapperId: string): NDKEvent | null {
return this.decryptedEvents.get(wrapperId) || null;
}

addDecryptedEvent(event: NDKEvent): void {
this.decryptedEvents.set(event.id, event);
addDecryptedEvent(wrapperId: string, decryptedEvent: NDKEvent): void {
this.decryptedEvents.set(wrapperId, decryptedEvent);
}
}

Expand Down Expand Up @@ -369,8 +369,7 @@ describe("NDKEvent encryption (Nip44 & Nip59)", () => {
vi.spyOn(giftWrappingModule, "giftWrap").mockImplementation(async (event, _recipient, _signer, params = {}) => {
const method = params.scheme === "nip04" ? "nip04_encrypt" : "nip44_encrypt";
mockSendRequest("", method, {}, 0, () => {});
const wrapped = new NDKEvent(event.ndk);
return wrapped;
return new NDKEvent(event.ndk);
});

await giftWrappingModule.giftWrap(message, receiveUser, send46Signer);
Expand Down Expand Up @@ -407,12 +406,11 @@ describe("NDKEvent encryption (Nip44 & Nip59)", () => {

// Set up mock cache adapter
const mockCache = new MockCacheAdapter();
mockCache.addDecryptedEvent(decryptedEvent);
mockCache.addDecryptedEvent(encryptedEvent.id, decryptedEvent);
fixture.ndk.cacheAdapter = mockCache;

// Spy on cache methods
const getDecryptedEventSpy = vi.spyOn(mockCache, "getDecryptedEvent");
const _addDecryptedEventSpy = vi.spyOn(mockCache, "addDecryptedEvent");

// Mock the decrypt function for signer to verify it's not called
const decryptSpy = vi.spyOn(receiveSigner, "decrypt");
Expand Down Expand Up @@ -465,7 +463,7 @@ describe("NDKEvent encryption (Nip44 & Nip59)", () => {
expect(getDecryptedEventSpy).toHaveBeenCalledWith(encryptedEvent.id);

// Verify the decrypted event was cached
expect(addDecryptedEventSpy).toHaveBeenCalledWith(encryptedEvent);
expect(addDecryptedEventSpy).toHaveBeenCalledWith(encryptedEvent.id, encryptedEvent);

// Verify content is correct
expect(encryptedEvent.content).toBe(original);
Expand Down
16 changes: 8 additions & 8 deletions core/src/events/gift-wrapping.test.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { beforeEach, describe, expect, it } from "vitest";
import { NDK } from "../ndk/index.js";
import { NDKPrivateKeySigner } from "../signers/private-key/index.js";
import type { NDKCacheAdapter, NDKEventId } from "../cache/index.js";
import type { NDKCacheAdapter } from "../cache";
import { NDK } from "../ndk";
import { NDKPrivateKeySigner } from "../signers/private-key";
import { giftUnwrap, giftWrap } from "./gift-wrapping.js";
import { NDKEvent } from "./index.js";
import { NDKKind } from "./kinds/index.js";
import { giftWrap, giftUnwrap } from "./gift-wrapping.js";
import { NDKKind } from "./kinds";

// Mock cache adapter to track cache operations
class MockCacheAdapter implements Partial<NDKCacheAdapter> {
public locking = false;
private cache = new Map<NDKEventId, NDKEvent>();
private cache = new Map<NDKEvent["id"], NDKEvent>();
public getDecryptedEventCalls: string[] = [];
public addDecryptedEventCalls: Array<{ wrapperId: string; rumorId: string }> = [];

async getDecryptedEvent(wrapperId: NDKEventId): Promise<NDKEvent | null> {
async getDecryptedEvent(wrapperId: NDKEvent["id"]): Promise<NDKEvent | null> {
this.getDecryptedEventCalls.push(wrapperId);
return this.cache.get(wrapperId) ?? null;
}

async addDecryptedEvent(wrapperId: NDKEventId, decryptedEvent: NDKEvent): Promise<void> {
async addDecryptedEvent(wrapperId: NDKEvent["id"], decryptedEvent: NDKEvent): Promise<void> {
this.addDecryptedEventCalls.push({ wrapperId, rumorId: decryptedEvent.id });
this.cache.set(wrapperId, decryptedEvent);
}
Expand Down
18 changes: 16 additions & 2 deletions core/src/events/kinds/follow-pack.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,26 @@ describe("NDKFollowPack", () => {
});
});

it("should get/set pubkeys and manipulate p tags", () => {
it("should get/set pubkeys and manipulate p tags if pubkeys are invalid", () => {
const fp = new NDKFollowPack();
expect(fp.pubkeys).toEqual([]);

fp.pubkeys = ["pk1", "pk2"];
expect(fp.pubkeys).toEqual(["pk1", "pk2"]);
expect(fp.pubkeys).toEqual([]);
});

it("should get/set pubkeys and manipulate p tags are valid", () => {
const fp = new NDKFollowPack();
expect(fp.pubkeys).toEqual([]);

fp.pubkeys = [
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
];
expect(fp.pubkeys).toEqual([
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
]);
expect(fp.tags.filter((t) => t[0] === "p").length).toBe(2);

fp.pubkeys = [];
Expand Down
69 changes: 60 additions & 9 deletions core/src/events/kinds/interest-list.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, test } from "bun:test";
import { NDKEvent } from "../../events/index.js";
import { NDK } from "../../ndk/index.js";
import { beforeEach, describe, expect, test } from "vitest";
import { NDK } from "../../ndk";
import { NDKEvent } from "../index";
import { NDKKind } from "./index.js";
import { NDKInterestList } from "./interest-list.js";

Expand Down Expand Up @@ -29,6 +29,18 @@ describe("NDKInterestList", () => {
expect(interests).toEqual(["nostr", "bitcoin", "technology"]);
});

test("filters out falsy interest tag values", () => {
const list = new NDKInterestList(ndk);
list.tags = [
["t", "nostr"],
["t", ""],
["t", undefined as any],
["t", "bitcoin"],
];

expect(list.interests).toEqual(["nostr", "bitcoin"]);
});

test("sets interests replacing existing ones", () => {
const list = new NDKInterestList(ndk);
list.tags = [
Expand All @@ -51,6 +63,35 @@ describe("NDKInterestList", () => {
expect(list.interests).toEqual(["nostr", "bitcoin"]);
});

test("removeInterest is a no-op when interest does not exist", () => {
const list = new NDKInterestList(ndk);
list.tags = [
["t", "nostr"],
["title", "My Interests"],
["t", "bitcoin"],
];

const beforeTags = list.tags.map((t) => [...t]);

list.removeInterest("technology");

expect(list.tags).toEqual(beforeTags);
expect(list.interests).toEqual(["nostr", "bitcoin"]);
});

test("removes only the first matching interest tag", () => {
const list = new NDKInterestList(ndk);
list.tags = [
["t", "nostr"],
["t", "nostr"],
["t", "bitcoin"],
];

list.removeInterest("nostr");

expect(list.interests).toEqual(["nostr", "bitcoin"]);
});

test("removes interest", () => {
const list = new NDKInterestList(ndk);
list.interests = ["nostr", "bitcoin", "technology"];
Expand Down Expand Up @@ -99,22 +140,32 @@ describe("NDKInterestList", () => {
expect(list.interestSetReferences).toEqual([]);
});

test("updates created_at when adding interest", () => {
test("does not set created_at when adding interest (local mutation only)", () => {
const list = new NDKInterestList(ndk);
const before = Math.floor(Date.now() / 1000);
expect(list.created_at).toBeUndefined();

list.addInterest("nostr");

expect(list.created_at).toBeGreaterThanOrEqual(before);
expect(list.created_at).toBeUndefined();
});

test("updates created_at when removing interest", () => {
test("does not set created_at when removing interest (local mutation only)", () => {
const list = new NDKInterestList(ndk);
list.interests = ["nostr", "bitcoin"];
const before = Math.floor(Date.now() / 1000);
expect(list.created_at).toBeUndefined();

list.removeInterest("nostr");

expect(list.created_at).toBeGreaterThanOrEqual(before);
expect(list.created_at).toBeUndefined();
});

test("does not set created_at when removing a missing interest (no-op)", () => {
const list = new NDKInterestList(ndk);
list.interests = ["nostr", "bitcoin"];
expect(list.created_at).toBeUndefined();

list.removeInterest("technology");

expect(list.created_at).toBeUndefined();
});
});
Loading