@openora/core 0.4.1-canary.78 → 0.4.1-canary.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/audit/plugin.d.ts.map +1 -1
  3. package/dist/audit/plugin.js +24 -0
  4. package/dist/audit/plugin.js.map +1 -1
  5. package/dist/contracts/schemas/events.d.ts +14 -0
  6. package/dist/contracts/schemas/events.d.ts.map +1 -1
  7. package/dist/contracts/schemas/events.js +10 -9
  8. package/dist/contracts/schemas/events.js.map +1 -1
  9. package/dist/engagement/chat/service/chat.service.d.ts.map +1 -1
  10. package/dist/engagement/chat/service/chat.service.js +8 -0
  11. package/dist/engagement/chat/service/chat.service.js.map +1 -1
  12. package/dist/engagement/social/__tests__/social.router.int.test.js +80 -0
  13. package/dist/engagement/social/__tests__/social.router.int.test.js.map +1 -1
  14. package/dist/engagement/social/__tests__/social.service.int.test.js +336 -1
  15. package/dist/engagement/social/__tests__/social.service.int.test.js.map +1 -1
  16. package/dist/engagement/social/contract/index.d.ts +74 -0
  17. package/dist/engagement/social/contract/index.d.ts.map +1 -1
  18. package/dist/engagement/social/contract/index.js +33 -0
  19. package/dist/engagement/social/contract/index.js.map +1 -1
  20. package/dist/engagement/social/drizzle/migrations/0004_friendship-cancel-constraint.sql +2 -0
  21. package/dist/engagement/social/drizzle/migrations/meta/0004_snapshot.json +145 -0
  22. package/dist/engagement/social/drizzle/migrations/meta/_journal.json +7 -0
  23. package/dist/engagement/social/router/index.d.ts +43 -0
  24. package/dist/engagement/social/router/index.d.ts.map +1 -1
  25. package/dist/engagement/social/router/index.js +27 -1
  26. package/dist/engagement/social/router/index.js.map +1 -1
  27. package/dist/engagement/social/schema/index.js +1 -1
  28. package/dist/engagement/social/schema/index.js.map +1 -1
  29. package/dist/engagement/social/service/social.service.d.ts +16 -16
  30. package/dist/engagement/social/service/social.service.d.ts.map +1 -1
  31. package/dist/engagement/social/service/social.service.js +183 -39
  32. package/dist/engagement/social/service/social.service.js.map +1 -1
  33. package/dist/pam/identity/adapters/identity-reader.service.d.ts.map +1 -1
  34. package/dist/pam/identity/adapters/identity-reader.service.js +5 -2
  35. package/dist/pam/identity/adapters/identity-reader.service.js.map +1 -1
  36. package/package.json +1 -1
@@ -54,6 +54,86 @@ describe('social router authz', () => {
54
54
  const { router } = build();
55
55
  await expect(call(router.removeFriend, { targetUserId: randomUUID() }, { context: testContext() })).rejects.toBeInstanceOf(ORPCError);
56
56
  });
