This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

in mem connection repo

+204 -5
+4
src/modules/atproto/tests/application/ProcessCardFirehoseEventUseCase.test.ts
··· 5 5 import { RemoveCardFromLibraryUseCase } from '../../../cards/application/useCases/commands/RemoveCardFromLibraryUseCase'; 6 6 import { InMemoryCardRepository } from '../../../cards/tests/utils/InMemoryCardRepository'; 7 7 import { InMemoryCollectionRepository } from '../../../cards/tests/utils/InMemoryCollectionRepository'; 8 + import { InMemoryConnectionRepository } from '../../../cards/tests/utils/InMemoryConnectionRepository'; 8 9 import { FakeCardPublisher } from '../../../cards/tests/utils/FakeCardPublisher'; 9 10 import { FakeCollectionPublisher } from '../../../cards/tests/utils/FakeCollectionPublisher'; 10 11 import { FakeMetadataService } from '../../../cards/tests/utils/FakeMetadataService'; ··· 26 27 let removeCardFromLibraryUseCase: RemoveCardFromLibraryUseCase; 27 28 let cardRepository: InMemoryCardRepository; 28 29 let collectionRepository: InMemoryCollectionRepository; 30 + let connectionRepository: InMemoryConnectionRepository; 29 31 let cardPublisher: FakeCardPublisher; 30 32 let collectionPublisher: FakeCollectionPublisher; 31 33 let metadataService: FakeMetadataService; ··· 39 41 configService = new EnvironmentConfigService(); 40 42 cardRepository = InMemoryCardRepository.getInstance(); 41 43 collectionRepository = InMemoryCollectionRepository.getInstance(); 44 + connectionRepository = InMemoryConnectionRepository.getInstance(); 42 45 cardPublisher = new FakeCardPublisher(); 43 46 collectionPublisher = new FakeCollectionPublisher(); 44 47 metadataService = new FakeMetadataService(); ··· 59 62 atUriResolutionService = new InMemoryAtUriResolutionService( 60 63 collectionRepository, 61 64 cardRepository, 65 + connectionRepository, 62 66 ); 63 67 64 68 addUrlToLibraryUseCase = new AddUrlToLibraryUseCase(
+4
src/modules/atproto/tests/application/ProcessCollectionFirehoseEventUseCase.test.ts
··· 4 4 import { UpdateCollectionUseCase } from '../../../cards/application/useCases/commands/UpdateCollectionUseCase'; 5 5 import { DeleteCollectionUseCase } from '../../../cards/application/useCases/commands/DeleteCollectionUseCase'; 6 6 import { InMemoryCollectionRepository } from '../../../cards/tests/utils/InMemoryCollectionRepository'; 7 + import { InMemoryConnectionRepository } from '../../../cards/tests/utils/InMemoryConnectionRepository'; 7 8 import { FakeCollectionPublisher } from '../../../cards/tests/utils/FakeCollectionPublisher'; 8 9 import { CollectionBuilder } from '../../../cards/tests/utils/builders/CollectionBuilder'; 9 10 import { CuratorId } from '../../../cards/domain/value-objects/CuratorId'; ··· 20 21 let deleteCollectionUseCase: DeleteCollectionUseCase; 21 22 let collectionRepository: InMemoryCollectionRepository; 22 23 let cardRepository: InMemoryCardRepository; 24 + let connectionRepository: InMemoryConnectionRepository; 23 25 let collectionPublisher: FakeCollectionPublisher; 24 26 let curatorId: CuratorId; 25 27 let configService: EnvironmentConfigService; ··· 28 30 configService = new EnvironmentConfigService(); 29 31 collectionRepository = InMemoryCollectionRepository.getInstance(); 30 32 cardRepository = InMemoryCardRepository.getInstance(); 33 + connectionRepository = InMemoryConnectionRepository.getInstance(); 31 34 collectionPublisher = new FakeCollectionPublisher(); 32 35 33 36 atUriResolutionService = new InMemoryAtUriResolutionService( 34 37 collectionRepository, 35 38 cardRepository, 39 + connectionRepository, 36 40 ); 37 41 38 42 createCollectionUseCase = new CreateCollectionUseCase(
+4
src/modules/atproto/tests/application/ProcessCollectionLinkFirehoseEventUseCase.test.ts
··· 3 3 import { UpdateUrlCardAssociationsUseCase } from '../../../cards/application/useCases/commands/UpdateUrlCardAssociationsUseCase'; 4 4 import { InMemoryCardRepository } from '../../../cards/tests/utils/InMemoryCardRepository'; 5 5 import { InMemoryCollectionRepository } from '../../../cards/tests/utils/InMemoryCollectionRepository'; 6 + import { InMemoryConnectionRepository } from '../../../cards/tests/utils/InMemoryConnectionRepository'; 6 7 import { FakeCardPublisher } from '../../../cards/tests/utils/FakeCardPublisher'; 7 8 import { FakeCollectionPublisher } from '../../../cards/tests/utils/FakeCollectionPublisher'; 8 9 import { FakeEventPublisher } from '../../../cards/tests/utils/FakeEventPublisher'; ··· 23 24 let updateUrlCardAssociationsUseCase: UpdateUrlCardAssociationsUseCase; 24 25 let cardRepository: InMemoryCardRepository; 25 26 let collectionRepository: InMemoryCollectionRepository; 27 + let connectionRepository: InMemoryConnectionRepository; 26 28 let cardPublisher: FakeCardPublisher; 27 29 let collectionPublisher: FakeCollectionPublisher; 28 30 let eventPublisher: FakeEventPublisher; ··· 35 37 configService = new EnvironmentConfigService(); 36 38 cardRepository = InMemoryCardRepository.getInstance(); 37 39 collectionRepository = InMemoryCollectionRepository.getInstance(); 40 + connectionRepository = InMemoryConnectionRepository.getInstance(); 38 41 cardPublisher = new FakeCardPublisher(); 39 42 collectionPublisher = new FakeCollectionPublisher(); 40 43 eventPublisher = new FakeEventPublisher(); ··· 54 57 atUriResolutionService = new InMemoryAtUriResolutionService( 55 58 collectionRepository, 56 59 cardRepository, 60 + connectionRepository, 57 61 ); 58 62 59 63 updateUrlCardAssociationsUseCase = new UpdateUrlCardAssociationsUseCase(
+4
src/modules/atproto/tests/application/ProcessFirehoseEventUseCase.test.ts
··· 24 24 import { InMemoryCardRepository } from '../../../cards/tests/utils/InMemoryCardRepository'; 25 25 import { InMemoryCardQueryRepository } from '../../../cards/tests/utils/InMemoryCardQueryRepository'; 26 26 import { InMemoryCollectionRepository } from '../../../cards/tests/utils/InMemoryCollectionRepository'; 27 + import { InMemoryConnectionRepository } from '../../../cards/tests/utils/InMemoryConnectionRepository'; 27 28 import { FakeCardPublisher } from '../../../cards/tests/utils/FakeCardPublisher'; 28 29 import { FakeCollectionPublisher } from '../../../cards/tests/utils/FakeCollectionPublisher'; 29 30 import { FakeConnectionPublisher } from '../../../cards/tests/utils/FakeConnectionPublisher'; ··· 60 61 let cardRepository: InMemoryCardRepository; 61 62 let cardQueryRepository: InMemoryCardQueryRepository; 62 63 let collectionRepository: InMemoryCollectionRepository; 64 + let connectionRepository: InMemoryConnectionRepository; 63 65 let cardPublisher: FakeCardPublisher; 64 66 let collectionPublisher: FakeCollectionPublisher; 65 67 let metadataService: FakeMetadataService; ··· 90 92 // Set up all the real dependencies 91 93 cardRepository = InMemoryCardRepository.getInstance(); 92 94 collectionRepository = InMemoryCollectionRepository.getInstance(); 95 + connectionRepository = InMemoryConnectionRepository.getInstance(); 93 96 cardQueryRepository = new InMemoryCardQueryRepository( 94 97 cardRepository, 95 98 collectionRepository, ··· 114 117 atUriResolutionService = new InMemoryAtUriResolutionService( 115 118 collectionRepository, 116 119 cardRepository, 120 + connectionRepository, 117 121 ); 118 122 119 123 // Create use cases for card processing
+24 -3
src/modules/cards/tests/utils/InMemoryAtUriResolutionService.ts
··· 10 10 import { FollowTargetType } from '../../../user/domain/value-objects/FollowTargetType'; 11 11 import { InMemoryCollectionRepository } from './InMemoryCollectionRepository'; 12 12 import { InMemoryCardRepository } from './InMemoryCardRepository'; 13 + import { InMemoryConnectionRepository } from './InMemoryConnectionRepository'; 13 14 14 15 export class InMemoryAtUriResolutionService implements IAtUriResolutionService { 15 16 constructor( 16 17 private collectionRepository: InMemoryCollectionRepository, 17 18 private cardRepository: InMemoryCardRepository, 19 + private connectionRepository: InMemoryConnectionRepository, 18 20 ) {} 19 21 20 22 async resolveAtUri( ··· 53 55 }, 54 56 }); 55 57 } 58 + } 59 + } 60 + 61 + // Check connections 62 + const allConnections = this.connectionRepository.getAllConnections(); 63 + for (const connection of allConnections) { 64 + if (connection.publishedRecordId?.uri === atUri) { 65 + return ok({ 66 + type: AtUriResourceType.CONNECTION, 67 + id: connection.connectionId, 68 + }); 56 69 } 57 70 } 58 71 ··· 128 141 async resolveConnectionId( 129 142 atUri: string, 130 143 ): Promise<Result<ConnectionId | null>> { 131 - // For testing purposes, return null (connection not found) 132 - // TODO: When InMemoryConnectionRepository is created, search through connections 133 - return ok(null); 144 + const result = await this.resolveAtUri(atUri); 145 + 146 + if (result.isErr()) { 147 + return err(result.error); 148 + } 149 + 150 + if (!result.value || result.value.type !== AtUriResourceType.CONNECTION) { 151 + return ok(null); 152 + } 153 + 154 + return ok(result.value.id as ConnectionId); 134 155 } 135 156 }
+160
src/modules/cards/tests/utils/InMemoryConnectionRepository.ts
··· 1 + import { Result, ok, err } from '../../../../shared/core/Result'; 2 + import { IConnectionRepository } from '../../domain/IConnectionRepository'; 3 + import { Connection } from '../../domain/Connection'; 4 + import { ConnectionId } from '../../domain/value-objects/ConnectionId'; 5 + import { UrlOrCardId } from '../../domain/value-objects/UrlOrCardId'; 6 + import { CuratorId } from '../../domain/value-objects/CuratorId'; 7 + 8 + export class InMemoryConnectionRepository implements IConnectionRepository { 9 + private static instance: InMemoryConnectionRepository; 10 + private connections: Map<string, Connection> = new Map(); 11 + 12 + private constructor() {} 13 + 14 + public static getInstance(): InMemoryConnectionRepository { 15 + if (!InMemoryConnectionRepository.instance) { 16 + InMemoryConnectionRepository.instance = 17 + new InMemoryConnectionRepository(); 18 + } 19 + return InMemoryConnectionRepository.instance; 20 + } 21 + 22 + private clone(connection: Connection): Connection { 23 + const connectionResult = Connection.create( 24 + { 25 + curatorId: connection.curatorId, 26 + source: connection.source, 27 + target: connection.target, 28 + type: connection.type, 29 + note: connection.note, 30 + publishedRecordId: connection.publishedRecordId, 31 + createdAt: connection.createdAt, 32 + updatedAt: connection.updatedAt, 33 + }, 34 + connection.id, 35 + ); 36 + 37 + if (connectionResult.isErr()) { 38 + throw new Error( 39 + `Failed to clone connection: ${connectionResult.error.message}`, 40 + ); 41 + } 42 + 43 + return connectionResult.value; 44 + } 45 + 46 + async findById(id: ConnectionId): Promise<Result<Connection | null>> { 47 + try { 48 + const connection = this.connections.get(id.getStringValue()); 49 + return ok(connection ? this.clone(connection) : null); 50 + } catch (error) { 51 + return err(error as Error); 52 + } 53 + } 54 + 55 + async findByIds(ids: ConnectionId[]): Promise<Result<Connection[]>> { 56 + try { 57 + const connections: Connection[] = []; 58 + for (const id of ids) { 59 + const connection = this.connections.get(id.getStringValue()); 60 + if (connection) { 61 + connections.push(this.clone(connection)); 62 + } 63 + } 64 + return ok(connections); 65 + } catch (error) { 66 + return err(error as Error); 67 + } 68 + } 69 + 70 + async findByCuratorId(curatorId: CuratorId): Promise<Result<Connection[]>> { 71 + try { 72 + const connections = Array.from(this.connections.values()).filter( 73 + (connection) => connection.curatorId.value === curatorId.value, 74 + ); 75 + return ok(connections.map((connection) => this.clone(connection))); 76 + } catch (error) { 77 + return err(error as Error); 78 + } 79 + } 80 + 81 + async findBySource(source: UrlOrCardId): Promise<Result<Connection[]>> { 82 + try { 83 + const connections = Array.from(this.connections.values()).filter( 84 + (connection) => 85 + connection.source.type === source.type && 86 + connection.source.stringValue === source.stringValue, 87 + ); 88 + return ok(connections.map((connection) => this.clone(connection))); 89 + } catch (error) { 90 + return err(error as Error); 91 + } 92 + } 93 + 94 + async findByTarget(target: UrlOrCardId): Promise<Result<Connection[]>> { 95 + try { 96 + const connections = Array.from(this.connections.values()).filter( 97 + (connection) => 98 + connection.target.type === target.type && 99 + connection.target.stringValue === target.stringValue, 100 + ); 101 + return ok(connections.map((connection) => this.clone(connection))); 102 + } catch (error) { 103 + return err(error as Error); 104 + } 105 + } 106 + 107 + async findBetween( 108 + source: UrlOrCardId, 109 + target: UrlOrCardId, 110 + ): Promise<Result<Connection[]>> { 111 + try { 112 + const connections = Array.from(this.connections.values()).filter( 113 + (connection) => 114 + connection.source.type === source.type && 115 + connection.source.stringValue === source.stringValue && 116 + connection.target.type === target.type && 117 + connection.target.stringValue === target.stringValue, 118 + ); 119 + return ok(connections.map((connection) => this.clone(connection))); 120 + } catch (error) { 121 + return err(error as Error); 122 + } 123 + } 124 + 125 + async save(connection: Connection): Promise<Result<void>> { 126 + try { 127 + this.connections.set( 128 + connection.connectionId.getStringValue(), 129 + this.clone(connection), 130 + ); 131 + return ok(undefined); 132 + } catch (error) { 133 + return err(error as Error); 134 + } 135 + } 136 + 137 + async delete(connectionId: ConnectionId): Promise<Result<void>> { 138 + try { 139 + this.connections.delete(connectionId.getStringValue()); 140 + return ok(undefined); 141 + } catch (error) { 142 + return err(error as Error); 143 + } 144 + } 145 + 146 + // Helper methods for testing 147 + public clear(): void { 148 + this.connections.clear(); 149 + } 150 + 151 + public getStoredConnection(id: ConnectionId): Connection | undefined { 152 + return this.connections.get(id.getStringValue()); 153 + } 154 + 155 + public getAllConnections(): Connection[] { 156 + return Array.from(this.connections.values()).map((connection) => 157 + this.clone(connection), 158 + ); 159 + } 160 + }
+4 -2
src/shared/infrastructure/http/factories/RepositoryFactory.ts
··· 13 13 import { InMemoryCardQueryRepository } from '../../../../modules/cards/tests/utils/InMemoryCardQueryRepository'; 14 14 import { InMemoryCollectionRepository } from '../../../../modules/cards/tests/utils/InMemoryCollectionRepository'; 15 15 import { InMemoryCollectionQueryRepository } from '../../../../modules/cards/tests/utils/InMemoryCollectionQueryRepository'; 16 + import { InMemoryConnectionRepository } from '../../../../modules/cards/tests/utils/InMemoryConnectionRepository'; 16 17 import { InMemoryUserRepository } from '../../../../modules/user/tests/infrastructure/InMemoryUserRepository'; 17 18 import { InMemoryTokenRepository } from '../../../../modules/user/tests/infrastructure/InMemoryTokenRepository'; 18 19 import { InMemoryAppPasswordSessionRepository } from '../../../../modules/atproto/tests/infrastructure/InMemoryAppPasswordSessionRepository'; ··· 76 77 const tokenRepository = InMemoryTokenRepository.getInstance(); 77 78 const cardRepository = InMemoryCardRepository.getInstance(); 78 79 const collectionRepository = InMemoryCollectionRepository.getInstance(); 80 + const connectionRepository = InMemoryConnectionRepository.getInstance(); 79 81 const cardQueryRepository = new InMemoryCardQueryRepository( 80 82 cardRepository, 81 83 collectionRepository, ··· 91 93 const atUriResolutionService = new InMemoryAtUriResolutionService( 92 94 collectionRepository, 93 95 cardRepository, 96 + connectionRepository, 94 97 ); 95 98 const notificationRepository = 96 99 InMemoryNotificationRepository.getInstance(); ··· 107 110 cardQueryRepository, 108 111 collectionRepository, 109 112 collectionQueryRepository, 110 - // TODO: Create InMemoryConnectionRepository 111 - connectionRepository: null as any, 113 + connectionRepository, 112 114 appPasswordSessionRepository, 113 115 feedRepository, 114 116 followsRepository,