tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit e96d60444f5448b2ae6e0dd62f7f685fce26b508
parent 2132f219cb77ce83611db4aac4bcfd2362e63b98
Author: Reem H <42309026+reemhamz@users.noreply.github.com>
Date:   Mon,  3 Nov 2025 05:38:18 +0000

Bug 1997821 - Add tests for focus timer types resetting to initial values when pref is disabled. r=home-newtab-reviewers,npypchenko

Differential Revision: https://phabricator.services.mozilla.com/D270983

Diffstat:
Mbrowser/extensions/newtab/content-src/components/Widgets/Widgets.jsx | 55+++++++++++++++++++++++++++++++++----------------------
Mbrowser/extensions/newtab/data/content/activity-stream.bundle.js | 47+++++++++++++++++++++++++++++------------------
Mbrowser/extensions/newtab/test/unit/content-src/components/Widgets.test.jsx | 73++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 134 insertions(+), 41 deletions(-)

diff --git a/browser/extensions/newtab/content-src/components/Widgets/Widgets.jsx b/browser/extensions/newtab/content-src/components/Widgets/Widgets.jsx @@ -16,6 +16,38 @@ const PREF_WIDGETS_TIMER_ENABLED = "widgets.focusTimer.enabled"; const PREF_WIDGETS_SYSTEM_TIMER_ENABLED = "widgets.system.focusTimer.enabled"; const PREF_FEEDS_SECTION_TOPSTORIES = "feeds.section.topstories"; +// resets timer to default values (exported for testing) +// In practice, this logic runs inside a useEffect when +// the timer widget is disabled (after the pref flips from true to false). +// Because Enzyme tests cannot reliably simulate that pref update or trigger +// the related useEffect, we expose this helper to at least just test the reset behavior instead + +export function resetTimerToDefaults(dispatch, timerType) { + const originalTime = timerType === "focus" ? 1500 : 300; + + // Reset both focus and break timers to their initial durations + dispatch( + ac.AlsoToMain({ + type: at.WIDGETS_TIMER_RESET, + data: { + timerType, + duration: originalTime, + initialDuration: originalTime, + }, + }) + ); + + // Set the timer type back to "focus" + dispatch( + ac.AlsoToMain({ + type: at.WIDGETS_TIMER_SET_TYPE, + data: { + timerType: "focus", + }, + }) + ); +} + function Widgets() { const prefs = useSelector(state => state.Prefs.values); const { messageData } = useSelector(state => state.Messages); @@ -51,31 +83,10 @@ function Widgets() { useEffect(() => { const wasTimerEnabled = prevTimerEnabledRef.current; const isTimerEnabled = timerEnabled; - const originalTime = timerType === "focus" ? 1500 : 300; // Only reset if timer was enabled and is now disabled if (wasTimerEnabled && !isTimerEnabled && timerData) { - // Reset both focus and break timers to their initial durations - dispatch( - ac.AlsoToMain({ - type: at.WIDGETS_TIMER_RESET, - data: { - timerType, - duration: originalTime, - initialDuration: originalTime, - }, - }) - ); - - // Set the timer type back to "focus" - dispatch( - ac.AlsoToMain({ - type: at.WIDGETS_TIMER_SET_TYPE, - data: { - timerType: "focus", - }, - }) - ); + resetTimerToDefaults(dispatch, timerType); } // Update the ref to track current state diff --git a/browser/extensions/newtab/data/content/activity-stream.bundle.js b/browser/extensions/newtab/data/content/activity-stream.bundle.js @@ -13514,6 +13514,34 @@ const PREF_WIDGETS_SYSTEM_LISTS_ENABLED = "widgets.system.lists.enabled"; const PREF_WIDGETS_TIMER_ENABLED = "widgets.focusTimer.enabled"; const PREF_WIDGETS_SYSTEM_TIMER_ENABLED = "widgets.system.focusTimer.enabled"; const PREF_FEEDS_SECTION_TOPSTORIES = "feeds.section.topstories"; + +// resets timer to default values (exported for testing) +// In practice, this logic runs inside a useEffect when +// the timer widget is disabled (after the pref flips from true to false). +// Because Enzyme tests cannot reliably simulate that pref update or trigger +// the related useEffect, we expose this helper to at least just test the reset behavior instead + +function resetTimerToDefaults(dispatch, timerType) { + const originalTime = timerType === "focus" ? 1500 : 300; + + // Reset both focus and break timers to their initial durations + dispatch(actionCreators.AlsoToMain({ + type: actionTypes.WIDGETS_TIMER_RESET, + data: { + timerType, + duration: originalTime, + initialDuration: originalTime + } + })); + + // Set the timer type back to "focus" + dispatch(actionCreators.AlsoToMain({ + type: actionTypes.WIDGETS_TIMER_SET_TYPE, + data: { + timerType: "focus" + } + })); +} function Widgets() { const prefs = (0,external_ReactRedux_namespaceObject.useSelector)(state => state.Prefs.values); const { @@ -13537,27 +13565,10 @@ function Widgets() { (0,external_React_namespaceObject.useEffect)(() => { const wasTimerEnabled = prevTimerEnabledRef.current; const isTimerEnabled = timerEnabled; - const originalTime = timerType === "focus" ? 1500 : 300; // Only reset if timer was enabled and is now disabled if (wasTimerEnabled && !isTimerEnabled && timerData) { - // Reset both focus and break timers to their initial durations - dispatch(actionCreators.AlsoToMain({ - type: actionTypes.WIDGETS_TIMER_RESET, - data: { - timerType, - duration: originalTime, - initialDuration: originalTime - } - })); - - // Set the timer type back to "focus" - dispatch(actionCreators.AlsoToMain({ - type: actionTypes.WIDGETS_TIMER_SET_TYPE, - data: { - timerType: "focus" - } - })); + resetTimerToDefaults(dispatch, timerType); } // Update the ref to track current state diff --git a/browser/extensions/newtab/test/unit/content-src/components/Widgets.test.jsx b/browser/extensions/newtab/test/unit/content-src/components/Widgets.test.jsx @@ -3,8 +3,12 @@ import { mount } from "enzyme"; import { Provider } from "react-redux"; import { INITIAL_STATE, reducers } from "common/Reducers.sys.mjs"; import { combineReducers, createStore } from "redux"; -import { Widgets } from "content-src/components/Widgets/Widgets"; +import { + Widgets, + resetTimerToDefaults, +} from "content-src/components/Widgets/Widgets"; import { Lists } from "content-src/components/Widgets/Lists/Lists"; +import { actionTypes as at } from "common/Actions.mjs"; import { FocusTimer } from "content-src/components/Widgets/FocusTimer/FocusTimer"; const PREF_WIDGETS_LISTS_ENABLED = "widgets.lists.enabled"; @@ -61,4 +65,71 @@ describe("<Widgets>", () => { assert.ok(wrapper.find(".widgets-container").exists()); assert.ok(wrapper.find(FocusTimer).exists()); }); + + it("should not render FocusTimer when timer pref is disabled", () => { + const state = { + ...INITIAL_STATE, + Prefs: { + ...INITIAL_STATE.Prefs, + values: { + ...INITIAL_STATE.Prefs.values, + [PREF_WIDGETS_TIMER_ENABLED]: false, + [PREF_WIDGETS_SYSTEM_TIMER_ENABLED]: true, + }, + }, + }; + const wrapper = mount( + <WrapWithProvider state={state}> + <Widgets /> + </WrapWithProvider> + ); + assert.ok(!wrapper.find(FocusTimer).exists()); + }); + + describe("resetTimerToDefaults", () => { + it("should dispatch WIDGETS_TIMER_RESET with focus timer defaults", () => { + const dispatch = sinon.spy(); + const timerType = "focus"; + + resetTimerToDefaults(dispatch, timerType); + + const resetCall = dispatch + .getCalls() + .find(call => call.args[0]?.type === at.WIDGETS_TIMER_RESET); + const setTypeCall = dispatch + .getCalls() + .find(call => call.args[0]?.type === at.WIDGETS_TIMER_SET_TYPE); + + assert.ok(resetCall, "should dispatch WIDGETS_TIMER_RESET"); + assert.ok(setTypeCall, "should dispatch WIDGETS_TIMER_SET_TYPE"); + assert.equal( + resetCall.args[0].data.duration, + 1500, + "should reset focus to 25 minutes" + ); + assert.equal(resetCall.args[0].data.initialDuration, 1500); + assert.equal(resetCall.args[0].data.timerType, "focus"); + assert.equal(setTypeCall.args[0].data.timerType, "focus"); + }); + + it("should dispatch WIDGETS_TIMER_RESET with break timer defaults", () => { + const dispatch = sinon.spy(); + const timerType = "break"; + + resetTimerToDefaults(dispatch, timerType); + + const resetCall = dispatch + .getCalls() + .find(call => call.args[0]?.type === at.WIDGETS_TIMER_RESET); + + assert.ok(resetCall, "should dispatch WIDGETS_TIMER_RESET"); + assert.equal( + resetCall.args[0].data.duration, + 300, + "should reset break to 5 minutes" + ); + assert.equal(resetCall.args[0].data.initialDuration, 300); + assert.equal(resetCall.args[0].data.timerType, "break"); + }); + }); });