- Bump version in package.json to 1.3.0 - Add new properties for field mapping in DynamicPollWebPart.manifest.json - Enhance DynamicPollWebPart.ts to support dynamic field mapping for polls and answers - Implement field loading and default application logic in PollDataService.ts - Update PollTypes.ts to include new interfaces for field mapping - Modify DynamicPollCollection.tsx to display configurable web part title - Update styles in DynamicPoll.module.scss for improved UI - Add localization strings for new properties in en-us.js and de-de.js - Update tests to reflect changes in data structure and functionality - Validate project structure and ensure all new features are accounted for
51 lines
2.7 KiB
TypeScript
51 lines
2.7 KiB
TypeScript
import {
|
|
calculatePollResults,
|
|
findUserAnswer,
|
|
parsePollOptionLines,
|
|
selectActivePoll,
|
|
selectActivePolls
|
|
} from '../src/webparts/dynamicPoll/PollCore';
|
|
import { IPoll, IPollAnswer } from '../src/webparts/dynamicPoll/PollTypes';
|
|
|
|
let passed: number = 0;
|
|
function assert(name: string, condition: boolean): void {
|
|
if (!condition) { throw new Error('FAILED: ' + name); }
|
|
passed++; console.log('OK:', name);
|
|
}
|
|
function poll(value: any): IPoll { return value as IPoll; } // tslint:disable-line:no-any
|
|
|
|
const now: Date = new Date('2026-08-23T12:00:00Z');
|
|
const selected: IPoll = selectActivePoll([
|
|
poll({ id: 1, question: 'old', options: ['A'], isActive: true,
|
|
startDate: new Date('2026-08-20T00:00:00Z'), endDate: new Date('2026-08-22T00:00:00Z') }),
|
|
poll({ id: 2, question: 'current', options: ['A', 'B'], isActive: true,
|
|
startDate: new Date('2026-08-23T00:00:00Z'), endDate: new Date('2026-08-24T00:00:00Z') }),
|
|
poll({ id: 3, question: 'future', options: ['A'], isActive: true,
|
|
startDate: new Date('2026-08-24T00:00:00Z') })
|
|
], now);
|
|
assert('current poll is selected by activation window', !!selected && selected.id === 2);
|
|
const activePolls: IPoll[] = selectActivePolls([
|
|
poll({ id: 2, question: 'newer', options: ['A'], isActive: true,
|
|
startDate: new Date('2026-08-23T00:00:00Z') }),
|
|
poll({ id: 4, question: 'older', options: ['A'], isActive: true,
|
|
startDate: new Date('2026-08-21T00:00:00Z') })
|
|
], now);
|
|
assert('all active polls are returned in activation order',
|
|
activePolls.length === 2 && activePolls[0].id === 2 && activePolls[1].id === 4);
|
|
|
|
const answers: IPollAnswer[] = [
|
|
{ id: 1, pollKey: 'poll-1', userKey: 'one@contoso.local', answer: 'A' },
|
|
{ id: 2, pollKey: 'poll-1', userKey: 'two@contoso.local', answer: 'B' },
|
|
{ id: 3, pollKey: 'poll-1', userKey: 'three@contoso.local', answer: 'A' },
|
|
{ id: 4, pollKey: 'poll-1', userKey: 'legacy@contoso.local', answer: 'Removed option' }
|
|
];
|
|
const results = calculatePollResults(['A', 'B'], answers);
|
|
assert('votes are counted per configured option', results[0].votes === 2 && results[1].votes === 1);
|
|
assert('invalid legacy answer is excluded from percentage', results[0].percentage === 67 && results[1].percentage === 33);
|
|
assert('user lookup is case insensitive', findUserAnswer(answers, 'ONE@CONTOSO.LOCAL') === 'A');
|
|
assert('unknown user has no answer', findUserAnswer(answers, 'unknown@contoso.local') === '');
|
|
const parsedOptions: string[] = parsePollOptionLines(['Ja\r\nNein\n\n Anderer Termin ', 'ja']);
|
|
assert('multiline options are trimmed, split and deduplicated',
|
|
parsedOptions.length === 3 && parsedOptions[0] === 'Ja' && parsedOptions[2] === 'Anderer Termin');
|
|
console.log('DynamicPoll core tests passed:', passed);
|