From 811697f49f6b3787b9612295a48fb4bc341245e7 Mon Sep 17 00:00:00 2001 From: NejcZdovc Date: Wed, 7 Jun 2017 16:13:51 -0700 Subject: [PATCH] Refactors PublisherToggle into redux component Resolves #9323 Auditors: @bridiver @bscfliton Test Plan: --- app/common/lib/publisherUtil.js | 67 ++++++ app/common/state/siteSettingsState.js | 19 ++ .../components/navigation/navigationBar.js | 79 +++---- .../components/navigation/navigator.js | 9 +- .../components/navigation/publisherToggle.js | 137 +++++------- app/renderer/components/navigation/urlBar.js | 18 +- test/unit/app/common/lib/publisherUtilTest.js | 138 ++++++++++++ .../navigation/navigationBarTest.js | 136 ++++++++++++ .../navigation/publisherToggleTest.js | 204 +++++++----------- 9 files changed, 537 insertions(+), 270 deletions(-) create mode 100644 app/common/lib/publisherUtil.js create mode 100644 test/unit/app/common/lib/publisherUtilTest.js create mode 100644 test/unit/app/renderer/components/navigation/navigationBarTest.js diff --git a/app/common/lib/publisherUtil.js b/app/common/lib/publisherUtil.js new file mode 100644 index 00000000000..76c17775d41 --- /dev/null +++ b/app/common/lib/publisherUtil.js @@ -0,0 +1,67 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const Immutable = require('immutable') + +// Constants +const settings = require('../../../js/constants/settings') +const siteSettingsState = require('../state/siteSettingsState') + +// Utils +const {getSetting} = require('../../../js/settings') +const {isHttpOrHttps} = require('../../../js/lib/urlutil') +const {isSourceAboutUrl} = require('../../../js/lib/appUrlUtil') + +const visiblePublisher = (state, publisherId) => { + if (publisherId == null) { + return true + } + + // ledgerPaymentsShown is undefined by default until + // user decide to permanently hide the publisher, + // so for icon to be shown it can be everything but false + const hostSettings = siteSettingsState.getSettingsByHost(state, publisherId) + const ledgerPaymentsShown = hostSettings && hostSettings.get('ledgerPaymentsShown') + + return typeof ledgerPaymentsShown === 'boolean' + ? ledgerPaymentsShown + : true +} + +const publisherState = { + enabledForPaymentsPublisher: (state, locationId) => { + const locationInfo = state.get('locationInfo', Immutable.Map()) + const publisherId = locationInfo.getIn([locationId, 'publisher']) + + const synopsis = state.getIn(['publisherInfo', 'synopsis'], Immutable.Map()) + const hostSettings = siteSettingsState.getSettingsByHost(state, publisherId) + + // All publishers will be enabled by default if AUTO_SUGGEST is ON, + // excluding publishers defined on ledger's exclusion list + const excluded = locationInfo.getIn([locationId, 'exclude']) + const autoSuggestSites = getSetting(settings.AUTO_SUGGEST_SITES) + + // If session is clear then siteSettings is undefined and icon + // will never be shown, but synopsis may not be empty. + // In such cases let's check if synopsis matches current publisherId + const isValidPublisherSynopsis = !!synopsis.map(entry => entry.get('site')) + .includes(publisherId) + + // hostSettings is undefined until user hit addFunds button. + // For such cases check autoSuggestSites for eligibility. + return hostSettings + ? hostSettings.get('ledgerPayments') !== false + : isValidPublisherSynopsis || (autoSuggestSites && !excluded) + }, + + shouldShowAddPublisherButton: (state, location, publisherId) => { + return location && + !isSourceAboutUrl(location) && + getSetting(settings.PAYMENTS_ENABLED) && + isHttpOrHttps(location) && + visiblePublisher(state, publisherId) + } +} + +module.exports = publisherState diff --git a/app/common/state/siteSettingsState.js b/app/common/state/siteSettingsState.js index 6effa414577..ba00633663e 100644 --- a/app/common/state/siteSettingsState.js +++ b/app/common/state/siteSettingsState.js @@ -1,6 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const Immutable = require('immutable') + +// Constants const appConfig = require('../../../js/constants/appConfig') + +// State const siteSettings = require('../../../js/state/siteSettings') +// Utils +const {getHostPattern} = require('../../../js/lib/urlutil') + const api = { getAllSiteSettings: (state, isPrivate) => { if (isPrivate) { @@ -9,6 +21,13 @@ const api = { return state.get('siteSettings') }, + getSettingsByHost: (state, url) => { + const siteSettings = state.get('siteSettings') + const hostPattern = getHostPattern(url) + + return siteSettings ? siteSettings.get(hostPattern) : Immutable.Map() + }, + isNoScriptEnabled (state, settings) { return siteSettings.activeSettings(settings, state, appConfig).noScript === true } diff --git a/app/renderer/components/navigation/navigationBar.js b/app/renderer/components/navigation/navigationBar.js index 32f45623646..6c1a0804ed3 100644 --- a/app/renderer/components/navigation/navigationBar.js +++ b/app/renderer/components/navigation/navigationBar.js @@ -24,6 +24,7 @@ const settings = require('../../../../js/constants/settings') // State const tabState = require('../../../common/state/tabState') +const publisherState = require('../../../common/lib/publisherUtil') const frameStateUtil = require('../../../../js/state/frameStateUtil') // Store @@ -31,7 +32,7 @@ const windowStore = require('../../../../js/stores/windowStore') // Utils const cx = require('../../../../js/lib/classSet') -const {isSourceAboutUrl} = require('../../../../js/lib/appUrlUtil') +const {getBaseUrl} = require('../../../../js/lib/appUrlUtil') const siteUtil = require('../../../../js/state/siteUtil') const eventUtil = require('../../../../js/lib/eventUtil') const UrlUtil = require('../../../../js/lib/urlutil') @@ -55,7 +56,7 @@ class NavigationBar extends React.Component { } onToggleBookmark () { - const editing = this.bookmarked + const editing = this.props.isBookmarked // show the AddEditBookmarkHanger control; saving/deleting takes place there let siteDetail = siteUtil.getDetailFromFrame(this.activeFrame, siteTags.BOOKMARK) const key = siteUtil.getSiteKey(siteDetail) @@ -109,11 +110,6 @@ class NavigationBar extends React.Component { } } - get bookmarked () { - return this.props.activeFrameKey !== undefined && - this.props.bookmarked - } - componentDidMount () { ipc.on(messages.SHORTCUT_ACTIVE_FRAME_BOOKMARK, () => this.onToggleBookmark()) ipc.on(messages.SHORTCUT_ACTIVE_FRAME_REMOVE_BOOKMARK, () => this.onToggleBookmark()) @@ -129,10 +125,12 @@ class NavigationBar extends React.Component { const activeTabShowingMessageBox = tabState.isShowingMessageBox(state, activeTabId) const bookmarkDetail = currentWindow.get('bookmarkDetail') const mouseInTitlebar = currentWindow.getIn(['ui', 'mouseInTitlebar']) - const title = activeFrame.get('title') || '' + const title = activeFrame.get('title', '') const loading = activeFrame.get('loading') - const location = activeFrame.get('location') || '' - const navbar = activeFrame.get('navbar') || Immutable.Map() + const location = activeFrame.get('location', '') + const locationId = getBaseUrl(location) + const publisherId = state.getIn(['locationInfo', locationId, 'publisher']) + const navbar = activeFrame.get('navbar', Immutable.Map()) const hasTitle = title && location && title !== location.replace(/^https?:\/\//, '') const titleMode = activeTabShowingMessageBox || @@ -148,42 +146,36 @@ class NavigationBar extends React.Component { ) const props = {} - - props.navbar = navbar - props.sites = state.get('sites') // TODO(nejc) remove, primitives only + // used in renderer props.activeFrameKey = activeFrameKey - props.location = location - props.title = title - props.bookmarked = activeTab && activeTab.get('bookmarked') - props.partitionNumber = activeFrame.get('partitionNumber') || 0 - props.isSecure = activeFrame.getIn(['security', 'isSecure']) - props.loading = loading - props.showBookmarkHanger = bookmarkDetail && bookmarkDetail.get('isBookmarkHanger') - props.mouseInTitlebar = mouseInTitlebar - props.settings = state.get('settings') - props.siteSettings = state.get('siteSettings') - props.synopsis = state.getIn(['publisherInfo', 'synopsis']) || new Immutable.Map() - props.activeTabShowingMessageBox = activeTabShowingMessageBox - props.locationInfo = state.get('locationInfo') props.titleMode = titleMode - props.isWideURLbarEnabled = getSetting(settings.WIDE_URL_BAR) + props.isBookmarked = props.activeFrameKey !== undefined && + activeTab && activeTab.get('bookmarked') + props.isWideUrlBarEnabled = getSetting(settings.WIDE_URL_BAR) + props.showBookmarkHanger = bookmarkDetail && bookmarkDetail.get('isBookmarkHanger') + props.isLoading = loading + props.showPublisherToggle = publisherState.shouldShowAddPublisherButton(state, location, publisherId) + props.showHomeButton = !props.titleMode && getSetting(settings.SHOW_HOME_BUTTON) + + // used in other functions + props.navbar = navbar // TODO(nejc) remove, primitives only + props.sites = state.get('sites') // TODO(nejc) remove, primitives only props.activeTabId = activeTabId return props } render () { - if (this.props.activeFrameKey === undefined || - this.props.siteSettings === undefined) { + if (this.props.dontRender) { return null } - return - + { + this.props.showNavigationBar + ? + : null + }
entry.get('site')).includes(this.publisherId) - } - - get enabledForPaymentsPublisher () { - // All publishers will be enabled by default if AUTO_SUGGEST is ON, - // excluding publishers defined on ledger's exclusion list - const excluded = this.props.locationInfo && this.props.locationInfo.getIn([this.locationId, 'exclude']) - const autoSuggestSites = getSetting(settings.AUTO_SUGGEST_SITES) - - // hostSettings is undefined until user hit addFunds button. - // For such cases check autoSuggestSites for eligibility. - return this.hostSettings - ? this.hostSettings.get('ledgerPayments') !== false - : this.validPublisherSynopsis || (autoSuggestSites && !excluded) - } - - get verifiedPublisher () { - return this.props.locationInfo && this.props.locationInfo.getIn([this.locationId, 'verified']) - } - - get visiblePublisher () { - // ledgerPaymentsShown is undefined by default until - // user decide to permanently hide the publisher, - // so for icon to be shown it can be everything but false - const ledgerPaymentsShown = this.hostSettings && this.hostSettings.get('ledgerPaymentsShown') - return typeof ledgerPaymentsShown === 'boolean' - ? ledgerPaymentsShown - : true - } - - get shouldShowAddPublisherButton () { - return getSetting(settings.PAYMENTS_ENABLED) && - isHttpOrHttps(this.props.location) && - this.visiblePublisher - } - get l10nString () { let l10nData = 'disabledPublisher' - if (this.verifiedPublisher && !this.enabledForPaymentsPublisher) { + if (this.props.isVerifiedPublisher && !this.props.isEnabledForPaymentsPublisher) { l10nData = 'verifiedPublisher' - } else if (this.enabledForPaymentsPublisher) { + } else if (this.props.isEnabledForPaymentsPublisher) { l10nData = 'enabledPublisher' } return l10nData } onAuthorizePublisher () { - const hostPattern = getHostPattern(this.publisherId) - appActions.changeSiteSetting(hostPattern, 'ledgerPayments', !this.enabledForPaymentsPublisher) + appActions.changeSiteSetting(this.props.hostPattern, 'ledgerPayments', !this.props.isEnabledForPaymentsPublisher) + } + + mergeProps (state, ownProps) { + const currentWindow = state.get('currentWindow') + const activeFrame = frameStateUtil.getActiveFrame(currentWindow) || Immutable.Map() + const location = activeFrame.get('location', '') + const locationId = getBaseUrl(location) + const locationInfo = state.get('locationInfo', Immutable.Map()) + + const props = {} + // used in renderer + props.isEnabledForPaymentsPublisher = publisherState.enabledForPaymentsPublisher(state, locationId) + props.isVerifiedPublisher = locationInfo.getIn([locationId, 'verified']) + + // used in functions + props.publisherId = locationInfo.getIn([locationId, 'publisher']) + props.hostPattern = getHostPattern(props.publisherId) + + return props } render () { - if (!this.props.locationInfo) { - return null - } - return this.shouldShowAddPublisherButton - ? - - - : null + return + + } } +module.exports = ReduxComponent.connect(PublisherToggle) + const styles = StyleSheet.create({ addPublisherButtonContainer: { boxSizing: 'border-box', @@ -166,5 +129,3 @@ const styles = StyleSheet.create({ backgroundSize: '18px' } }) - -module.exports = PublisherToggle diff --git a/app/renderer/components/navigation/urlBar.js b/app/renderer/components/navigation/urlBar.js index 163906fc193..afb06097334 100644 --- a/app/renderer/components/navigation/urlBar.js +++ b/app/renderer/components/navigation/urlBar.js @@ -33,11 +33,11 @@ const cx = require('../../../../js/lib/classSet') const debounce = require('../../../../js/lib/debounce') const {getSetting} = require('../../../../js/settings') const contextMenus = require('../../../../js/contextMenus') -const UrlUtil = require('../../../../js/lib/urlutil') const {eventElHasAncestorWithClasses, isForSecondaryAction} = require('../../../../js/lib/eventUtil') const {getBaseUrl, isUrl} = require('../../../../js/lib/appUrlUtil') const {getCurrentWindowId} = require('../../currentWindow') const {normalizeLocation} = require('../../../common/lib/suggestion') +const publisherUtil = require('../../../common/lib/publisherUtil') // Icons const iconNoScript = require('../../../../img/url-bar-no-script.svg') @@ -428,17 +428,17 @@ class UrlBar extends React.Component { mergeProps (state, ownProps) { const currentWindow = state.get('currentWindow') const activeFrame = frameStateUtil.getActiveFrame(currentWindow) || Immutable.Map() - const activeTabId = activeFrame.get('tabId') || tabState.TAB_ID_NONE + const activeTabId = activeFrame.get('tabId', tabState.TAB_ID_NONE) const location = tabState.getVisibleURL(state, activeTabId) - const frameLocation = activeFrame.get('location') || '' + const frameLocation = activeFrame.get('location', '') const displayEntry = tabState.getVisibleEntry(state, activeTabId) || Immutable.Map() const displayURL = tabState.getVisibleVirtualURL(state, activeTabId) || '' const hostValue = displayEntry.get('host', '') const protocol = displayEntry.get('protocol', '') const baseUrl = getBaseUrl(location) - const urlbar = activeFrame.getIn(['navbar', 'urlbar']) || Immutable.Map() + const urlbar = activeFrame.getIn(['navbar', 'urlbar'], Immutable.Map()) const urlbarLocation = urlbar.get('location') const selectedIndex = urlbar.getIn(['suggestions', 'selectedIndex']) const allSiteSettings = siteSettingsState.getAllSiteSettings(state, activeFrame.get('isPrivate')) @@ -446,12 +446,6 @@ class UrlBar extends React.Component { // TODO(bridiver) - these definitely needs a helpers const publisherId = state.getIn(['locationInfo', baseUrl, 'publisher']) - const hostPattern = UrlUtil.getHostPattern(publisherId) - const hostSettings = siteSettings.getSiteSettingsForHostPattern(state.get('settings'), hostPattern) - const ledgerPaymentsShown = hostSettings && hostSettings.get('ledgerPaymentsShown') - const visiblePublisher = typeof ledgerPaymentsShown === 'boolean' ? ledgerPaymentsShown : true - const isPublisherButtonEnabled = getSetting(settings.PAYMENTS_ENABLED) && - UrlUtil.isHttpOrHttps(location) && visiblePublisher const activateSearchEngine = urlbar.getIn(['searchDetail', 'activateSearchEngine']) const urlbarSearchDetail = urlbar.get('searchDetail') @@ -485,7 +479,7 @@ class UrlBar extends React.Component { props.noScriptIsVisible = currentWindow.getIn(['ui', 'noScriptInfo', 'isVisible']) || false props.menubarVisible = ownProps.menubarVisible props.activeTabShowingMessageBox = tabState.isShowingMessageBox(state, activeTabId) - props.noBorderRadius = isPublisherButtonEnabled + props.publisherButtonVisible = publisherUtil.shouldShowAddPublisherButton(state, location, publisherId) props.onStop = ownProps.onStop props.titleMode = ownProps.titleMode props.urlbarLocation = urlbarLocation @@ -516,7 +510,7 @@ class UrlBar extends React.Component { className={cx({ urlbarForm: true, [css(styles.urlbarForm_wide)]: this.props.isWideURLbarEnabled, - noBorderRadius: this.props.noBorderRadius + noBorderRadius: this.props.publisherButtonVisible })} action='#' id='urlbar' diff --git a/test/unit/app/common/lib/publisherUtilTest.js b/test/unit/app/common/lib/publisherUtilTest.js new file mode 100644 index 00000000000..eec128a8859 --- /dev/null +++ b/test/unit/app/common/lib/publisherUtilTest.js @@ -0,0 +1,138 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* global describe, it, before, beforeEach, after */ + +const assert = require('assert') +const mockery = require('mockery') +const Immutable = require('immutable') + +require('../../../braveUnit') + +describe('publisherUtil test', function () { + let publisherUtil, getSetting + + before(function () { + mockery.enable({ + warnOnReplace: false, + warnOnUnregistered: false, + useCleanCache: true + }) + + mockery.registerMock('../../../js/settings', { + getSetting: () => getSetting + }) + publisherUtil = require('../../../../../app/common/lib/publisherUtil') + }) + + beforeEach(function () { + getSetting = true + }) + + after(function () { + mockery.disable() + }) + + describe('shouldShowAddPublisherButton', function () { + const state = Immutable.fromJS({ + siteSettings: { + 'https?://brave.com': { + ledgerPayments: false + } + } + }) + + it('location is empty', function () { + const result = publisherUtil.shouldShowAddPublisherButton(state, '', 'brave.com') + assert.equal(result, false) + }) + + it('location is about page', function () { + const result = publisherUtil.shouldShowAddPublisherButton(state, 'about:about', 'about:about') + assert.equal(result, false) + }) + + it('location is file', function () { + const result = publisherUtil.shouldShowAddPublisherButton(state, 'file://test.txt', 'test.txt') + assert.equal(result, false) + }) + + it('payment is disabled', function () { + getSetting = false + const result = publisherUtil.shouldShowAddPublisherButton(state, 'https://brave.com', 'brave.com') + assert.equal(result, false) + }) + + it('everything is ok', function () { + const result = publisherUtil.shouldShowAddPublisherButton(state, 'https://brave.com', 'brave.com') + assert.equal(result, true) + }) + }) + + describe('enabledForPaymentsPublisher', function () { + const state = Immutable.fromJS({ + locationInfo: { + 'https://brave.com': { + exclude: false, + publisher: 'brave.com', + stickyP: false, + timestamp: 1496942403068, + verified: false + } + }, + publisherInfo: { + synopsis: { + 0: { + daysSpent: 0, + duration: 623405, + faviconURL: '', + hoursSpent: 0, + minutesSpent: 10, + percentage: 100, + publisherURL: 'http://brave.com', + score: 9.365888800773842, + secondsSpent: 23, + site: 'brave.com', + verified: false, + views: 1, + weight: 100 + } + } + }, + siteSettings: { + 'https?://brave.com': { + ledgerPayments: false + } + } + }) + + it('host settings is null and is not valid publisher and is not auto suggested', function () { + const result = publisherUtil.enabledForPaymentsPublisher(Immutable.fromJS({}), 'https://brave.com') + assert.equal(result, false) + }) + + it('host settings is null, but publisher synopsis is valid', function () { + let newState = state.set('siteSettings', Immutable.fromJS({})) + const result = publisherUtil.enabledForPaymentsPublisher(newState, 'https://brave.com') + assert.equal(result, true) + }) + + it('host settings is null, publisher synopsis is null, but auto include is on and exclude on off', function () { + let newState = state.set('siteSettings', Immutable.fromJS({})) + newState = newState.set('publisherInfo', Immutable.fromJS({})) + const result = publisherUtil.enabledForPaymentsPublisher(newState, 'https://brave.com') + assert.equal(result, true) + }) + + it('host settings is set and ledgerPayments is false', function () { + const result = publisherUtil.enabledForPaymentsPublisher(state, 'https://brave.com') + assert.equal(result, false) + }) + + it('host settings is set and ledgerPayments is true', function () { + let newState = state.setIn(['siteSettings', 'https?://brave.com', 'ledgerPayments'], true) + const result = publisherUtil.enabledForPaymentsPublisher(newState, 'https://brave.com') + assert.equal(result, true) + }) + }) +}) diff --git a/test/unit/app/renderer/components/navigation/navigationBarTest.js b/test/unit/app/renderer/components/navigation/navigationBarTest.js new file mode 100644 index 00000000000..54a9d525f9a --- /dev/null +++ b/test/unit/app/renderer/components/navigation/navigationBarTest.js @@ -0,0 +1,136 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* global describe, it, before, after */ + +const mockery = require('mockery') +const React = require('react') +const {mount} = require('enzyme') +const assert = require('assert') +const Immutable = require('immutable') +const fakeElectron = require('../../../../lib/fakeElectron') +require('../../../../braveUnit') + +class urlBarFake extends React.Component { + render () { + return null + } +} + +const fakeAppState = Immutable.fromJS({ + locationInfo: { + 'https://brave.com': { + exclude: false, + publisher: 'brave.com', + stickyP: false, + timestamp: 1496942403068, + verified: true + } + }, + publisherInfo: { + synopsis: { + 0: { + daysSpent: 0, + duration: 623405, + faviconURL: '', + hoursSpent: 0, + minutesSpent: 10, + percentage: 100, + publisherURL: 'https://brave.com', + score: 9.365888800773842, + secondsSpent: 23, + site: 'brave.com', + verified: false, + views: 1, + weight: 100 + } + } + }, + siteSettings: { + 'https?://brave.com': { + ledgerPayments: false, + ledgerPaymentsShown: false + } + }, + tabs: [{ + active: true, + tabId: 1, + canGoBack: true, + canGoForward: true, + windowId: 1 + }], + tabsInternal: { + index: { + 1: 0 + } + }, + windows: [] +}) + +const defaultWindowStore = Immutable.fromJS({ + activeFrameKey: 0, + frames: [{ + key: 0, + tabId: 1, + location: 'https://brave.com' + }], + tabs: [{ + key: 0 + }] +}) + +describe('NavigationBar component', function () { + let NavigationBar, windowStore, appStore + + before(function () { + mockery.enable({ + warnOnReplace: false, + warnOnUnregistered: false, + useCleanCache: true + }) + mockery.registerMock('electron', fakeElectron) + mockery.registerMock('../../../js/settings', { + getSetting: () => true + }) + mockery.registerMock('../../../../img/url-bar-no-script.svg') + mockery.registerMock('../../../extensions/brave/img/urlbar/browser_URL_fund_no_verified.svg') + mockery.registerMock('../../../extensions/brave/img/urlbar/browser_URL_fund_yes_verified.svg') + mockery.registerMock('../../../extensions/brave/img/urlbar/browser_URL_fund_no.svg') + mockery.registerMock('../../../extensions/brave/img/urlbar/browser_URL_fund_yes.svg') + mockery.registerMock('../../../extensions/brave/img/caret_down_grey.svg') + mockery.registerMock('./urlBar', urlBarFake) + windowStore = require('../../../../../../js/stores/windowStore') + appStore = require('../../../../../../js/stores/appStoreRenderer') + NavigationBar = require('../../../../../../app/renderer/components/navigation/navigationBar') + }) + + after(function () { + mockery.disable() + }) + + describe('publisherToggle', function () { + it('do not render if about page', function () { + windowStore.state = defaultWindowStore.setIn(['frames', 0, 'location'], 'about:preferences') + appStore.state = fakeAppState + + const wrapper = mount() + assert.equal(wrapper.find('PublisherToggle').length, 0) + }) + + it('do not render if publisher is permanently hidden', function () { + windowStore.state = defaultWindowStore + appStore.state = fakeAppState + + const wrapper = mount() + assert.equal(wrapper.find('PublisherToggle').length, 0) + }) + + it('render if ok', function () { + windowStore.state = defaultWindowStore + appStore.state = fakeAppState.setIn(['siteSettings', 'https?://brave.com', 'ledgerPaymentsShown'], true) + + const wrapper = mount() + assert.equal(wrapper.find('PublisherToggle').length, 1) + }) + }) +}) diff --git a/test/unit/app/renderer/components/navigation/publisherToggleTest.js b/test/unit/app/renderer/components/navigation/publisherToggleTest.js index fe461a397d2..88b1dc50841 100644 --- a/test/unit/app/renderer/components/navigation/publisherToggleTest.js +++ b/test/unit/app/renderer/components/navigation/publisherToggleTest.js @@ -1,41 +1,66 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ /* global describe, it, before, after */ + const mockery = require('mockery') -const {shallow} = require('enzyme') +const {mount} = require('enzyme') const assert = require('assert') const Immutable = require('immutable') const fakeElectron = require('../../../../lib/fakeElectron') -const settingsConst = require('../../../../../../js/constants/settings') -const {getHostPattern} = require('../../../../../../js/lib/urlutil') -let PublisherToggle require('../../../../braveUnit') -describe('PublisherToggle component', function () { - const getUrlOrigin = url => url.split('/').slice(0, 3).join('/') - const getHostName = url => getUrlOrigin(url).split('/').slice(2).join('/') - const getPattern = pattern => getHostPattern(getHostName(pattern)) - - const locationInfo = (url, exclude, verified) => Immutable.fromJS({ - [url]: { - 'publisher': getHostName(url), - 'exclude': exclude, - 'verified': verified +const fakeAppState = Immutable.fromJS({ + locationInfo: { + 'https://brave.com': { + exclude: false, + publisher: 'brave.com', + stickyP: false, + timestamp: 1496942403068, + verified: true } - }) - const hostPattern = (pattern, isEnabled, shouldShow) => Immutable.fromJS({ - [getPattern(pattern)]: { - 'ledgerPayments': isEnabled, - 'ledgerPaymentsShown': shouldShow + }, + publisherInfo: { + synopsis: { + 0: { + daysSpent: 0, + duration: 623405, + faviconURL: '', + hoursSpent: 0, + minutesSpent: 10, + percentage: 100, + publisherURL: 'https://brave.com', + score: 9.365888800773842, + secondsSpent: 23, + site: 'brave.com', + verified: false, + views: 1, + weight: 100 + } } - }) - const publisherSynopsis = (url, verified) => Immutable.fromJS([{ - 'site': getHostName(url), - 'publisherURL': url, - 'verified': verified - }]) - const paymentsEnabled = settingsConst.PAYMENTS_ENABLED - const autoSuggestSites = settingsConst.AUTO_SUGGEST_SITES - const url1 = 'https://clifton.io/sharing-my-passion-for-mercedes-benz' - const aboutPage = 'about:preferences' + }, + siteSettings: { + 'https?://brave.com': { + ledgerPayments: false, + ledgerPaymentsShown: false + } + } +}) + +const defaultWindowStore = Immutable.fromJS({ + activeFrameKey: 0, + frames: [{ + key: 0, + tabId: 1, + location: 'https://brave.com' + }], + tabs: [{ + key: 0 + }] +}) + +describe('PublisherToggle component', function () { + let PublisherToggle, windowStore, appStore before(function () { mockery.enable({ @@ -43,123 +68,58 @@ describe('PublisherToggle component', function () { warnOnUnregistered: false, useCleanCache: true }) + mockery.registerMock('electron', fakeElectron) mockery.registerMock('../../../extensions/brave/img/urlbar/browser_URL_fund_no_verified.svg') mockery.registerMock('../../../extensions/brave/img/urlbar/browser_URL_fund_yes_verified.svg') mockery.registerMock('../../../extensions/brave/img/urlbar/browser_URL_fund_no.svg') mockery.registerMock('../../../extensions/brave/img/urlbar/browser_URL_fund_yes.svg') - mockery.registerMock('../../../../js/settings', { getSetting: (settingKey, settingsCollection, value) => { - if (settingKey === paymentsEnabled || settingKey === autoSuggestSites) { - return true - } - return false - }}) - mockery.registerMock('electron', fakeElectron) - window.chrome = fakeElectron + mockery.registerMock('../../../../js/settings', { + getSetting: () => true + }) + windowStore = require('../../../../../../js/stores/windowStore') + appStore = require('../../../../../../js/stores/appStoreRenderer') PublisherToggle = require('../../../../../../app/renderer/components/navigation/publisherToggle') }) + after(function () { mockery.disable() }) describe('default behaviour (when autoSuggest is ON)', function () { - it('show as enabled if site is on synopsis list (siteSettings is empty)', function () { - const wrapper = shallow( - - ) - assert.equal(wrapper.find('[data-test-id="publisherButton"]').length, 1) - assert.equal(wrapper.props()['data-test-authorized'], true) - }) - it('show as enabled if hostPattern is on siteSettings list (synopsis is empty)', function () { - const wrapper = shallow( - - ) - assert.equal(wrapper.find('[data-test-id="publisherButton"]').length, 1) - assert.equal(wrapper.props()['data-test-authorized'], true) - }) - it('show as enabled if url exists in locationInfo (both synopsis and siteSettings are empty)', function () { - const wrapper = shallow( - - ) - assert.equal(wrapper.find('[data-test-id="publisherButton"]').length, 1) - assert.equal(wrapper.props()['data-test-authorized'], true) - }) it('Show as disabled if publisher is on exclusion list', function () { - const wrapper = shallow( - - ) + windowStore.state = defaultWindowStore + appStore.state = fakeAppState.setIn(['locationInfo', 'https://brave.com', 'exclude'], true) + + const wrapper = mount() assert.equal(wrapper.find('[data-test-id="publisherButton"]').length, 1) - assert.equal(wrapper.props()['data-test-authorized'], false) + assert.equal(wrapper.find('span').props()['data-test-authorized'], false) }) + it('Show as verified if publisher is shown as verified on locationInfo list', function () { - const wrapper = shallow( - - ) + windowStore.state = defaultWindowStore + appStore.state = fakeAppState + const wrapper = mount() assert.equal(wrapper.find('[data-test-id="publisherButton"]').length, 1) - assert.equal(wrapper.props()['data-test-verified'], true) - }) - it('do not render if about page', function () { - const wrapper = shallow( - - ) - assert.equal(wrapper.find('[data-test-id="publisherButton"]').length, 0) + assert.equal(wrapper.find('span').props()['data-test-verified'], true) }) }) describe('user interaction behaviour', function () { - it('do not render if publisher is permanently hidden', function () { - const wrapper = shallow( - - ) - assert.equal(wrapper.find('[data-test-id="publisherButton"]').length, 0) - }) it('show as enabled if ledgerPayments is true for that publisher', function () { - const wrapper = shallow( - - ) + windowStore.state = defaultWindowStore + appStore.state = fakeAppState.setIn(['siteSettings', 'https?://brave.com', 'ledgerPayments'], true) + + const wrapper = mount() assert.equal(wrapper.find('[data-test-id="publisherButton"]').length, 1) - assert.equal(wrapper.props()['data-test-authorized'], true) + assert.equal(wrapper.find('span').props()['data-test-authorized'], true) }) + it('Show as disabled if ledgerPayments is false for that publisher', function () { - const wrapper = shallow( - - ) - assert.equal(wrapper.props()['data-test-authorized'], false) + windowStore.state = defaultWindowStore + appStore.state = fakeAppState + + const wrapper = mount() + assert.equal(wrapper.find('span').props()['data-test-authorized'], false) }) }) })