perlsky is a Perl 5 implementation of an AT Protocol Personal Data Server.
1use v5.34;
2use warnings;
3
4use Config ();
5use File::Spec;
6use File::Temp qw(tempdir);
7use FindBin qw($Bin);
8use Test::More;
9
10BEGIN {
11 require lib;
12 my $root = File::Spec->rel2abs(File::Spec->catdir($Bin, '..'));
13 lib->import(
14 File::Spec->catdir($root, 'lib'),
15 File::Spec->catdir($root, 'local', 'lib', 'perl5'),
16 File::Spec->catdir($root, 'local', 'lib', 'perl5', $Config::Config{archname}),
17 );
18}
19
20use ATProto::PDS::API::Helpers qw(admin_account_view);
21use ATProto::PDS::Store::SQLite;
22
23my $tmp = tempdir(CLEANUP => 1);
24my $store = ATProto::PDS::Store::SQLite->new(
25 path => File::Spec->catfile($tmp, 'perlsky.sqlite'),
26)->bootstrap;
27
28my $creator = $store->create_account(
29 did => 'did:web:example.test:users:creator',
30 handle => 'creator.example.test',
31 email => 'creator@example.test',
32 created_at => 1_700_000_000,
33);
34my $invitee = $store->create_account(
35 did => 'did:web:example.test:users:invitee',
36 handle => 'invitee.example.test',
37 email => 'invitee@example.test',
38 email_confirmed_at => 1_700_000_100,
39 invites_disabled => 1,
40 created_at => 1_700_000_050,
41);
42
43$store->create_invite_code(
44 code => 'perlsky-first',
45 for_account => $invitee->{did},
46 created_by => $creator->{did},
47 use_count => 2,
48 created_at => 1_700_000_150,
49);
50$store->create_invite_code(
51 code => 'perlsky-second',
52 for_account => $invitee->{did},
53 created_by => $creator->{did},
54 use_count => 1,
55 created_at => 1_700_000_151,
56);
57$store->create_invite_code(
58 code => 'perlsky-parent',
59 for_account => $creator->{did},
60 created_by => 'admin',
61 use_count => 1,
62 created_at => 1_700_000_010,
63);
64$store->record_invite_code_use(
65 code => 'perlsky-parent',
66 used_by => $invitee->{did},
67 used_at => 1_700_000_020,
68);
69
70my $view = admin_account_view($store, $invitee, entryway => 0);
71
72is($view->{did}, $invitee->{did}, 'admin account view keeps the DID');
73is($view->{handle}, $invitee->{handle}, 'admin account view keeps the handle');
74is($view->{email}, $invitee->{email}, 'admin account view keeps the email');
75is($view->{indexedAt}, '2023-11-14T22:14:10Z', 'admin account view uses created_at for indexedAt');
76ok($view->{invitesDisabled}, 'admin account view exposes invite disablement');
77is($view->{invitedBy}{code}, 'perlsky-parent', 'admin account view includes the invite that created the account');
78is($view->{invitedBy}{createdBy}, 'admin', 'admin account view includes invitedBy metadata');
79is(scalar @{ $view->{invites} || [] }, 2, 'admin account view includes owned invite codes');
80is($view->{invites}[0]{code}, 'perlsky-second', 'admin account view keeps invite ordering');
81is($view->{invites}[1]{code}, 'perlsky-first', 'admin account view includes all invites');
82
83my $entryway_view = admin_account_view($store, $invitee, entryway => 1);
84ok(!exists $entryway_view->{invitedBy}, 'entryway mode omits invitedBy');
85ok(!exists $entryway_view->{invites}, 'entryway mode omits invite lists');
86ok(!exists $entryway_view->{invitesDisabled}, 'entryway mode omits invite disablement');
87
88done_testing;