Source code
Revision control
Copy as Markdown
Other Tools
import React from "react";
import { mount } from "enzyme";
import { Provider } from "react-redux";
import { INITIAL_STATE, reducers } from "common/Reducers.sys.mjs";
import { combineReducers, createStore } from "redux";
import { Weather } from "content-src/components/Weather/Weather";
import { actionTypes as at } from "common/Actions.mjs";
import { LinkMenu } from "content-src/components/LinkMenu/LinkMenu";
const PREF_SYS_SHOW_WEATHER = "system.showWeather";
const PREF_SYS_SHOW_WEATHER_OPT_IN = "system.showWeatherOptIn";
const PREF_OPT_IN_DISPLAYED = "weather.optInDisplayed";
const PREF_OPT_IN_ACCEPTED = "weather.optInAccepted";
const PREF_STATIC_WEATHER_DATA = "weather.staticData.enabled";
// keeps initialize = true and provides fake suggestion + location data
// so the component skips <WeatherPlaceholder>.
const weatherInit = {
initialized: true,
suggestions: [
{
current_conditions: {
temperature: { c: 22, f: 72 },
icon_id: 3,
summary: "Sunny",
},
},
],
locationData: { city: "Testville" },
};
// base mockState for general Weather-rendering tests.
// Opt-in is disabled here since it's only shown in specific locations
const mockState = {
...INITIAL_STATE,
Prefs: {
...INITIAL_STATE.Prefs,
values: {
...INITIAL_STATE.Prefs.values,
[PREF_SYS_SHOW_WEATHER]: true,
[PREF_SYS_SHOW_WEATHER_OPT_IN]: false,
},
},
Weather: { ...weatherInit },
};
// mock state for opt-in prompt tests.
// Ensures the opt-in dialog appears by default.
const optInMockState = {
...mockState,
Prefs: {
...mockState.Prefs,
values: {
...mockState.Prefs.values,
showWeather: true,
[PREF_SYS_SHOW_WEATHER_OPT_IN]: true,
[PREF_OPT_IN_DISPLAYED]: true,
[PREF_OPT_IN_ACCEPTED]: false,
[PREF_STATIC_WEATHER_DATA]: true,
"weather.locationSearchEnabled": true,
"weather.display": "simple",
"weather.temperatureUnits": "c",
},
},
};
function WrapWithProvider({ children, state = INITIAL_STATE }) {
const store = createStore(combineReducers(reducers), state);
return <Provider store={store}>{children}</Provider>;
}
describe("<Weather>", () => {
let wrapper;
let sandbox;
let dispatch;
beforeEach(() => {
sandbox = sinon.createSandbox();
dispatch = sandbox.stub();
});
afterEach(() => {
sandbox.restore();
wrapper?.unmount();
});
it("should render and show <Weather> if the `system.showWeather` pref is enabled", () => {
wrapper = mount(
<WrapWithProvider state={mockState}>
<Weather dispatch={dispatch} />
</WrapWithProvider>
);
assert.ok(wrapper.exists());
assert.ok(wrapper.find(".weather").exists());
});
describe("Opt-in prompt actions", () => {
it("should dispatch correct actions when user accepts weather opt-in", () => {
const store = createStore(combineReducers(reducers), optInMockState);
sinon.spy(store, "dispatch");
wrapper = mount(
<Provider store={store}>
<Weather />
</Provider>
);
const acceptBtn = wrapper.find("#accept-opt-in");
acceptBtn.simulate("click", { preventDefault() {} });
const dispatchedActions = store.dispatch
.getCalls()
.map(call => call.args[0]);
assert.ok(
dispatchedActions.some(
action => action.type === at.WEATHER_USER_OPT_IN_LOCATION
),
"Expected WEATHER_USER_OPT_IN_LOCATION to be dispatched"
);
assert.ok(
dispatchedActions.some(
action =>
action.type === at.WEATHER_OPT_IN_PROMPT_SELECTION &&
action.data === "accepted opt-in"
),
"Expected WEATHER_OPT_IN_PROMPT_SELECTION with accepted opt-in"
);
});
it("should render a shorter context menu when system.showWeatherOptIn is enabled", () => {
wrapper = mount(
<WrapWithProvider state={optInMockState}>
<Weather dispatch={dispatch} />
</WrapWithProvider>
);
// find the inner _Weather component (the real class)
const inner = wrapper.find("_Weather");
assert.ok(inner.exists(), "Inner _Weather component should exist");
// toggle context menu state on the real instance
inner.instance().setState({ showContextMenu: true });
wrapper.update();
const menu = wrapper.find(LinkMenu);
assert.ok(
menu.exists(),
"Expected LinkMenu to render when context menu opened"
);
const contextMenuOptions = menu.prop("options");
assert.deepEqual(contextMenuOptions, [
"ChangeWeatherLocation",
"DetectLocation",
"HideWeather",
"OpenLearnMoreURL",
]);
});
// TODO: Add test for "detect my location" telemetry once telemetry for that action is set up in another patch
});
});