mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-01-23 02:36:05 +00:00
test(focus-mode,backup): add missing service providers to fix 150+ failing tests
- Add GlobalTrackingIntervalService and TakeABreakService providers to FocusMode test suites - Add selectIsResumingBreak selector overrides to bug #5875 tests - Update BackupService test expectations for dual-archive architecture (no merge) - All 6,412 unit tests now passing
This commit is contained in:
parent
548ec8b6cb
commit
02430a34c7
5 changed files with 85 additions and 9 deletions
|
|
@ -31,6 +31,8 @@ import { TaskService } from '../../tasks/task.service';
|
|||
import { BannerService } from '../../../core/banner/banner.service';
|
||||
import { MetricService } from '../../metric/metric.service';
|
||||
import { FocusModeStorageService } from '../focus-mode-storage.service';
|
||||
import { GlobalTrackingIntervalService } from '../../../core/global-tracking-interval/global-tracking-interval.service';
|
||||
import { TakeABreakService } from '../../take-a-break/take-a-break.service';
|
||||
import * as actions from './focus-mode.actions';
|
||||
import * as selectors from './focus-mode.selectors';
|
||||
import { FocusModeMode, FocusScreen, TimerState } from '../focus-mode.model';
|
||||
|
|
@ -88,6 +90,10 @@ describe('FocusMode Bug #5875: Pomodoro timer sync issues', () => {
|
|||
logFocusSession: jasmine.createSpy('logFocusSession'),
|
||||
};
|
||||
|
||||
const takeABreakServiceMock = {
|
||||
otherNoBreakTIme$: new BehaviorSubject<number>(0),
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
FocusModeEffects,
|
||||
|
|
@ -126,6 +132,13 @@ describe('FocusMode Bug #5875: Pomodoro timer sync issues', () => {
|
|||
provide: FocusModeStorageService,
|
||||
useValue: { setLastCountdownDuration: jasmine.createSpy() },
|
||||
},
|
||||
{ provide: TakeABreakService, useValue: takeABreakServiceMock },
|
||||
{
|
||||
provide: GlobalTrackingIntervalService,
|
||||
useValue: {
|
||||
todayStr$: new BehaviorSubject<string>('2024-01-19'),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
@ -152,6 +165,7 @@ describe('FocusMode Bug #5875: Pomodoro timer sync issues', () => {
|
|||
store.overrideSelector(selectors.selectMode, FocusModeMode.Pomodoro);
|
||||
store.overrideSelector(selectors.selectCurrentScreen, FocusScreen.Break);
|
||||
store.overrideSelector(selectors.selectPausedTaskId, null);
|
||||
store.overrideSelector(selectors.selectIsResumingBreak, false);
|
||||
store.refreshState();
|
||||
|
||||
effects = TestBed.inject(FocusModeEffects);
|
||||
|
|
@ -187,6 +201,7 @@ describe('FocusMode Bug #5875: Pomodoro timer sync issues', () => {
|
|||
store.overrideSelector(selectors.selectMode, FocusModeMode.Pomodoro);
|
||||
store.overrideSelector(selectors.selectCurrentScreen, FocusScreen.Break);
|
||||
store.overrideSelector(selectors.selectPausedTaskId, null);
|
||||
store.overrideSelector(selectors.selectIsResumingBreak, false);
|
||||
store.refreshState();
|
||||
|
||||
effects = TestBed.inject(FocusModeEffects);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import { BannerService } from '../../../core/banner/banner.service';
|
|||
import { MetricService } from '../../metric/metric.service';
|
||||
import { FocusModeStorageService } from '../focus-mode-storage.service';
|
||||
import { TakeABreakService } from '../../take-a-break/take-a-break.service';
|
||||
import { GlobalTrackingIntervalService } from '../../../core/global-tracking-interval/global-tracking-interval.service';
|
||||
import * as actions from './focus-mode.actions';
|
||||
import * as selectors from './focus-mode.selectors';
|
||||
import { FocusModeMode, FocusScreen, TimerState } from '../focus-mode.model';
|
||||
|
|
@ -153,6 +154,12 @@ describe('FocusMode Bug #5995: Resume paused break', () => {
|
|||
{ provide: MetricService, useValue: metricServiceMock },
|
||||
{ provide: FocusModeStorageService, useValue: {} },
|
||||
{ provide: TakeABreakService, useValue: takeABreakServiceMock },
|
||||
{
|
||||
provide: GlobalTrackingIntervalService,
|
||||
useValue: {
|
||||
todayStr$: new BehaviorSubject<string>('2024-01-19'),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import { TaskService } from '../../tasks/task.service';
|
|||
import { BannerService } from '../../../core/banner/banner.service';
|
||||
import { MetricService } from '../../metric/metric.service';
|
||||
import { FocusModeStorageService } from '../focus-mode-storage.service';
|
||||
import { GlobalTrackingIntervalService } from '../../../core/global-tracking-interval/global-tracking-interval.service';
|
||||
import { TakeABreakService } from '../../take-a-break/take-a-break.service';
|
||||
import * as actions from './focus-mode.actions';
|
||||
import * as selectors from './focus-mode.selectors';
|
||||
import { FocusModeMode, FocusScreen, TimerState } from '../focus-mode.model';
|
||||
|
|
@ -83,6 +85,10 @@ describe('FocusModeEffects', () => {
|
|||
.and.returnValue(false),
|
||||
};
|
||||
|
||||
const takeABreakServiceMock = {
|
||||
otherNoBreakTIme$: new BehaviorSubject<number>(0),
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
FocusModeEffects,
|
||||
|
|
@ -120,6 +126,13 @@ describe('FocusModeEffects', () => {
|
|||
useValue: { setLastCountdownDuration: jasmine.createSpy() },
|
||||
},
|
||||
{ provide: HydrationStateService, useValue: hydrationStateServiceMock },
|
||||
{ provide: TakeABreakService, useValue: takeABreakServiceMock },
|
||||
{
|
||||
provide: GlobalTrackingIntervalService,
|
||||
useValue: {
|
||||
todayStr$: new BehaviorSubject<string>('2024-01-19'),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
import { provideMockStore, MockStore } from '@ngrx/store/testing';
|
||||
import { provideMockActions } from '@ngrx/effects/testing';
|
||||
import { of, ReplaySubject, Subject, Subscription } from 'rxjs';
|
||||
import { of, ReplaySubject, Subject, Subscription, BehaviorSubject } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { Action } from '@ngrx/store';
|
||||
import { FocusModeMode } from '../focus-mode.model';
|
||||
|
|
@ -16,6 +16,8 @@ import { FocusModeStrategyFactory } from '../focus-mode-strategies';
|
|||
import { MetricService } from '../../metric/metric.service';
|
||||
import { FocusModeStorageService } from '../focus-mode-storage.service';
|
||||
import { selectFocusModeConfig } from '../../config/store/global-config.reducer';
|
||||
import { GlobalTrackingIntervalService } from '../../../core/global-tracking-interval/global-tracking-interval.service';
|
||||
import { TakeABreakService } from '../../take-a-break/take-a-break.service';
|
||||
|
||||
describe('FocusMode Flowtime behavior', () => {
|
||||
describe('Reducer: startFocusSession', () => {
|
||||
|
|
@ -93,6 +95,9 @@ describe('FocusMode Flowtime behavior', () => {
|
|||
let actions$: ReplaySubject<Action>;
|
||||
let storageService: jasmine.SpyObj<FocusModeStorageService>;
|
||||
let effects: FocusModeEffects;
|
||||
const takeABreakServiceMock = {
|
||||
otherNoBreakTIme$: new BehaviorSubject<number>(0),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
actions$ = new ReplaySubject<Action>(1);
|
||||
|
|
@ -129,6 +134,13 @@ describe('FocusMode Flowtime behavior', () => {
|
|||
'setLastCountdownDuration',
|
||||
]),
|
||||
},
|
||||
{ provide: TakeABreakService, useValue: takeABreakServiceMock },
|
||||
{
|
||||
provide: GlobalTrackingIntervalService,
|
||||
useValue: {
|
||||
todayStr$: new BehaviorSubject<string>('2024-01-19'),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
store = TestBed.inject(MockStore);
|
||||
|
|
@ -315,6 +327,9 @@ describe('FocusMode Flowtime behavior', () => {
|
|||
duration: 45_000,
|
||||
purpose: 'work' as const,
|
||||
};
|
||||
const takeABreakServiceMock = {
|
||||
otherNoBreakTIme$: new BehaviorSubject<number>(0),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
actions$ = new ReplaySubject<Action>(1);
|
||||
|
|
@ -351,6 +366,13 @@ describe('FocusMode Flowtime behavior', () => {
|
|||
'setLastCountdownDuration',
|
||||
]),
|
||||
},
|
||||
{ provide: TakeABreakService, useValue: takeABreakServiceMock },
|
||||
{
|
||||
provide: GlobalTrackingIntervalService,
|
||||
useValue: {
|
||||
todayStr$: new BehaviorSubject<string>('2024-01-19'),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
@ -410,6 +432,9 @@ describe('FocusMode Flowtime behavior', () => {
|
|||
let effects: FocusModeEffects;
|
||||
let actions$: Subject<Action>;
|
||||
let getStrategySpy: jasmine.Spy;
|
||||
const takeABreakServiceMock = {
|
||||
otherNoBreakTIme$: new BehaviorSubject<number>(0),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
actions$ = new Subject<Action>();
|
||||
|
|
@ -449,6 +474,13 @@ describe('FocusMode Flowtime behavior', () => {
|
|||
'setLastCountdownDuration',
|
||||
]),
|
||||
},
|
||||
{ provide: TakeABreakService, useValue: takeABreakServiceMock },
|
||||
{
|
||||
provide: GlobalTrackingIntervalService,
|
||||
useValue: {
|
||||
todayStr$: new BehaviorSubject<string>('2024-01-19'),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -191,8 +191,8 @@ describe('BackupService', () => {
|
|||
expect(calledWith.task.ids).toContain('archived-task-1');
|
||||
});
|
||||
|
||||
it('should write archiveOld to IndexedDB when present in backup', async () => {
|
||||
// Note: dataRepair merges archiveOld into archiveYoung, but both are still written
|
||||
it('should write archiveOld separately to IndexedDB when present in backup', async () => {
|
||||
// Note: Dual-archive architecture keeps archives separate (no merge)
|
||||
const archiveOld = createArchiveModel('archived-task-old', 'Archived Task Old');
|
||||
const backupData = {
|
||||
...createMinimalValidBackup(),
|
||||
|
|
@ -202,15 +202,19 @@ describe('BackupService', () => {
|
|||
|
||||
await service.importCompleteBackup(backupData as any, true, true);
|
||||
|
||||
// After dataRepair, archiveOld is empty (merged into archiveYoung)
|
||||
// Both should be written
|
||||
// Both archives should be written
|
||||
expect(mockArchiveDbAdapter.saveArchiveYoung).toHaveBeenCalled();
|
||||
expect(mockArchiveDbAdapter.saveArchiveOld).toHaveBeenCalled();
|
||||
|
||||
// The archiveOld task should have been merged into archiveYoung by dataRepair
|
||||
// archiveOld remains separate - verify it was written to IndexedDB
|
||||
const oldCalledWith =
|
||||
mockArchiveDbAdapter.saveArchiveOld.calls.mostRecent().args[0];
|
||||
expect(oldCalledWith.task.ids).toContain('archived-task-old');
|
||||
|
||||
// archiveYoung should remain empty (no merge happened)
|
||||
const youngCalledWith =
|
||||
mockArchiveDbAdapter.saveArchiveYoung.calls.mostRecent().args[0];
|
||||
expect(youngCalledWith.task.ids).toContain('archived-task-old');
|
||||
expect(youngCalledWith.task.ids).toEqual([]);
|
||||
});
|
||||
|
||||
it('should write both archiveYoung and archiveOld when both present', async () => {
|
||||
|
|
@ -227,11 +231,16 @@ describe('BackupService', () => {
|
|||
expect(mockArchiveDbAdapter.saveArchiveYoung).toHaveBeenCalled();
|
||||
expect(mockArchiveDbAdapter.saveArchiveOld).toHaveBeenCalled();
|
||||
|
||||
// dataRepair merges archiveOld into archiveYoung
|
||||
// Dual-archive architecture: verify both written separately (no merge)
|
||||
const youngCalledWith =
|
||||
mockArchiveDbAdapter.saveArchiveYoung.calls.mostRecent().args[0];
|
||||
expect(youngCalledWith.task.ids).toContain('young-task');
|
||||
expect(youngCalledWith.task.ids).toContain('old-task');
|
||||
expect(youngCalledWith.task.ids).not.toContain('old-task');
|
||||
|
||||
const oldCalledWith =
|
||||
mockArchiveDbAdapter.saveArchiveOld.calls.mostRecent().args[0];
|
||||
expect(oldCalledWith.task.ids).toContain('old-task');
|
||||
expect(oldCalledWith.task.ids).not.toContain('young-task');
|
||||
});
|
||||
|
||||
it('should write default empty archives when not present in backup (added by dataRepair)', async () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue