import { TestBed } from '@angular/core/testing'; import { RuleService, RuleType, IfThenRule, TimeWindowRule } from './rule-service'; import { SelectableDayType } from './calendar-service'; describe('RuleService', () => { let service: RuleService; beforeEach(() => { // Clear localStorage before each test to ensure a clean state localStorage.clear(); TestBed.configureTestingModule({}); service = TestBed.inject(RuleService); }); it('should be created', () => { expect(service).toBeTruthy(); }); it('should initialize with default rules', () => { const rules = service.rules; expect(rules.length).toBe(2); expect(rules[0].id).toBe('default-samedi-malin'); expect(rules[1].id).toBe('default-christmas'); }); it('should parse dates correctly for TimeWindowRules', () => { const rules = service.rules; const christmasRule = rules.find((r) => r.type === RuleType.TIME_WINDOW) as TimeWindowRule; expect(christmasRule).toBeDefined(); expect(christmasRule.startDate instanceof Date).toBe(true); expect(christmasRule.endDate instanceof Date).toBe(true); }); it('migrates legacy force values without changing rule order or dates', () => { TestBed.resetTestingModule(); localStorage.setItem( 'vacationRules', JSON.stringify([ { id: 'legacy-first', name: 'First', type: RuleType.TIME_WINDOW, enabled: true, startDate: '2024-02-01', endDate: '2024-02-05', placeDays: 1, placeType: SelectableDayType.CP, }, { id: 'legacy-second', name: 'Second', type: RuleType.TIME_WINDOW, enabled: true, force: 'obligation', startDate: '2024-03-01', endDate: '2024-03-02', placeDays: 1, placeType: SelectableDayType.RTT, }, ]), ); TestBed.configureTestingModule({}); service = TestBed.inject(RuleService); expect(service.rules.map((rule) => rule.id)).toEqual(['legacy-first', 'legacy-second']); expect(service.rules[0].force).toBe('preference'); const first = service.rules[0] as TimeWindowRule; expect(first.startDate.toISOString().slice(0, 10)).toBe('2024-02-01'); }); it('should add a new rule', () => { const newRule: IfThenRule = { id: 'test-rule', name: 'Test Rule', type: RuleType.IF_THEN, enabled: true, dayOfWeek: 1, // Monday placeDays: 1, placeType: SelectableDayType.RTT, placement: 'after', rewardDays: 0, rewardType: SelectableDayType.OTHER, }; service.addRule(newRule); const rules = service.rules; expect(rules.length).toBe(3); expect(rules.find((r) => r.id === 'test-rule')).toBeDefined(); }); it('should update an existing rule', () => { const rules = service.rules; const targetRule = { ...rules[0] } as IfThenRule; targetRule.name = 'Updated Name'; service.updateRule(targetRule); const updatedRules = service.rules; const updated = updatedRules.find((r) => r.id === targetRule.id); expect(updated?.name).toBe('Updated Name'); }); it('should delete a rule', () => { const rules = service.rules; const idToDelete = rules[0].id; service.deleteRule(idToDelete); const updatedRules = service.rules; expect(updatedRules.length).toBe(1); expect(updatedRules.find((r) => r.id === idToDelete)).toBeUndefined(); }); it('should toggle rule enabled state', () => { const targetId = service.rules[0].id; const initialState = service.rules[0].enabled; service.toggleRule(targetId); expect(service.rules.find((r) => r.id === targetId)?.enabled).toBe(!initialState); }); it('should reorder rules correctly', () => { const rulesBefore = service.rules; const firstRuleId = rulesBefore[0].id; const secondRuleId = rulesBefore[1].id; // Move first rule to second position service.reorderRules(0, 1); const rulesAfter = service.rules; expect(rulesAfter[0].id).toBe(secondRuleId); expect(rulesAfter[1].id).toBe(firstRuleId); }); });