Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-2258: Preserve user onboarding settings #681

Merged
merged 10 commits into from Mar 15, 2021
@@ -19,6 +19,11 @@ import Tooltip from '../../../../shared-components/Tooltip';
import RadioButton from '../../../../shared-components/RadioButton/RadioButton';
import ToggleCheckbox from '../../../../shared-components/ToggleCheckbox/ToggleCheckbox';
import { BLOCK_SETTINGS, ONBOARDING } from '../../OnboardingView/OnboardingConstants';
import {
BLOCKING_POLICY_RECOMMENDED,
BLOCKING_POLICY_NOTHING,
BLOCKING_POLICY_EVERYTHING
} from '../../../../shared-hub/constants/BlockingPolicyConstants';

/**
* @class Implement the Block Settings View for the Dawn Hub onboarding flow
@@ -29,26 +34,61 @@ class BlockSettingsView extends Component {
constructor(props) {
super(props);
this.state = {
recommendedChoices: false,
enable_ad_block: null,
kindsOfTrackers: null,
enable_ad_block: null,
enable_anti_tracking: null,
enable_smart_block: null
};
}

componentDidMount() {
const { setupLifecycle: { blockSetupSeen } } = this.props;

if (blockSetupSeen) {
const {
enable_anti_tracking,
enable_ad_block,
enable_smart_block,
blockingPolicy
} = this.props;

this.setState({
kindsOfTrackers: blockingPolicy,
enable_ad_block,
enable_anti_tracking,
enable_smart_block
});
}
}

enumerateBlockingPolicy = (blockingPolicy) => {
let decodedPolicy;
switch (blockingPolicy) {
case BLOCKING_POLICY_EVERYTHING:
decodedPolicy = 1;
break;
case BLOCKING_POLICY_RECOMMENDED:
decodedPolicy = 2;
break;
case BLOCKING_POLICY_NOTHING:
decodedPolicy = 3;
break;
default:
break;
}
return decodedPolicy;
}

toggleRecommendedChoices = (value) => {
if (value === true) {
this.setState({
recommendedChoices: true,
enable_ad_block: true,
kindsOfTrackers: 2,
kindsOfTrackers: BLOCKING_POLICY_RECOMMENDED,
enable_anti_tracking: true,
enable_smart_block: true
});
} else {
this.setState({
recommendedChoices: false,
enable_ad_block: null,
kindsOfTrackers: null,
enable_anti_tracking: null,
@@ -57,6 +97,19 @@ class BlockSettingsView extends Component {
}
}

recommendedChoicesActive = () => {
const {
enable_anti_tracking,
enable_ad_block,
enable_smart_block,
kindsOfTrackers
} = this.state;
if (kindsOfTrackers === BLOCKING_POLICY_RECOMMENDED && enable_ad_block === true && enable_anti_tracking === true && enable_smart_block === true) {
return true;
}
return false;
}

handleAnswerChange = (category, answer) => {
this.setState({ [category]: answer });
}
@@ -71,7 +124,7 @@ class BlockSettingsView extends Component {
} = this.state;

const partOne = (enable_ad_block) ? '1' : '2';
const partTwo = kindsOfTrackers.toString();
const partTwo = this.enumerateBlockingPolicy(kindsOfTrackers);
const partThree = (enable_anti_tracking) ? '1' : '2';
const partFour = (enable_smart_block) ? '1' : '2';

@@ -94,35 +147,22 @@ class BlockSettingsView extends Component {
});

const {
setAdBlock, setAntiTracking, setSmartBlocking, setBlockingPolicy, setSetupStep
setAdBlock, setAntiTracking, setSmartBlocking, setBlockingPolicy, setSetupStep, setBlockSetupSeen
} = actions;
const { history } = this.props;

setAdBlock({ enable_ad_block });
setAntiTracking({ enable_anti_tracking });
setSmartBlocking({ enable_smart_block });

let blockingPolicy;
switch (kindsOfTrackers) {
case 1:
blockingPolicy = 'BLOCKING_POLICY_EVERYTHING';
break;
case 2:
blockingPolicy = 'BLOCKING_POLICY_RECOMMENDED';
break;
case 3:
blockingPolicy = 'BLOCKING_POLICY_NOTHING';
break;
default:
break;
}
setBlockingPolicy({ blockingPolicy });
setBlockingPolicy({ blockingPolicy: kindsOfTrackers });

setSetupStep({
setup_step: BLOCK_SETTINGS,
dawn_setup_number: this.buildSetupNumberString(),
origin: ONBOARDING
});
setBlockSetupSeen(true);
history.push('/onboarding/3');
} else {
setToast({
@@ -132,6 +172,24 @@ class BlockSettingsView extends Component {
}
}

renderQuestion = (question, tooltip = null) => {
if (tooltip) {
return (
<li className="BlockSettingsView_question">
<div className="BlockSettingsView_questionBlock">
{question}
<div className="BlockSettingsView__infoIcon g-tooltip">
<Tooltip header={tooltip} position="top" delay="300" isOnboardingHub />
</div>
</div>
</li>
);
}
return (
<li className="BlockSettingsView_question">{question}</li>
);
}

renderAnswerBlock = (checked, category, answer, label) => (
<div className="BlockSettingsView_answerBlock" onClick={() => this.handleAnswerChange(category, answer)}>
<div className="BlockSettingsView__radioButtonContainer">
@@ -143,10 +201,12 @@ class BlockSettingsView extends Component {

render() {
const {
recommendedChoices, enable_ad_block, kindsOfTrackers, enable_anti_tracking, enable_smart_block
enable_ad_block, kindsOfTrackers, enable_anti_tracking, enable_smart_block
} = this.state;
const { actions } = this.props;
const { logout } = actions;

const recommendedChoicesActive = this.recommendedChoicesActive();
return (
<Fragment>
<div className="BlockSettingsView__relativeContainer">
@@ -164,44 +224,23 @@ class BlockSettingsView extends Component {
<div className="BlockSettingsView_checkboxBlock">
<ToggleCheckbox
className="BlockSettingsView_checkbox"
checked={recommendedChoices}
onChange={() => this.toggleRecommendedChoices(!recommendedChoices)}
checked={recommendedChoicesActive}
onChange={() => this.toggleRecommendedChoices(!recommendedChoicesActive)}
/>
<div className="BlockSettingsView_checkboxLabel" onClick={() => this.toggleRecommendedChoices(!recommendedChoices)}>{t('ghostery_dawn_onboarding_recommended_choices')}</div>
<div className="BlockSettingsView_checkboxLabel" onClick={() => this.toggleRecommendedChoices(!recommendedChoicesActive)}>{t('ghostery_dawn_onboarding_recommended_choices')}</div>
</div>
<ol>
<li className="BlockSettingsView_question">{t('ghostery_dawn_onboarding_question_block_ads')}</li>
{this.renderQuestion(t('ghostery_dawn_onboarding_question_block_ads'))}
{this.renderAnswerBlock((enable_ad_block === true), 'enable_ad_block', true, t('hub_setup_modal_button_yes'))}
{this.renderAnswerBlock((enable_ad_block === false), 'enable_ad_block', false, t('hub_setup_modal_button_no'))}
<li className="BlockSettingsView_question">
<div className="BlockSettingsView_questionBlock">
{t('ghostery_dawn_onboarding_question_kinds_of_trackers')}
<div className="BlockSettingsView__infoIcon g-tooltip">
<Tooltip header={t('ghostery_dawn_onboarding_info_blocking_all')} position="top" delay="300" isOnboardingHub />
</div>
</div>
</li>
{this.renderAnswerBlock((kindsOfTrackers === 1), 'kindsOfTrackers', 1, t('ghostery_dawn_onboarding_kinds_of_trackers_all'))}
{this.renderAnswerBlock((kindsOfTrackers === 2), 'kindsOfTrackers', 2, t('ghostery_dawn_onboarding_kinds_of_trackers_ad_and_analytics'))}
{this.renderAnswerBlock((kindsOfTrackers === 3), 'kindsOfTrackers', 3, t('ghostery_dawn_onboarding_kinds_of_trackers_none'))}
<li className="BlockSettingsView_question">
<div className="BlockSettingsView_questionBlock">
{t('ghostery_dawn_onboarding_question_anti_tracking')}
<div className="BlockSettingsView__infoIcon g-tooltip">
<Tooltip header={t('ghostery_dawn_onboarding_info_anti_tracking')} position="top" delay="300" isOnboardingHub />
</div>
</div>
</li>
{this.renderQuestion(t('ghostery_dawn_onboarding_question_kinds_of_trackers'), t('ghostery_dawn_onboarding_info_blocking_all'))}
{this.renderAnswerBlock((kindsOfTrackers === BLOCKING_POLICY_EVERYTHING), 'kindsOfTrackers', BLOCKING_POLICY_EVERYTHING, t('ghostery_dawn_onboarding_kinds_of_trackers_all'))}
{this.renderAnswerBlock((kindsOfTrackers === BLOCKING_POLICY_RECOMMENDED), 'kindsOfTrackers', BLOCKING_POLICY_RECOMMENDED, t('ghostery_dawn_onboarding_kinds_of_trackers_ad_and_analytics'))}
{this.renderAnswerBlock((kindsOfTrackers === BLOCKING_POLICY_NOTHING), 'kindsOfTrackers', BLOCKING_POLICY_NOTHING, t('ghostery_dawn_onboarding_kinds_of_trackers_none'))}
{this.renderQuestion(t('ghostery_dawn_onboarding_question_anti_tracking'), t('ghostery_dawn_onboarding_info_anti_tracking'))}
{this.renderAnswerBlock((enable_anti_tracking === true), 'enable_anti_tracking', true, t('hub_setup_modal_button_yes'))}
{this.renderAnswerBlock((enable_anti_tracking === false), 'enable_anti_tracking', false, t('hub_setup_modal_button_no'))}
<li className="BlockSettingsView_question">
<div className="BlockSettingsView_questionBlock">
{t('ghostery_dawn_onboarding_question_smart_browsing')}
<div className="BlockSettingsView__infoIcon g-tooltip">
<Tooltip header={t('ghostery_dawn_onboarding_info_smart_browsing')} position="top" delay="300" isOnboardingHub />
</div>
</div>
</li>
{this.renderQuestion(t('ghostery_dawn_onboarding_question_smart_browsing'), t('ghostery_dawn_onboarding_info_smart_browsing'))}
{this.renderAnswerBlock((enable_smart_block === true), 'enable_smart_block', true, t('hub_setup_modal_button_yes'))}
{this.renderAnswerBlock((enable_smart_block === false), 'enable_smart_block', false, t('hub_setup_modal_button_no'))}
</ol>
@@ -231,5 +270,13 @@ BlockSettingsView.propTypes = {
setBlockingPolicy: PropTypes.func.isRequired,
setToast: PropTypes.func.isRequired,
setSetupStep: PropTypes.func.isRequired,
setBlockSetupSeen: PropTypes.func.isRequired,
}).isRequired,
setupLifecycle: PropTypes.shape({
blockSetupSeen: PropTypes.bool.isRequired,
}).isRequired,
enable_ad_block: PropTypes.bool.isRequired,
enable_anti_tracking: PropTypes.bool.isRequired,
enable_smart_block: PropTypes.bool.isRequired,
blockingPolicy: PropTypes.string.isRequired
};
@@ -16,12 +16,22 @@ import renderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import { MemoryRouter } from 'react-router';
import BlockSettingsView from '../BlockSettingsView';
import {
BLOCKING_POLICY_RECOMMENDED,
} from '../../../../../shared-hub/constants/BlockingPolicyConstants';

const noop = () => {};
jest.mock('../../../../../shared-components/Tooltip');

describe('app/dawn-hub/Views/OnboardingViews/Step2_BlockSettingsView/BlockSettingsView.test.jsx', () => {
const initialState = {
setupLifecycle: {
blockSetupSeen: false
},
blockingPolicy: '',
enable_ad_block: false,
enable_anti_tracking: false,
enable_smart_block: false,
actions: {
logout: noop,
setAntiTracking: noop,
@@ -30,7 +40,8 @@ describe('app/dawn-hub/Views/OnboardingViews/Step2_BlockSettingsView/BlockSettin
setBlockingPolicy: noop,
setToast: noop,
setSetupStep: noop,
}
setBlockSetupSeen: noop,
},
};
describe('Snapshot tests with react-test-renderer', () => {
test('BlockSettings View is rendered correctly', () => {
@@ -55,6 +66,7 @@ describe('app/dawn-hub/Views/OnboardingViews/Step2_BlockSettingsView/BlockSettin
setBlockingPolicy: jest.fn(),
setToast: noop,
setSetupStep: jest.fn(),
setBlockSetupSeen: jest.fn(),
},
history: {
push: noop
@@ -66,7 +78,7 @@ describe('app/dawn-hub/Views/OnboardingViews/Step2_BlockSettingsView/BlockSettin

instance.toggleRecommendedChoices(true);
expect(component.state('enable_ad_block')).toBe(true);
expect(component.state('kindsOfTrackers')).toBe(2);
expect(component.state('kindsOfTrackers')).toBe(BLOCKING_POLICY_RECOMMENDED);
expect(component.state('enable_anti_tracking')).toBe(true);
expect(component.state('enable_smart_block')).toBe(true);

@@ -18,16 +18,17 @@ import { logout } from '../../../../Account/AccountActions';
import { setAntiTracking, setAdBlock, setSmartBlocking } from '../../../../shared-hub/actions/AntiSuiteActions';
import setBlockingPolicy from '../../../../shared-hub/actions/BlockingPolicyActions';
import setToast from '../../../../shared-hub/actions/ToastActions';
import { setSetupStep } from '../../../../shared-hub/actions/SetupLifecycleActions';
import { setSetupStep, setBlockSetupSeen } from '../../../../shared-hub/actions/SetupLifecycleActions';

const actionCreators = {
logout,
setAntiTracking,
setAdBlock,
setSmartBlocking,
setBlockingPolicy,
setBlockSetupSeen,
setToast,
setSetupStep,
};

export default withRouter(buildReduxHOC(null, actionCreators, BlockSettingsView));
export default withRouter(buildReduxHOC(['setupLifecycle', 'antiSuite', 'blockingPolicy'], actionCreators, BlockSettingsView));
@@ -76,6 +76,21 @@ class ChooseDefaultSearchView extends Component {
document.addEventListener('click', this.handleClickAway);

this.fetchSearchEnginesAsync();

const { setupLifecycle: { searchSetupSeen } } = this.props;

if (searchSetupSeen) {
const { defaultSearch } = this.props;
const searchChoices = [
SEARCH_GHOSTERY,
SEARCH_BING,
SEARCH_YAHOO,
SEARCH_STARTPAGE,
];
const isOther = !searchChoices.includes(defaultSearch);
const prevChosenSearch = isOther ? SEARCH_OTHER : defaultSearch;
this.setState({ chosenSearch: prevChosenSearch, otherSearchSelected: isOther ? defaultSearch : null });
}
}

componentWillUnmount() {
@@ -138,7 +153,7 @@ class ChooseDefaultSearchView extends Component {
handleSubmit = () => {
const { chosenSearch, otherSearchSelected } = this.state;
const { actions, history } = this.props;
const { setSetupStep, setDefaultSearch } = actions;
const { setSetupStep, setDefaultSearch, setSearchSetupSeen } = actions;

const chosenSearchName = chosenSearch === SEARCH_OTHER
? otherSearchSelected
@@ -171,6 +186,7 @@ class ChooseDefaultSearchView extends Component {
dawn_setup_number,
origin: ONBOARDING
});
setSearchSetupSeen(true);
history.push(`/${ONBOARDING}/${CHOOSE_PLAN}`);
}

@@ -15,11 +15,12 @@ import { withRouter } from 'react-router-dom';
import ChooseDefaultSearchView from './ChooseDefaultSearchView';
import { buildReduxHOC } from '../../../../shared-hub/utils';
import setDefaultSearch from './ChooseDefaultSearchActions';
import { setSetupStep } from '../../../../shared-hub/actions/SetupLifecycleActions';
import { setSetupStep, setSearchSetupSeen } from '../../../../shared-hub/actions/SetupLifecycleActions';

const actionCreators = {
setDefaultSearch,
setSetupStep,
setSearchSetupSeen,
};

export default withRouter(buildReduxHOC(null, actionCreators, ChooseDefaultSearchView));
export default withRouter(buildReduxHOC(['setupLifecycle', 'defaultSearch'], actionCreators, ChooseDefaultSearchView));
ProTip! Use n and p to navigate between commits in a pull request.