208 lines
7 KiB
JavaScript
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');
|
|
});
|
|
});
|
|
});
|
|
|