plugin-voting/__tests__/repositories/CampaignRepository.test.js
2025-11-03 14:01:07 +02:00

208 lines
7 KiB
JavaScript

/**
* Campaign Repository Tests
*
* Tests for CampaignRepository database operations
* Uses REAL PostgreSQL database - NO mocks
*/
const { CampaignRepository } = require('../../repositories');
const VotingTestHelper = require('../helpers/testHelper');
describe('CampaignRepository', () => {
let campaignRepo;
let testHelper;
let testSite;
let testUserId;
beforeAll(async () => {
campaignRepo = new CampaignRepository();
testHelper = new VotingTestHelper();
testSite = await testHelper.createTestSite();
const testUser = await testHelper.createTestUser(testSite.id);
testUserId = testUser.id;
});
afterAll(async () => {
// Cleanup handled by global schema manager
});
describe('create', () => {
it('should create a new campaign', async () => {
const formData = await testHelper.createTestForm(testSite.id);
const campaignData = {
site_id: testSite.id,
title: 'Board Elections 2025',
description: 'Annual board elections',
campaign_type: 'board_election',
form_id: formData.id,
status: 'draft',
overall_sharing_results: 'detailed',
public_access: 'restrict',
start_date: new Date().toISOString(),
end_date: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
recipient_type: 'all_owners',
send_email: true,
send_text: true,
send_owner_app: true,
created_by: testUserId
};
const campaign = await campaignRepo.create(campaignData);
expect(campaign).toBeDefined();
expect(campaign.id).toBeDefined();
expect(campaign.title).toBe('Board Elections 2025');
expect(campaign.campaign_type).toBe('board_election');
expect(campaign.status).toBe('draft');
});
});
describe('findOne', () => {
it('should find a campaign by ID', async () => {
const formData = await testHelper.createTestForm(testSite.id);
const campaign = await testHelper.createTestCampaign(testSite.id, formData.id);
const found = await campaignRepo.findOne({ id: campaign.id });
expect(found).toBeDefined();
expect(found.id).toBe(campaign.id);
expect(found.title).toBe(campaign.title);
});
it('should return null if campaign not found', async () => {
const found = await campaignRepo.findOne({ id: '00000000-0000-0000-0000-000000000000' });
expect(found).toBeUndefined();
});
});
describe('findAll', () => {
it('should find all campaigns for a site', async () => {
const formData = await testHelper.createTestForm(testSite.id);
// Create multiple campaigns
await testHelper.createTestCampaign(testSite.id, formData.id, 'board_election');
await testHelper.createTestCampaign(testSite.id, formData.id, 'decision');
await testHelper.createTestCampaign(testSite.id, formData.id, 'survey');
const campaigns = await campaignRepo.findAll(
{ site_id: testSite.id },
{ orderBy: 'created_at', orderDirection: 'desc' }
);
expect(campaigns).toBeInstanceOf(Array);
expect(campaigns.length).toBeGreaterThanOrEqual(3);
});
it('should filter campaigns by type', async () => {
const formData = await testHelper.createTestForm(testSite.id);
await testHelper.createTestCampaign(testSite.id, formData.id, 'board_election');
await testHelper.createTestCampaign(testSite.id, formData.id, 'decision');
const elections = await campaignRepo.findAll(
{ site_id: testSite.id, campaign_type: 'board_election' },
{ orderBy: 'created_at', orderDirection: 'desc' }
);
elections.forEach(campaign => {
expect(campaign.campaign_type).toBe('board_election');
});
});
it('should filter campaigns by status', async () => {
const formData = await testHelper.createTestForm(testSite.id);
const campaign = await testHelper.createTestCampaign(testSite.id, formData.id);
// Update status
await campaignRepo.updateById(campaign.id, { status: 'active' });
const activeCampaigns = await campaignRepo.findAll(
{ site_id: testSite.id, status: 'active' }
);
expect(activeCampaigns.length).toBeGreaterThanOrEqual(1);
activeCampaigns.forEach(c => {
expect(c.status).toBe('active');
});
});
});
describe('updateById', () => {
it('should update campaign details', async () => {
const formData = await testHelper.createTestForm(testSite.id);
const campaign = await testHelper.createTestCampaign(testSite.id, formData.id);
const updated = await campaignRepo.updateById(campaign.id, {
title: 'Updated Campaign Title',
status: 'active'
});
expect(updated).toBeDefined();
expect(updated.title).toBe('Updated Campaign Title');
expect(updated.status).toBe('active');
});
});
describe('deleteById', () => {
it('should delete a campaign', async () => {
const formData = await testHelper.createTestForm(testSite.id);
const campaign = await testHelper.createTestCampaign(testSite.id, formData.id);
const deleted = await campaignRepo.deleteById(campaign.id);
expect(deleted).toBe(true);
const found = await campaignRepo.findOne({ id: campaign.id });
expect(found).toBeUndefined();
});
});
describe('findByIdWithDetails', () => {
it('should return campaign with participation statistics', async () => {
const formData = await testHelper.createTestForm(testSite.id);
const campaign = await testHelper.createTestCampaign(testSite.id, formData.id);
const details = await campaignRepo.findByIdWithDetails(campaign.id);
expect(details).toBeDefined();
expect(details.participation_count).toBeDefined();
expect(details.total_invited).toBeDefined();
expect(details.participation_percentage).toBeDefined();
});
});
describe('updateStatus', () => {
it('should update campaign status to active', async () => {
const formData = await testHelper.createTestForm(testSite.id);
const campaign = await testHelper.createTestCampaign(testSite.id, formData.id);
const updated = await campaignRepo.updateStatus(campaign.id, 'active');
expect(updated).toBeDefined();
expect(updated.status).toBe('active');
});
it('should update campaign status to completed', async () => {
const formData = await testHelper.createTestForm(testSite.id);
const campaign = await testHelper.createTestCampaign(testSite.id, formData.id);
const updated = await campaignRepo.updateStatus(campaign.id, 'completed');
expect(updated).toBeDefined();
expect(updated.status).toBe('completed');
});
it('should throw error for invalid status', async () => {
const formData = await testHelper.createTestForm(testSite.id);
const campaign = await testHelper.createTestCampaign(testSite.id, formData.id);
await expect(
campaignRepo.updateStatus(campaign.id, 'invalid_status')
).rejects.toThrow('Invalid status: invalid_status');
});
});
});