Skip to content

Commit

Permalink
test: Upsert Friendship tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinszuchet committed Jan 13, 2025
1 parent cce1500 commit 855f8eb
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/logic/friendships.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type CommonParsedRequest<A extends Action> = {
user: string
}

type ParsedUpsertFriendshipRequest =
export type ParsedUpsertFriendshipRequest =
| (CommonParsedRequest<Action.REQUEST> & { metadata: { message: string } | null })
| CommonParsedRequest<Action.ACCEPT>
| CommonParsedRequest<Action.CANCEL>
Expand Down
1 change: 1 addition & 0 deletions test/mocks/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './logs'
export * from './db'
export * from './pubsub'
2 changes: 2 additions & 0 deletions test/mocks/components/logs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { IMetricsComponent } from '@well-known-components/interfaces'
import { ILoggerComponent } from '@well-known-components/interfaces/dist/components/logger'
import { createLogComponent } from '@well-known-components/logger'

export const mockLogs: jest.Mocked<ILoggerComponent> = {
getLogger: jest.fn().mockReturnValue({
Expand Down
8 changes: 8 additions & 0 deletions test/mocks/components/pubsub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { IPubSubComponent } from '../../../src/adapters/pubsub'

export const mockPubSub: jest.Mocked<IPubSubComponent> = {
start: jest.fn(),
stop: jest.fn(),
subscribeToFriendshipUpdates: jest.fn(),
publishFriendshipUpdate: jest.fn()
}
154 changes: 154 additions & 0 deletions test/unit/logic/adapters/rpc-server/services/upsert-friendship.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { mockDb, mockLogs, mockPubSub } from '../../../../../mocks/components'
import { upsertFriendshipService } from '../../../../../../src/adapters/rpc-server/services/upsert-friendship'
import { Action, FriendshipStatus, RpcServerContext, AppComponents } from '../../../../../../src/types'
import * as FriendshipsLogic from '../../../../../../src/logic/friendships'
import {
UpsertFriendshipPayload,
UpsertFriendshipResponse
} from '@dcl/protocol/out-ts/decentraland/social_service_v2/social_service.gen'
import { ParsedUpsertFriendshipRequest } from '../../../../../../src/logic/friendships'

jest.mock('../../../../../../src/logic/friendships')

describe('upsertFriendshipService', () => {
let components: jest.Mocked<Pick<AppComponents, 'db' | 'logs' | 'pubsub'>>
let upsertFriendship: ReturnType<typeof upsertFriendshipService>

const rpcContext: RpcServerContext = { address: '0x123', subscribers: undefined }
const userAddress = '0x456'
const message = 'Hello'

const mockRequest: UpsertFriendshipPayload = {
action: {
$case: 'request',
request: { user: { address: userAddress }, message }
}
}

const mockParsedRequest: ParsedUpsertFriendshipRequest = {
action: Action.REQUEST,
user: userAddress,
metadata: { message }
}

const existingFriendship = {
id: 'friendship-id',
status: FriendshipStatus.Requested,
address_requester: rpcContext.address,
address_requested: userAddress,
is_active: true,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString()
}

const lastFriendshipAction = {
id: 'action-id',
friendship_id: 'friendship-id',
acting_user: rpcContext.address,
action: Action.REQUEST,
timestamp: Date.now().toString()
}

beforeEach(() => {
components = { db: mockDb, logs: mockLogs, pubsub: mockPubSub }
upsertFriendship = upsertFriendshipService({ components })

jest.clearAllMocks()
mockDb.executeTx.mockImplementation(async (cb) => await cb({} as any))
})

it('should return an internalServerError for an invalid request', async () => {
jest.spyOn(FriendshipsLogic, 'parseUpsertFriendshipRequest').mockReturnValueOnce(undefined)

const result: UpsertFriendshipResponse = await upsertFriendship(mockRequest, rpcContext)

expect(result).toEqual({
response: {
$case: 'internalServerError',
internalServerError: {}
}
})
})

it('should return invalidFriendshipAction for an invalid action', async () => {
jest.spyOn(FriendshipsLogic, 'parseUpsertFriendshipRequest').mockReturnValueOnce(mockParsedRequest)
jest.spyOn(FriendshipsLogic, 'validateNewFriendshipAction').mockReturnValueOnce(false)

const result: UpsertFriendshipResponse = await upsertFriendship(mockRequest, rpcContext)

expect(result).toEqual({
response: {
$case: 'invalidFriendshipAction',
invalidFriendshipAction: {}
}
})
})

it('should update an existing friendship', async () => {
jest.spyOn(FriendshipsLogic, 'parseUpsertFriendshipRequest').mockReturnValueOnce(mockParsedRequest)
jest.spyOn(FriendshipsLogic, 'validateNewFriendshipAction').mockReturnValueOnce(true)
jest.spyOn(FriendshipsLogic, 'getNewFriendshipStatus').mockReturnValueOnce(FriendshipStatus.Friends)

mockDb.getFriendship.mockResolvedValueOnce(existingFriendship)
mockDb.getLastFriendshipAction.mockResolvedValueOnce(lastFriendshipAction)

const result: UpsertFriendshipResponse = await upsertFriendship(mockRequest, rpcContext)

expect(mockDb.updateFriendshipStatus).toHaveBeenCalledWith(existingFriendship.id, true, expect.anything())
expect(mockDb.recordFriendshipAction).toHaveBeenCalledWith(
existingFriendship.id,
rpcContext.address,
mockParsedRequest.action,
mockParsedRequest.metadata,
expect.anything()
)
expect(result).toEqual({
response: {
$case: 'accepted',
accepted: {}
}
})
})

it('should create a new friendship', async () => {
jest.spyOn(FriendshipsLogic, 'parseUpsertFriendshipRequest').mockReturnValueOnce(mockParsedRequest)
jest.spyOn(FriendshipsLogic, 'validateNewFriendshipAction').mockReturnValueOnce(true)
jest.spyOn(FriendshipsLogic, 'getNewFriendshipStatus').mockReturnValueOnce(FriendshipStatus.Requested)

mockDb.getFriendship.mockResolvedValueOnce(null)
mockDb.createFriendship.mockResolvedValueOnce('new-friendship-id')

const result: UpsertFriendshipResponse = await upsertFriendship(mockRequest, rpcContext)

expect(mockDb.createFriendship).toHaveBeenCalledWith([rpcContext.address, userAddress], false, expect.anything())
expect(mockDb.recordFriendshipAction).toHaveBeenCalledWith(
'new-friendship-id',
rpcContext.address,
mockParsedRequest.action,
mockParsedRequest.metadata,
expect.anything()
)
expect(result).toEqual({
response: {
$case: 'accepted',
accepted: {}
}
})
})

it('should handle errors gracefully', async () => {
jest.spyOn(FriendshipsLogic, 'parseUpsertFriendshipRequest').mockReturnValueOnce(mockParsedRequest)
mockDb.getFriendship.mockImplementationOnce(() => {
throw new Error('Database error')
})

const result: UpsertFriendshipResponse = await upsertFriendship(mockRequest, rpcContext)

expect(result).toEqual({
response: {
$case: 'internalServerError',
internalServerError: {}
}
})
})
})

0 comments on commit 855f8eb

Please sign in to comment.