185 lines
5.5 KiB
TypeScript
185 lines
5.5 KiB
TypeScript
import type { NotificationService } from '@core/notifications/application/ports/NotificationService';
|
|
import type { IWalletRepository } from '@core/payments/domain/repositories/IWalletRepository';
|
|
import type { Logger } from '@core/shared/application';
|
|
import { beforeEach, describe, expect, it, Mock, vi } from 'vitest';
|
|
import { LeagueWallet } from '../../domain/entities/league-wallet/LeagueWallet';
|
|
import { Season } from '../../domain/entities/season/Season';
|
|
import { SponsorshipRequest } from '../../domain/entities/SponsorshipRequest';
|
|
import type { ILeagueWalletRepository } from '../../domain/repositories/ILeagueWalletRepository';
|
|
import type { ISeasonRepository } from '../../domain/repositories/ISeasonRepository';
|
|
import type { ISeasonSponsorshipRepository } from '../../domain/repositories/ISeasonSponsorshipRepository';
|
|
import type { ISponsorshipRequestRepository } from '../../domain/repositories/ISponsorshipRequestRepository';
|
|
import { Money } from '../../domain/value-objects/Money';
|
|
import { AcceptSponsorshipRequestUseCase } from './AcceptSponsorshipRequestUseCase';
|
|
|
|
describe('AcceptSponsorshipRequestUseCase', () => {
|
|
let mockSponsorshipRequestRepo: {
|
|
findById: Mock;
|
|
update: Mock;
|
|
};
|
|
let mockSeasonSponsorshipRepo: {
|
|
create: Mock;
|
|
};
|
|
let mockSeasonRepo: {
|
|
findById: Mock;
|
|
};
|
|
let mockNotificationService: {
|
|
sendNotification: Mock;
|
|
};
|
|
let processPayment: Mock;
|
|
let mockWalletRepo: {
|
|
findById: Mock;
|
|
update: Mock;
|
|
};
|
|
let mockLeagueWalletRepo: {
|
|
findById: Mock;
|
|
update: Mock;
|
|
};
|
|
let mockLogger: {
|
|
debug: Mock;
|
|
info: Mock;
|
|
warn: Mock;
|
|
error: Mock;
|
|
};
|
|
|
|
beforeEach(() => {
|
|
mockSponsorshipRequestRepo = {
|
|
findById: vi.fn(),
|
|
update: vi.fn(),
|
|
};
|
|
mockSeasonSponsorshipRepo = {
|
|
create: vi.fn(),
|
|
};
|
|
mockSeasonRepo = {
|
|
findById: vi.fn(),
|
|
};
|
|
mockNotificationService = {
|
|
sendNotification: vi.fn(),
|
|
};
|
|
processPayment = vi.fn();
|
|
mockWalletRepo = {
|
|
findById: vi.fn(),
|
|
update: vi.fn(),
|
|
};
|
|
mockLeagueWalletRepo = {
|
|
findById: vi.fn(),
|
|
update: vi.fn(),
|
|
};
|
|
mockLogger = {
|
|
debug: vi.fn(),
|
|
info: vi.fn(),
|
|
warn: vi.fn(),
|
|
error: vi.fn(),
|
|
};
|
|
});
|
|
|
|
it('should send notification to sponsor, process payment, update wallets, and present result when accepting season sponsorship', async () => {
|
|
const output = {
|
|
present: vi.fn(),
|
|
};
|
|
|
|
const useCase = new AcceptSponsorshipRequestUseCase(
|
|
mockSponsorshipRequestRepo as unknown as ISponsorshipRequestRepository,
|
|
mockSeasonSponsorshipRepo as unknown as ISeasonSponsorshipRepository,
|
|
mockSeasonRepo as unknown as ISeasonRepository,
|
|
mockNotificationService as unknown as NotificationService,
|
|
processPayment,
|
|
mockWalletRepo as unknown as IWalletRepository,
|
|
mockLeagueWalletRepo as unknown as ILeagueWalletRepository,
|
|
mockLogger as unknown as Logger,
|
|
output,
|
|
);
|
|
|
|
const request = SponsorshipRequest.create({
|
|
id: 'req1',
|
|
sponsorId: 'sponsor1',
|
|
entityId: 'season1',
|
|
entityType: 'season',
|
|
tier: 'main',
|
|
offeredAmount: Money.create(1000),
|
|
status: 'pending',
|
|
});
|
|
|
|
const season = Season.create({
|
|
id: 'season1',
|
|
leagueId: 'league1',
|
|
gameId: 'game1',
|
|
name: 'Season 1',
|
|
startDate: new Date(),
|
|
endDate: new Date(),
|
|
});
|
|
|
|
mockSponsorshipRequestRepo.findById.mockResolvedValue(request);
|
|
mockSeasonRepo.findById.mockResolvedValue(season);
|
|
mockNotificationService.sendNotification.mockResolvedValue(undefined);
|
|
processPayment.mockResolvedValue({
|
|
success: true,
|
|
transactionId: 'txn1',
|
|
timestamp: new Date(),
|
|
});
|
|
mockWalletRepo.findById.mockResolvedValue({
|
|
id: 'sponsor1',
|
|
leagueId: 'league1',
|
|
balance: 2000,
|
|
totalRevenue: 0,
|
|
totalPlatformFees: 0,
|
|
totalWithdrawn: 0,
|
|
currency: 'USD',
|
|
createdAt: new Date(),
|
|
});
|
|
const leagueWallet = LeagueWallet.create({
|
|
id: 'league1',
|
|
leagueId: 'league1',
|
|
balance: Money.create(500),
|
|
});
|
|
mockLeagueWalletRepo.findById.mockResolvedValue(leagueWallet);
|
|
|
|
const result = await useCase.execute({
|
|
requestId: 'req1',
|
|
respondedBy: 'driver1',
|
|
});
|
|
|
|
expect(result.isOk()).toBe(true);
|
|
expect(result.unwrap()).toBeUndefined();
|
|
|
|
expect(mockNotificationService.sendNotification).toHaveBeenCalledWith({
|
|
recipientId: 'sponsor1',
|
|
type: 'sponsorship_request_accepted',
|
|
title: 'Sponsorship Accepted',
|
|
body: 'Your sponsorship request for Season 1 has been accepted.',
|
|
channel: 'in_app',
|
|
urgency: 'toast',
|
|
data: {
|
|
requestId: 'req1',
|
|
sponsorshipId: expect.any(String),
|
|
},
|
|
});
|
|
expect(processPayment).toHaveBeenCalledWith({
|
|
amount: 1000,
|
|
payerId: 'sponsor1',
|
|
description: 'Sponsorship payment for season season1',
|
|
metadata: { requestId: 'req1' },
|
|
});
|
|
expect(mockWalletRepo.update).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
id: 'sponsor1',
|
|
balance: 1000,
|
|
}),
|
|
);
|
|
expect(mockLeagueWalletRepo.update).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
id: 'league1',
|
|
balance: expect.objectContaining({ amount: 1400 }),
|
|
}),
|
|
);
|
|
|
|
expect(output.present).toHaveBeenCalledWith({
|
|
requestId: 'req1',
|
|
sponsorshipId: expect.any(String),
|
|
status: 'accepted',
|
|
acceptedAt: expect.any(Date),
|
|
platformFee: expect.any(Number),
|
|
netAmount: expect.any(Number),
|
|
});
|
|
});
|
|
}); |