This repository has no description
1import { ICardPublisher } from '../../application/ports/ICardPublisher';
2import { Card } from '../../domain/Card';
3import { PublishedRecordId } from '../../domain/value-objects/PublishedRecordId';
4import { ok, err, Result } from '../../../../shared/core/Result';
5import { UseCaseError } from '../../../../shared/core/UseCaseError';
6import { AppError } from '../../../../shared/core/AppError';
7import { CuratorId } from 'src/modules/cards/domain/value-objects/CuratorId';
8import { EnvironmentConfigService } from 'src/shared/infrastructure/config/EnvironmentConfigService';
9
10export class FakeCardPublisher implements ICardPublisher {
11 private publishedRecords: Map<string, Card> = new Map();
12 private shouldFail: boolean = false;
13 private shouldFailUnpublish: boolean = false;
14 private unpublishedRecords: Array<{
15 cardId: string;
16 uri: string;
17 cid: string;
18 }> = [];
19 private cardType = new EnvironmentConfigService().getAtProtoCollections()
20 .card;
21
22 async publishCardToLibrary(
23 card: Card,
24 curatorId: CuratorId,
25 parentCardPublishedRecordId?: PublishedRecordId,
26 ): Promise<Result<PublishedRecordId, UseCaseError>> {
27 if (this.shouldFail) {
28 return err(
29 AppError.UnexpectedError.create(new Error('Simulated publish failure')),
30 );
31 }
32
33 const cardId = card.cardId.getStringValue();
34 // Simulate generating an AT URI based on curator DID and collection/rkey
35 const fakeUri = `at://${curatorId.value}/${this.cardType}/${cardId}`;
36 const fakeCid = `fake-cid-${cardId}`;
37 const publishedRecordId = PublishedRecordId.create({
38 uri: fakeUri,
39 cid: fakeCid,
40 });
41
42 // Store the published card for inspection using composite key
43 const compositeKey = fakeUri + fakeCid;
44 this.publishedRecords.set(compositeKey, card);
45
46 console.log(
47 `[FakeCardPublisher] Published card ${cardId} to curator ${curatorId.value} library at ${fakeUri}`,
48 );
49 return ok(publishedRecordId);
50 }
51
52 async unpublishCardFromLibrary(
53 recordId: PublishedRecordId,
54 curatorId: CuratorId,
55 ): Promise<Result<void, UseCaseError>> {
56 if (this.shouldFailUnpublish) {
57 return err(
58 AppError.UnexpectedError.create(
59 new Error('Simulated unpublish failure'),
60 ),
61 );
62 }
63
64 const compositeKey = recordId.uri + recordId.cid;
65 let card: Card | undefined;
66 if (this.publishedRecords.has(compositeKey)) {
67 card = this.publishedRecords.get(compositeKey);
68 this.publishedRecords.delete(compositeKey);
69 console.log(
70 `[FakeCardPublisher] Unpublished record ${recordId.uri} from curator ${curatorId.value} library`,
71 );
72 }
73 this.unpublishedRecords.push({
74 cardId: card?.cardId.getStringValue() || '',
75 uri: recordId.uri,
76 cid: recordId.cid,
77 });
78 return ok(undefined);
79 }
80
81 setShouldFail(shouldFail: boolean): void {
82 this.shouldFail = shouldFail;
83 }
84
85 setShouldFailUnpublish(shouldFailUnpublish: boolean): void {
86 this.shouldFailUnpublish = shouldFailUnpublish;
87 }
88
89 clear(): void {
90 this.publishedRecords.clear();
91 this.shouldFail = false;
92 this.shouldFailUnpublish = false;
93 }
94
95 getPublishedCards(): Card[] {
96 return Array.from(this.publishedRecords.values());
97 }
98
99 getUnpublishedCards(): Array<{ cardId: string; uri: string; cid: string }> {
100 // For testing purposes, track unpublished cards
101 // This is a simplified implementation for test verification
102 return this.unpublishedRecords;
103 }
104}