Net-Nostr-Core

 view release on metacpan or  search on metacpan

t/nip/52.t  view on Meta::CPAN

subtest 'rsvp: e tag with relay' => sub {
    my $eid = 'b' x 64;
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'rsvp-123',
        event_coord  => "31922:${PK}:vacation-2024",
        event_id     => $eid,
        event_id_relay => 'wss://relay.example.com',
        status       => 'accepted',
    );
    my @e = grep { $_->[0] eq 'e' } @{$event->tags};
    is($e[0][2], 'wss://relay.example.com', 'relay in e tag');
};

# Spec: d tag (required)
subtest 'rsvp: d tag' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'rsvp-unique-id',
        event_coord  => "31922:${PK}:test",
        status       => 'accepted',
    );
    my @d = grep { $_->[0] eq 'd' } @{$event->tags};
    is($d[0][1], 'rsvp-unique-id', 'd tag');
};

# Spec: status tag (required) accepted/declined/tentative
subtest 'rsvp: status accepted' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'accepted',
    );
    my @s = grep { $_->[0] eq 'status' } @{$event->tags};
    is($s[0][1], 'accepted', 'accepted');
};

subtest 'rsvp: status declined' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'declined',
    );
    my @s = grep { $_->[0] eq 'status' } @{$event->tags};
    is($s[0][1], 'declined', 'declined');
};

subtest 'rsvp: status tentative' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'tentative',
    );
    my @s = grep { $_->[0] eq 'status' } @{$event->tags};
    is($s[0][1], 'tentative', 'tentative');
};

# Spec: fb tag (optional) free/busy
subtest 'rsvp: fb tag busy' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'accepted',
        fb           => 'busy',
    );
    my @fb = grep { $_->[0] eq 'fb' } @{$event->tags};
    is($fb[0][1], 'busy', 'fb busy');
};

subtest 'rsvp: fb tag free' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'accepted',
        fb           => 'free',
    );
    my @fb = grep { $_->[0] eq 'fb' } @{$event->tags};
    is($fb[0][1], 'free', 'fb free');
};

subtest 'rsvp: fb tag omitted when status declined' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'declined',
        fb           => 'busy',
    );
    my @fb = grep { $_->[0] eq 'fb' } @{$event->tags};
    is(scalar @fb, 0, 'fb omitted when declined');
};

# Spec: p tag (optional) pubkey of calendar event author
subtest 'rsvp: p tag (optional)' => sub {
    my $author = 'b' x 64;
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey           => $PK,
        identifier       => 'test',
        event_coord      => "31922:${author}:test",
        status           => 'accepted',
        event_author     => $author,
        event_author_relay => 'wss://relay.example.com',
    );
    my @p = grep { $_->[0] eq 'p' } @{$event->tags};
    is($p[0][1], $author, 'author pubkey');
    is($p[0][2], 'wss://relay.example.com', 'author relay');
};

# Spec: content is optional free-form note
subtest 'rsvp: content' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'accepted',
        content      => 'Looking forward to it!',
    );
    is($event->content, 'Looking forward to it!', 'content');
};

subtest 'rsvp: content defaults to empty string' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'accepted',
    );
    is($event->content, '', 'empty content');
};

# Spec: RSVP spec example
subtest 'rsvp: spec example' => sub {
    my $eid = 'b' x 64;
    my $author = 'c' x 64;
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey             => $PK,
        identifier         => 'random-identifier',
        event_coord        => "31922:${author}:d-identifier",
        event_relay        => 'wss://relay.example.com',
        event_id           => $eid,
        event_id_relay     => 'wss://relay.example.com',
        status             => 'accepted',
        fb                 => 'busy',
        event_author       => $author,
        event_author_relay => 'wss://relay.example.com',
        content            => 'note',
    );

    is($event->kind, 31925, 'kind');
    is($event->content, 'note', 'content');

    my @e = grep { $_->[0] eq 'e' } @{$event->tags};
    is($e[0][1], $eid, 'e tag');

    my @a = grep { $_->[0] eq 'a' } @{$event->tags};
    is($a[0][1], "31922:${author}:d-identifier", 'a tag');

    my @d = grep { $_->[0] eq 'd' } @{$event->tags};
    is($d[0][1], 'random-identifier', 'd');

    my @s = grep { $_->[0] eq 'status' } @{$event->tags};
    is($s[0][1], 'accepted', 'status');

    my @fb = grep { $_->[0] eq 'fb' } @{$event->tags};
    is($fb[0][1], 'busy', 'fb');

    my @p = grep { $_->[0] eq 'p' } @{$event->tags};
    is($p[0][1], $author, 'p tag');
};

###############################################################################
# from_event: round-trip parsing
###############################################################################

subtest 'from_event: date event round-trip' => sub {
    my $pk2 = 'b' x 64;
    my $event = Net::Nostr::Calendar->date_event(
        pubkey       => $PK,
        identifier   => 'trip',
        title        => 'Road Trip',
        content      => 'Cross-country drive',
        start        => '2024-08-01',
        end          => '2024-08-15',
        summary      => 'A road trip',
        image        => 'https://example.com/trip.jpg',
        locations    => ['Highway 66'],
        geohash      => 'abc123',
        participants => [[$pk2, 'wss://relay.example.com', 'driver']],
        hashtags     => ['travel'],
        references   => ['https://example.com'],
        calendars    => ["31924:${PK}:personal"],
    );
    my $cal = Net::Nostr::Calendar->from_event($event);
    ok($cal, 'from_event returns object');
    is($cal->identifier, 'trip', 'identifier');
    is($cal->title, 'Road Trip', 'title');
    is($cal->description, 'Cross-country drive', 'description');
    is($cal->start, '2024-08-01', 'start');
    is($cal->end, '2024-08-15', 'end');
    is($cal->summary, 'A road trip', 'summary');
    is($cal->image, 'https://example.com/trip.jpg', 'image');
    is($cal->locations, ['Highway 66'], 'locations');
    is($cal->geohash, 'abc123', 'geohash');
    is(scalar @{$cal->participants}, 1, 'participants');
    is($cal->hashtags, ['travel'], 'hashtags');
    is($cal->references, ['https://example.com'], 'references');
};

subtest 'from_event: time event round-trip' => sub {
    my $event = Net::Nostr::Calendar->time_event(
        pubkey     => $PK,
        identifier => 'meeting',
        title      => 'Standup',
        start      => 1700000000,
        end        => 1700003600,
        start_tzid => 'America/New_York',
        end_tzid   => 'America/Chicago',
        days       => [19675],
    );
    my $cal = Net::Nostr::Calendar->from_event($event);
    is($cal->start, '1700000000', 'start');
    is($cal->end, '1700003600', 'end');
    is($cal->start_tzid, 'America/New_York', 'start_tzid');
    is($cal->end_tzid, 'America/Chicago', 'end_tzid');
    is($cal->days, ['19675'], 'days');



( run in 1.249 second using v1.01-cache-2.11-cpan-6aa56a78535 )