57
+ it('rejects listFriendRequests for an unauthenticated caller', async () => {
58
+ const { router } = build();
59
+ await expect(call(router.listFriendRequests, { page: 1, limit: 20, direction: 'incoming' }, { context: testContext() })).rejects.toBeInstanceOf(ORPCError);
60
+ });
61
+ it('rejects acceptFriendRequest for an unauthenticated caller', async () => {
62
+ const { router } = build();
63
+ await expect(call(router.acceptFriendRequest, { friendshipId: randomUUID() }, { context: testContext() })).rejects.toBeInstanceOf(ORPCError);
64
+ });
65
+ it('rejects declineFriendRequest for an unauthenticated caller', async () => {
66
+ const { router } = build();
67
+ await expect(call(router.declineFriendRequest, { friendshipId: randomUUID() }, { context: testContext() })).rejects.toBeInstanceOf(ORPCError);
68
+ });
69
+ it('rejects cancelFriendRequest for an unauthenticated caller', async () => {
70
+ const { router } = build();
71
+ await expect(call(router.cancelFriendRequest, { friendshipId: randomUUID() }, { context: testContext() })).rejects.toBeInstanceOf(ORPCError);
72
+ });
73
+ });
74
+ describe('social router listFriendRequests / accept / decline / cancel', () => {
75
+ it('lists an incoming pending request and accepts it, removing it from the requests tab', async () => {
76
+ const { router } = build();
77
+ const requester = await seedPlayer({ displayName: 'Alice' });
78
+ const addressee = await seedPlayer({ displayName: 'Bob' });
79
+ const sent = await call(router.sendFriendRequest, { targetUserId: addressee.userId }, { context: ctxFor(requester.userId) });
80
+ const incoming = await call(router.listFriendRequests, { page: 1, limit: 20, direction: 'incoming' }, { context: ctxFor(addressee.userId) });
81
+ expect(incoming.items).toHaveLength(1);
82
+ expect(incoming.items[0]).toMatchObject({
83
+ friendshipId: sent.id,
84
+ userId: requester.userId,
85
+ direction: 'incoming',
86
+ mutualFriendsCount: 0,
87
+ });
88
+ const accepted = await call(router.acceptFriendRequest, { friendshipId: sent.id }, { context: ctxFor(addressee.userId) });
89
+ expect(accepted.acceptedAt).toEqual(expect.any(String));
90
+ const afterAccept = await call(router.listFriendRequests, { page: 1, limit: 20, direction: 'incoming' }, { context: ctxFor(addressee.userId) });
91
+ expect(afterAccept.items).toHaveLength(0);
92
+ });
93
+ it('maps accepting a nonexistent/wrong-caller request to NOT_FOUND', async () => {
94
+ const { router } = build();
95
+ const caller = await seedPlayer();
96
+ const error = await call(router.acceptFriendRequest, { friendshipId: randomUUID() }, { context: ctxFor(caller.userId) }).catch((e) => e);
97
+ expect(error).toBeInstanceOf(ORPCError);
98
+ expect(error.code).toBe('NOT_FOUND');
99
+ });
100
+ it('declines an incoming request, removing it with no acceptance', async () => {
101
+ const { router } = build();
102
+ const requester = await seedPlayer();
103
+ const addressee = await seedPlayer();
104
+ const sent = await call(router.sendFriendRequest, { targetUserId: addressee.userId }, { context: ctxFor(requester.userId) });
105
+ const result = await call(router.declineFriendRequest, { friendshipId: sent.id }, { context: ctxFor(addressee.userId) });
106
+ expect(result).toEqual({ success: true });
107
+ const afterDecline = await call(router.listFriendRequests, { page: 1, limit: 20, direction: 'incoming' }, { context: ctxFor(addressee.userId) });
108
+ expect(afterDecline.items).toHaveLength(0);
109
+ });
110
+ it('lists an outgoing pending request and cancels it, removing it from the requests tab', async () => {
111
+ const { router } = build();
112
+ const requester = await seedPlayer();
113
+ const addressee = await seedPlayer();
114
+ const sent = await call(router.sendFriendRequest, { targetUserId: addressee.userId }, { context: ctxFor(requester.userId) });
115
+ const outgoing = await call(router.listFriendRequests, { page: 1, limit: 20, direction: 'outgoing' }, { context: ctxFor(requester.userId) });
116
+ expect(outgoing.items).toHaveLength(1);
117
+ expect(outgoing.items[0]).toMatchObject({
118
+ friendshipId: sent.id,
119
+ userId: addressee.userId,
120
+ direction: 'outgoing',
121
+ mutualFriendsCount: null,
122
+ });
123
+ const result = await call(router.cancelFriendRequest, { friendshipId: sent.id }, { context: ctxFor(requester.userId) });
124
+ expect(result).toEqual({ success: true });
125
+ const afterCancel = await call(router.listFriendRequests, { page: 1, limit: 20, direction: 'outgoing' }, { context: ctxFor(requester.userId) });
126
+ expect(afterCancel.items).toHaveLength(0);
127
+ });
128
+ it('maps cancelling as the addressee (wrong side) to NOT_FOUND', async () => {
129
+ const { router } = build();
130
+ const requester = await seedPlayer();
131
+ const addressee = await seedPlayer();
132
+ const sent = await call(router.sendFriendRequest, { targetUserId: addressee.userId }, { context: ctxFor(requester.userId) });
133
+ const error = await call(router.cancelFriendRequest, { friendshipId: sent.id }, { context: ctxFor(addressee.userId) }).catch((e) => e);
134
+ expect(error).toBeInstanceOf(ORPCError);
135
+ expect(error.code).toBe('NOT_FOUND');
136
+ });
57
137
  });
