Files
marco/tests/unit/utils/activity-test.js
T

212 lines
6.8 KiB
JavaScript

import { module, test } from 'qunit';
import {
ActivityEntry,
parseZapReceipt,
enrichWithPhoto,
} from 'marco/utils/activity';
import {
setVerifyWrappedEventMethod,
fakeVerifyEvent,
} from 'applesauce-core/helpers/event';
setVerifyWrappedEventMethod(fakeVerifyEvent);
const USER_PUBKEY = 'a'.repeat(64);
const SENDER_PUBKEY = 'b'.repeat(64);
const PHOTO_EVENT_ID = '1'.repeat(64);
const RECEIPT_ID = '2'.repeat(64);
const ZAP_REQ_ID_1 = '3'.repeat(64);
const ZAP_REQ_ID_2 = '4'.repeat(64);
const PHOTO_XYZ_ID = '5'.repeat(64);
const OTHER_EVENT_ID = '6'.repeat(64);
const BOLT11_INVOICE =
'lnbc20u1p3y0x3hpp5743k2g0fsqqxj7n8qzuhns5gmkk4djeejk3wkp64ppevgekvc0jsdqcve5kzar2v9nr5gpqd4hkuetesp5ez2g297jduwc20t6lmqlsg3man0vf2jfd8ar9fh8fhn2g8yttfkqxqy9gcqcqzys9qrsgqrzjqtx3k77yrrav9hye7zar2rtqlfkytl094dsp0ms5majzth6gt7ca6uhdkxl983uywgqqqqlgqqqvx5qqjqrzjqd98kxkpyw0l9tyy8r8q57k7zpy9zjmh6sez752wj6gcumqnj3yxzhdsmg6qq56utgqqqqqqqqqqqeqqjq7jd56882gtxhrjm03c93aacyfy306m4fq0tskf83c0nmet8zc2lxyyg3saz8x6vwcp26xnrlagf9semau3qm2glysp7sv95693fphvsp54l567';
function makeZapReceiptEvent(opts = {}) {
const recipient = opts.recipient || USER_PUBKEY;
const sender = opts.sender || SENDER_PUBKEY;
const zappedEventId = opts.zappedEventId || PHOTO_EVENT_ID;
const description = JSON.stringify({
kind: 9734,
pubkey: sender,
content: opts.message || '',
id: ZAP_REQ_ID_1,
created_at: 10000,
sig: 'fake',
tags: [
['p', recipient],
['relays', ['wss://relay.example.com']],
],
});
return {
id: opts.id || RECEIPT_ID,
kind: 9735,
pubkey: opts.receiptAuthor || 'zap-service-pubkey',
created_at: opts.created_at || 10000,
tags: [
['p', recipient],
['P', sender],
['e', zappedEventId],
['bolt11', BOLT11_INVOICE],
['description', description],
],
content: '',
sig: 'sig',
};
}
function makePhotoEvent(opts = {}) {
return {
id: opts.id || PHOTO_EVENT_ID,
pubkey: opts.author || USER_PUBKEY,
kind: 360,
created_at: opts.created_at || 5000,
tags: [
['i', opts.placeIdentifier || 'osm:node:123'],
['imeta', `url ${opts.url || 'https://x.com/photo.jpg'}`, 'dim 800x600'],
],
content: '',
sig: 'sig',
};
}
module('Unit | Utility | activity', function () {
test('ActivityEntry has type "zap" and tracked sender fields', function (assert) {
const entry = new ActivityEntry({
photoEventId: '1'.repeat(64),
photo: null,
placeIdentifier: 'osm:node:1',
senderPubkey: SENDER_PUBKEY,
amountSats: 21,
message: 'Nice!',
createdAt: 10000,
});
assert.strictEqual(entry.type, 'zap');
assert.strictEqual(entry.senderPubkey, SENDER_PUBKEY);
assert.strictEqual(entry.amountSats, 21);
assert.strictEqual(entry.message, 'Nice!');
assert.true(entry.senderProfileLoading, 'senderProfileLoading starts true');
});
test('parseZapReceipt extracts sender, amount, and zapped event id', function (assert) {
const receipt = makeZapReceiptEvent({ message: 'Great photo!' });
const entry = parseZapReceipt(receipt, USER_PUBKEY);
assert.ok(entry, 'returns an entry');
assert.strictEqual(entry.senderPubkey, SENDER_PUBKEY);
assert.strictEqual(entry.photoEventId, PHOTO_EVENT_ID);
assert.strictEqual(entry.amountSats, 2000, '2000000 msat → 2000 sats');
assert.strictEqual(entry.message, 'Great photo!');
assert.strictEqual(entry.createdAt, 10000);
});
test('parseZapReceipt returns null when recipient is not the user', function (assert) {
const receipt = makeZapReceiptEvent({
recipient: 'c'.repeat(64),
});
const entry = parseZapReceipt(receipt, USER_PUBKEY);
assert.notOk(entry, 'not directed at the user');
});
test('parseZapReceipt returns null for wrong kind', function (assert) {
const receipt = makeZapReceiptEvent();
receipt.kind = 1;
const entry = parseZapReceipt(receipt, USER_PUBKEY);
assert.notOk(entry);
});
test('parseZapReceipt returns null when no event pointer', function (assert) {
const receipt = makeZapReceiptEvent();
receipt.tags = receipt.tags.filter((t) => t[0] !== 'e');
const entry = parseZapReceipt(receipt, USER_PUBKEY);
assert.notOk(entry);
});
test('parseZapReceipt handles null message', function (assert) {
const description = JSON.stringify({
kind: 9734,
pubkey: SENDER_PUBKEY,
content: '',
id: ZAP_REQ_ID_2,
created_at: 10000,
sig: 'fake',
tags: [
['p', USER_PUBKEY],
['relays', ['wss://relay.example.com']],
],
});
const receipt = makeZapReceiptEvent({ description });
const entry = parseZapReceipt(receipt, USER_PUBKEY);
assert.ok(entry);
assert.strictEqual(entry.message, null, 'empty content → null message');
});
test('enrichWithPhoto populates photo and placeIdentifier from the store', function (assert) {
const photoEvent = makePhotoEvent({
id: PHOTO_XYZ_ID,
placeIdentifier: 'osm:way:456',
});
const mockStore = {
getEvent: (id) => (id === PHOTO_XYZ_ID ? photoEvent : undefined),
};
const entry = parseZapReceipt(
makeZapReceiptEvent({ zappedEventId: PHOTO_XYZ_ID }),
USER_PUBKEY
);
const result = enrichWithPhoto(entry, mockStore, USER_PUBKEY);
assert.true(result, 'enrichment succeeded');
assert.ok(entry.photo, 'photo is populated');
assert.strictEqual(
entry.placeIdentifier,
'osm:way:456',
'placeIdentifier extracted from photo'
);
assert.strictEqual(entry.photo.url, 'https://x.com/photo.jpg');
});
test('enrichWithPhoto returns false when zapped event is not a kind 360', function (assert) {
const nonPhotoEvent = { id: OTHER_EVENT_ID, pubkey: USER_PUBKEY, kind: 1 };
const mockStore = { getEvent: () => nonPhotoEvent };
const entry = parseZapReceipt(
makeZapReceiptEvent({ zappedEventId: OTHER_EVENT_ID }),
USER_PUBKEY
);
const result = enrichWithPhoto(entry, mockStore, USER_PUBKEY);
assert.false(result, 'not a kind 360');
assert.notOk(entry.photo);
});
test('enrichWithPhoto returns false when zapped event is not authored by the user', function (assert) {
const otherUserPhoto = makePhotoEvent({ author: 'z'.repeat(64) });
const mockStore = { getEvent: () => otherUserPhoto };
const entry = parseZapReceipt(
makeZapReceiptEvent({ zappedEventId: PHOTO_EVENT_ID }),
USER_PUBKEY
);
const result = enrichWithPhoto(entry, mockStore, USER_PUBKEY);
assert.false(result, 'not authored by the user');
});
test('enrichWithPhoto returns false when zapped event not in store', function (assert) {
const mockStore = { getEvent: () => undefined };
const entry = parseZapReceipt(makeZapReceiptEvent(), USER_PUBKEY);
const result = enrichWithPhoto(entry, mockStore, USER_PUBKEY);
assert.false(result, 'event not in store');
});
});