58
138
  describe('social router listFriends', () => {
59
139
  it('returns the accepted, non-removed friends for the caller', async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"social.router.int.test.js","sourceRoot":"","sources":["../../../../src/engagement/social/__tests__/social.router.int.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"social.router.int.test.js","sourceRoot":"","sources":["../../../../src/engagement/social/__tests__/social.router.int.test.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ import { migrate as migrateProfile } from '@openora/core/pam/migrate/profile';
9
9
  import { makeEventBus, makeIdentityReader } from '../../../testing/mock.js';
10
10
  import { migrate } from '../migrate.js';
11
11
  import { friendship } from '../schema/index.js';
12
- import { SocialService, SelfFriendRequestError, FriendRequestTargetNotFoundError, FriendRequestUnavailableError, AlreadyFriendsError, RequestAlreadyPendingError, FriendRequestRefusedError, BlockedBySelfError, FriendshipNotFoundError, } from '../service/social.service.js';
12
+ import { SocialService, SelfFriendRequestError, FriendRequestTargetNotFoundError, FriendRequestUnavailableError, AlreadyFriendsError, RequestAlreadyPendingError, FriendRequestRefusedError, BlockedBySelfError, FriendshipNotFoundError, FriendRequestNotFoundError, } from '../service/social.service.js';
13
13
  let db;
14
14
  function realIdentityReader() {
15
15
  return {
@@ -184,6 +184,21 @@ describe('SocialService.getRelationships (real PG)', () => {
184
184
  { userId: other.userId, status: 'none', friendshipId: null, canSendRequest: true },
185
185
  ]);
186
186
  });
187
+ it('returns none + canSendRequest true for both sides after a decline (regression: previously stuck on refused/canSendRequest:false forever)', async () => {
188
+ const { svc } = makeService();
189
+ const requester = await seedPlayer();
190
+ const addressee = await seedPlayer();
191
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
192
+ await svc.declineFriendRequest(addressee.userId, request.id);
193
+ const fromRequester = await svc.getRelationships(requester.userId, [addressee.userId]);
194
+ const fromAddressee = await svc.getRelationships(addressee.userId, [requester.userId]);
195
+ expect(fromRequester).toEqual([
196
+ { userId: addressee.userId, status: 'none', friendshipId: null, canSendRequest: true },
197
+ ]);
198
+ expect(fromAddressee).toEqual([
199
+ { userId: requester.userId, status: 'none', friendshipId: null, canSendRequest: true },
200
+ ]);
201
+ });
187
202
  it('returns unavailable for a nonexistent user', async () => {
188
203
  const { svc } = makeService();
189
204
  const caller = await seedPlayer();
@@ -476,4 +491,324 @@ describe('SocialService.listFriends (real PG)', () => {
476
491
  expect(result.items.map((i) => i.userId)).toEqual([friend.userId]);
477
492
  });
478
493
  });
494
+ describe('SocialService.acceptFriendRequest (real PG)', () => {
495
+ it('accepts a pending incoming request and emits social.friend_request.accepted', async () => {
496
+ const { svc, events } = makeService();
497
+ const requester = await seedPlayer({ displayName: 'Alice' });
498
+ const addressee = await seedPlayer({ displayName: 'Bob' });
499
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
500
+ events.emit.mockClear();
501
+ const result = await svc.acceptFriendRequest(addressee.userId, request.id);
502
+ expect(result.id).toBe(request.id);
503
+ expect(result.acceptedAt).toEqual(expect.any(String));
504
+ expect(events.emit).toHaveBeenCalledWith('social.friend_request.accepted', {
505
+ friendshipId: request.id,
506
+ requesterId: requester.userId,
507
+ addresseeId: addressee.userId,
508
+ accepterId: addressee.userId,
509
+ accepterDisplayName: 'Bob',
510
+ });
511
+ const [row] = await db.drizzle.db
512
+ .select()
513
+ .from(friendship)
514
+ .where(eq(friendship.id, request.id));
515
+ expect(row?.acceptedAt).toBeInstanceOf(Date);
516
+ });
517
+ it('throws FriendRequestNotFoundError when the caller is not the addressee', async () => {
518
+ const { svc, events } = makeService();
519
+ const requester = await seedPlayer();
520
+ const addressee = await seedPlayer();
521
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
522
+ events.emit.mockClear();
523
+ // The requester (wrong side) tries to accept their own outgoing request.
524
+ await expect(svc.acceptFriendRequest(requester.userId, request.id)).rejects.toBeInstanceOf(FriendRequestNotFoundError);
525
+ expect(events.emit).not.toHaveBeenCalled();
526
+ });
527
+ it('throws FriendRequestNotFoundError on a nonexistent friendshipId', async () => {
528
+ const { svc } = makeService();
529
+ const addressee = await seedPlayer();
530
+ await expect(svc.acceptFriendRequest(addressee.userId, randomUUID())).rejects.toBeInstanceOf(FriendRequestNotFoundError);
531
+ });
532
+ it('throws FriendRequestNotFoundError on a double-accept', async () => {
533
+ const { svc, events } = makeService();
534
+ const requester = await seedPlayer();
535
+ const addressee = await seedPlayer();
536
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
537
+ await svc.acceptFriendRequest(addressee.userId, request.id);
538
+ events.emit.mockClear();
539
+ await expect(svc.acceptFriendRequest(addressee.userId, request.id)).rejects.toBeInstanceOf(FriendRequestNotFoundError);
540
+ expect(events.emit).not.toHaveBeenCalled();
541
+ });
542
+ it.each([
543
+ [
544
+ 'addressee blocked requester',
545
+ (requesterId, addresseeId) => seedBlock(addresseeId, requesterId),
546
+ ],
547
+ [
548
+ 'requester blocked addressee',
549
+ (requesterId, addresseeId) => seedBlock(requesterId, addresseeId),
550
+ ],
551
+ ])('throws FriendRequestUnavailableError when a block landed after the request was sent (%s)', async (_label, seedTheBlock) => {
552
+ const { svc, events } = makeService();
553
+ const requester = await seedPlayer();
554
+ const addressee = await seedPlayer();
555
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
556
+ await seedTheBlock(requester.userId, addressee.userId);
557
+ events.emit.mockClear();
558
+ await expect(svc.acceptFriendRequest(addressee.userId, request.id)).rejects.toBeInstanceOf(FriendRequestUnavailableError);
559
+ expect(events.emit).not.toHaveBeenCalled();
560
+ const [row] = await db.drizzle.db
561
+ .select()
562
+ .from(friendship)
563
+ .where(eq(friendship.id, request.id));
564
+ expect(row?.acceptedAt).toBeNull();
565
+ });
566
+ });
567
+ describe('SocialService.declineFriendRequest (real PG)', () => {
568
+ it('refuses a pending incoming request, emits social.friend_request.declined, and never emits a notification-triggering event', async () => {
569
+ const { svc, events } = makeService();
570
+ const requester = await seedPlayer();
571
+ const addressee = await seedPlayer();
572
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
573
+ events.emit.mockClear();
574
+ await svc.declineFriendRequest(addressee.userId, request.id);
575
+ expect(events.emit).toHaveBeenCalledWith('social.friend_request.declined', {
576
+ friendshipId: request.id,
577
+ requesterId: requester.userId,
578
+ addresseeId: addressee.userId,
579
+ });
580
+ expect(events.emit).not.toHaveBeenCalledWith('social.friend_request.accepted', expect.anything());
581
+ const [row] = await db.drizzle.db
582
+ .select()
583
+ .from(friendship)
584
+ .where(eq(friendship.id, request.id));
585
+ expect(row?.refusedAt).toBeNull();
586
+ expect(row?.removedAt).toBeInstanceOf(Date);
587
+ });
588
+ it('allows re-requesting the pair after a decline (regression: previously blocked forever)', async () => {
589
+ const { svc } = makeService();
590
+ const requester = await seedPlayer();
591
+ const addressee = await seedPlayer();
592
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
593
+ await svc.declineFriendRequest(addressee.userId, request.id);
594
+ const resent = await svc.sendFriendRequest(requester.userId, addressee.userId);
595
+ expect(resent.id).not.toBe(request.id);
596
+ expect(resent.acceptedAt).toBeNull();
597
+ const rows = await db.drizzle.db.select().from(friendship);
598
+ expect(rows).toHaveLength(2);
599
+ });
600
+ it('throws FriendRequestNotFoundError when the caller is not the addressee', async () => {
601
+ const { svc } = makeService();
602
+ const requester = await seedPlayer();
603
+ const addressee = await seedPlayer();
604
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
605
+ await expect(svc.declineFriendRequest(requester.userId, request.id)).rejects.toBeInstanceOf(FriendRequestNotFoundError);
606
+ });
607
+ });
608
+ describe('SocialService.cancelFriendRequest (real PG)', () => {
609
+ it('soft-removes a pending outgoing request, emits social.friend_request.cancelled, and never emits a notification-triggering event', async () => {
610
+ const { svc, events } = makeService();
611
+ const requester = await seedPlayer();
612
+ const addressee = await seedPlayer();
613
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
614
+ events.emit.mockClear();
615
+ await svc.cancelFriendRequest(requester.userId, request.id);
616
+ expect(events.emit).toHaveBeenCalledWith('social.friend_request.cancelled', {
617
+ friendshipId: request.id,
618
+ requesterId: requester.userId,
619
+ addresseeId: addressee.userId,
620
+ });
621
+ expect(events.emit).not.toHaveBeenCalledWith('social.friend_request.accepted', expect.anything());
622
+ const [row] = await db.drizzle.db
623
+ .select()
624
+ .from(friendship)
625
+ .where(eq(friendship.id, request.id));
626
+ expect(row?.removedAt).toBeInstanceOf(Date);
627
+ expect(row?.refusedAt).toBeNull();
628
+ });
629
+ it('allows re-requesting the pair after a cancel (new behavior enabled by the constraint change)', async () => {
630
+ const { svc } = makeService();
631
+ const requester = await seedPlayer();
632
+ const addressee = await seedPlayer();
633
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
634
+ await svc.cancelFriendRequest(requester.userId, request.id);
635
+ const resent = await svc.sendFriendRequest(requester.userId, addressee.userId);
636
+ expect(resent.id).not.toBe(request.id);
637
+ expect(resent.acceptedAt).toBeNull();
638
+ const rows = await db.drizzle.db.select().from(friendship);
639
+ expect(rows).toHaveLength(2);
640
+ });
641
+ it('throws FriendRequestNotFoundError when the caller is not the requester', async () => {
642
+ const { svc } = makeService();
643
+ const requester = await seedPlayer();
644
+ const addressee = await seedPlayer();
645
+ const request = await svc.sendFriendRequest(requester.userId, addressee.userId);
646
+ await expect(svc.cancelFriendRequest(addressee.userId, request.id)).rejects.toBeInstanceOf(FriendRequestNotFoundError);
647
+ });
648
+ });
649
+ describe('SocialService.listFriendRequests (real PG)', () => {
650
+ it('lists incoming pending requests, newest first, with mutualFriendsCount', async () => {
651
+ const { svc } = makeService();
652
+ const caller = await seedPlayer({ displayName: 'Caller' });
653
+ const senderA = await seedPlayer({ displayName: 'SenderA' });
654
+ const senderB = await seedPlayer({ displayName: 'SenderB' });
655
+ await svc.sendFriendRequest(senderA.userId, caller.userId);
656
+ await svc.sendFriendRequest(senderB.userId, caller.userId);
657
+ const result = await svc.listFriendRequests(caller.userId, {
658
+ direction: 'incoming',
659
+ page: 1,
660
+ limit: 20,
661
+ });
662
+ expect(result.total).toBe(2);
663
+ // newest first: senderB requested after senderA.
664
+ expect(result.items.map((i) => i.userId)).toEqual([senderB.userId, senderA.userId]);
665
+ for (const item of result.items) {
666
+ expect(item.direction).toBe('incoming');
667
+ expect(item.mutualFriendsCount).toBe(0);
668
+ }
669
+ });
670
+ it('lists outgoing pending requests with a null mutualFriendsCount', async () => {
671
+ const { svc } = makeService();
672
+ const caller = await seedPlayer({ displayName: 'Caller' });
673
+ const target = await seedPlayer({ displayName: 'Target' });
674
+ await svc.sendFriendRequest(caller.userId, target.userId);
675
+ const result = await svc.listFriendRequests(caller.userId, {
676
+ direction: 'outgoing',
677
+ page: 1,
678
+ limit: 20,
679
+ });
680
+ expect(result.total).toBe(1);
681
+ expect(result.items[0]).toMatchObject({
682
+ userId: target.userId,
683
+ displayName: 'Target',
684
+ direction: 'outgoing',
685
+ mutualFriendsCount: null,
686
+ });
687
+ });
688
+ it('excludes accepted, refused, and removed rows', async () => {
689
+ const { svc } = makeService();
690
+ const caller = await seedPlayer();
691
+ const accepted = await seedPlayer();
692
+ const refused = await seedPlayer();
693
+ const cancelled = await seedPlayer();
694
+ const pending = await seedPlayer({ displayName: 'StillPending' });
695
+ await makeFriends(svc, caller.userId, accepted.userId);
696
+ const refusedReq = await svc.sendFriendRequest(refused.userId, caller.userId);
697
+ await svc.declineFriendRequest(caller.userId, refusedReq.id);
698
+ const cancelledReq = await svc.sendFriendRequest(caller.userId, cancelled.userId);
699
+ await svc.cancelFriendRequest(caller.userId, cancelledReq.id);
700
+ await svc.sendFriendRequest(pending.userId, caller.userId);
701
+ const incoming = await svc.listFriendRequests(caller.userId, {
702
+ direction: 'incoming',
703
+ page: 1,
704
+ limit: 20,
705
+ });
706
+ expect(incoming.total).toBe(1);
707
+ expect(incoming.items[0]?.userId).toBe(pending.userId);
708
+ });
709
+ it.each(['suspended', 'closed'])('drops a pending sender whose account is %s', async (status) => {
710
+ const { svc } = makeService();
711
+ const caller = await seedPlayer();
712
+ const sender = await seedPlayer({ displayName: 'Sender' });
713
+ const unavailableSender = await seedPlayer({ displayName: 'Unavailable' });
714
+ await svc.sendFriendRequest(sender.userId, caller.userId);
715
+ await svc.sendFriendRequest(unavailableSender.userId, caller.userId);
716
+ await db.drizzle.db
717
+ .update(player)
718
+ .set({ status })
719
+ .where(eq(player.userId, unavailableSender.userId));
720
+ const result = await svc.listFriendRequests(caller.userId, {
721
+ direction: 'incoming',
722
+ page: 1,
723
+ limit: 20,
724
+ });
725
+ expect(result.items.map((i) => i.userId)).toEqual([sender.userId]);
726
+ });
727
+ it.each([
728
+ [
729
+ 'caller blocked the sender',
730
+ (callerId, senderId) => seedBlock(callerId, senderId),
731
+ ],
732
+ [
733
+ 'sender blocked the caller',
734
+ (callerId, senderId) => seedBlock(senderId, callerId),
735
+ ],
736
+ ])('drops an incoming pending sender who is blocked (%s)', async (_label, seedTheBlock) => {
737
+ const { svc } = makeService();
738
+ const caller = await seedPlayer();
739
+ const sender = await seedPlayer({ displayName: 'Sender' });
740
+ const blockedSender = await seedPlayer({ displayName: 'Blocked' });
741
+ await svc.sendFriendRequest(sender.userId, caller.userId);
742
+ await svc.sendFriendRequest(blockedSender.userId, caller.userId);
743
+ await seedTheBlock(caller.userId, blockedSender.userId);
744
+ const result = await svc.listFriendRequests(caller.userId, {
745
+ direction: 'incoming',
746
+ page: 1,
747
+ limit: 20,
748
+ });
749
+ expect(result.items.map((i) => i.userId)).toEqual([sender.userId]);
750
+ });
751
+ it('drops an outgoing pending target who is blocked', async () => {
752
+ const { svc } = makeService();
753
+ const caller = await seedPlayer();
754
+ const target = await seedPlayer({ displayName: 'Target' });
755
+ await svc.sendFriendRequest(caller.userId, target.userId);
756
+ await seedBlock(target.userId, caller.userId);
757
+ const result = await svc.listFriendRequests(caller.userId, {
758
+ direction: 'outgoing',
759
+ page: 1,
760
+ limit: 20,
761
+ });
762
+ expect(result.items).toEqual([]);
763
+ });
764
+ it('paginates results', async () => {
765
+ const { svc } = makeService();
766
+ const caller = await seedPlayer();
767
+ for (let i = 0; i < 3; i++) {
768
+ const sender = await seedPlayer({ displayName: `Sender${i}` });
769
+ await svc.sendFriendRequest(sender.userId, caller.userId);
770
+ }
771
+ const page1 = await svc.listFriendRequests(caller.userId, {
772
+ direction: 'incoming',
773
+ page: 1,
774
+ limit: 2,
775
+ });
776
+ const page2 = await svc.listFriendRequests(caller.userId, {
777
+ direction: 'incoming',
778
+ page: 2,
779
+ limit: 2,
780
+ });
781
+ expect(page1.total).toBe(3);
782
+ expect(page1.items).toHaveLength(2);
783
+ expect(page2.items).toHaveLength(1);
784
+ });
785
+ it('computes mutualFriendsCount via one batched query across exactly 2 shared accepted friends', async () => {
786
+ const { svc } = makeService();
787
+ const caller = await seedPlayer({ displayName: 'Caller' });
788
+ const requester = await seedPlayer({ displayName: 'Requester' });
789
+ const mutualA = await seedPlayer({ displayName: 'MutualA' });
790
+ const mutualB = await seedPlayer({ displayName: 'MutualB' });
791
+ const callerOnlyFriend = await seedPlayer({ displayName: 'CallerOnlyFriend' });
792
+ const requesterOnlyFriend = await seedPlayer({ displayName: 'RequesterOnlyFriend' });
793
+ // Shared friends: caller <-> mutualA/mutualB, requester <-> mutualA/mutualB.
794
+ await makeFriends(svc, caller.userId, mutualA.userId);
795
+ await makeFriends(svc, caller.userId, mutualB.userId);
796
+ await makeFriends(svc, requester.userId, mutualA.userId);
797
+ await makeFriends(svc, requester.userId, mutualB.userId);
798
+ // Non-shared friends on each side - must not inflate the count.
799
+ await makeFriends(svc, caller.userId, callerOnlyFriend.userId);
800
+ await makeFriends(svc, requester.userId, requesterOnlyFriend.userId);
801
+ await svc.sendFriendRequest(requester.userId, caller.userId);
802
+ const result = await svc.listFriendRequests(caller.userId, {
803
+ direction: 'incoming',
804
+ page: 1,
805
+ limit: 20,
806
+ });
807
+ expect(result.items).toHaveLength(1);
808
+ expect(result.items[0]).toMatchObject({
809
+ userId: requester.userId,
810
+ mutualFriendsCount: 2,
811
+ });
812
+ });
813
+ });
479
814
  //# sourceMappingURL=social.service.int.test.js.map