Remove the `enableFeatureMoreAndroidExtensions` flag (#12617)

This commit is contained in:
William Durand 2023-11-20 12:55:45 +01:00 коммит произвёл GitHub
Родитель 3621e596aa
Коммит 8265e60635
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 75 добавлений и 284 удалений

Просмотреть файл

@ -85,7 +85,6 @@ module.exports = {
'cookieSecure',
'defaultLang',
'enableDevTools',
'enableFeatureMoreAndroidExtensions',
'enableFeatureVPNPromo',
'enableFeatureFeedbackForm',
'enableFeatureFeedbackFormLinks',
@ -414,8 +413,6 @@ module.exports = {
enableFeatureVPNPromo: true,
enableFeatureMoreAndroidExtensions: true,
enableFeatureFeedbackForm: true,
enableFeatureFeedbackFormLinks: false,

Просмотреть файл

@ -42,7 +42,5 @@ module.exports = {
extensionWorkshopUrl: 'https://extensionworkshop-dev.allizom.org',
enableFeatureMoreAndroidExtensions: true,
enableFeatureFeedbackFormLinks: true,
};

Просмотреть файл

@ -80,7 +80,5 @@ module.exports = {
extensionWorkshopUrl: 'https://extensionworkshop-dev.allizom.org',
enableFeatureMoreAndroidExtensions: true,
enableFeatureFeedbackFormLinks: true,
};

Просмотреть файл

@ -4,7 +4,6 @@ import * as React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { compose } from 'redux';
import config from 'config';
import {
ADDON_TYPE_EXTENSION,
@ -49,14 +48,9 @@ type PropsFromState = {|
lang: string,
|};
type DefaultProps = {|
_config: typeof config,
|};
type InternalProps = {|
...Props,
...PropsFromState,
...DefaultProps,
history: ReactRouterHistoryType,
i18n: I18nType,
|};
@ -64,10 +58,6 @@ type InternalProps = {|
type SelectOption = {| children: string, value: string |};
export class SearchFiltersBase extends React.Component<InternalProps> {
static defaultProps: {| ...DefaultProps |} = {
_config: config,
};
onSelectElementChange: (event: SelectEvent) => boolean = (
event: SelectEvent,
) => {
@ -204,7 +194,7 @@ export class SearchFiltersBase extends React.Component<InternalProps> {
}
render(): React.Node {
const { _config, clientApp, filters, i18n } = this.props;
const { clientApp, filters, i18n } = this.props;
const expandableCardName = 'SearchFilters';
const selectedSortFields = filters.sort
@ -214,15 +204,6 @@ export class SearchFiltersBase extends React.Component<InternalProps> {
: [''];
const selectedSort = selectedSortFields[0];
// When we'll work on https://github.com/mozilla/addons-frontend/issues/12401,
// we won't need the variable anymore because we'll want to show the Badging
// filter unconditionally.
const hideBadgingFilterOnAndroid = _config.get(
'enableFeatureMoreAndroidExtensions',
)
? false
: clientApp === CLIENT_APP_ANDROID;
return (
<ExpandableCard
className={expandableCardName}
@ -269,28 +250,25 @@ export class SearchFiltersBase extends React.Component<InternalProps> {
</div>
)}
{/* Hide the badging filter on Android. */}
{!hideBadgingFilterOnAndroid && (
<div>
<label
className="SearchFilters-Badging-label SearchFilters-label"
htmlFor="SearchFilters-Badging"
>
{i18n.gettext('Badging')}
</label>
<Select
className="SearchFilters-Badging SearchFilters-select"
id="SearchFilters-Badging"
name="promoted"
onChange={this.onSelectElementChange}
value={filters.promoted || NO_FILTER}
>
{this.promotedOptions().map((option) => {
return <option key={option.value} {...option} />;
})}
</Select>
</div>
)}
<div>
<label
className="SearchFilters-Badging-label SearchFilters-label"
htmlFor="SearchFilters-Badging"
>
{i18n.gettext('Badging')}
</label>
<Select
className="SearchFilters-Badging SearchFilters-select"
id="SearchFilters-Badging"
name="promoted"
onChange={this.onSelectElementChange}
value={filters.promoted || NO_FILTER}
>
{this.promotedOptions().map((option) => {
return <option key={option.value} {...option} />;
})}
</Select>
</div>
</form>
</ExpandableCard>
);

Просмотреть файл

@ -1,12 +1,10 @@
import { oneLine } from 'common-tags';
import config from 'config';
import invariant from 'invariant';
import {
ADDON_TYPE_EXTENSION,
APPVERSION_FOR_ANDROID,
CLIENT_APP_ANDROID,
RECOMMENDED,
} from 'amo/constants';
import log from 'amo/logger';
import { USER_AGENT_OS_ANDROID, USER_AGENT_OS_IOS } from 'amo/reducers/api';
@ -42,7 +40,6 @@ export const paramsToFilter = {
};
export function addVersionCompatibilityToFilters({
_config = config,
filters,
userAgentInfo,
} = {}) {
@ -74,27 +71,20 @@ export function addVersionCompatibilityToFilters({
log.debug(oneLine`Setting "addonType" to "extension" for Android.`);
newFilters.addonType = ADDON_TYPE_EXTENSION;
if (_config.get('enableFeatureMoreAndroidExtensions')) {
// If the browser is not Firefox for Android, we want to filter out
// extensions to only the limited set, so we force-set the value of
// `compatibleWithVersion`. This should be removed after General
// Avaibility.
//
// This will apply even to Firefox Desktop browsing Android pages.
if (
userAgentInfo.browser.name !== 'Firefox' ||
userAgentInfo.os.name !== USER_AGENT_OS_ANDROID
) {
log.debug(oneLine`Setting "compatibleWithVersion" to
// If the browser is not Firefox for Android, we want to filter out
// extensions to only the limited set, so we force-set the value of
// `compatibleWithVersion`. This should be removed after General
// Avaibility.
//
// This will apply even to Firefox Desktop browsing Android pages.
if (
userAgentInfo.browser.name !== 'Firefox' ||
userAgentInfo.os.name !== USER_AGENT_OS_ANDROID
) {
log.debug(oneLine`Setting "compatibleWithVersion" to
"${APPVERSION_FOR_ANDROID}" for Android because the browser is not
Firefox for Android.`);
newFilters.compatibleWithVersion = APPVERSION_FOR_ANDROID;
}
} else {
// Otherwise, we only want recommended extensions.
log.debug(oneLine`Setting "promoted" to "recommended" for Android because
enableFeatureMoreAndroidExtensions is disabled.`);
newFilters.promoted = RECOMMENDED;
newFilters.compatibleWithVersion = APPVERSION_FOR_ANDROID;
}
}

Просмотреть файл

@ -3,7 +3,6 @@
import { oneLine } from 'common-tags';
import invariant from 'invariant';
import { mozCompare } from 'addons-moz-compare';
import config from 'config';
import {
USER_AGENT_BROWSER_FIREFOX,
@ -20,10 +19,8 @@ import {
INCOMPATIBLE_OVER_MAX_VERSION,
INCOMPATIBLE_UNDER_MIN_VERSION,
INCOMPATIBLE_UNSUPPORTED_PLATFORM,
RECOMMENDED,
} from 'amo/constants';
import log from 'amo/logger';
import { getPromotedCategory } from 'amo/utils/addons';
import type { AddonVersionType } from 'amo/reducers/versions';
import type { UserAgentInfoType } from 'amo/reducers/api';
import type { AddonType } from 'amo/types/addons';
@ -112,27 +109,11 @@ export const isFirefoxForIOS = (userAgentInfo: UserAgentInfoType): boolean => {
};
export const isAndroidInstallable = ({
_config = config,
addon,
}: {
_config?: typeof config,
addon: AddonType | null,
}): boolean => {
if (!addon || addon.type !== ADDON_TYPE_EXTENSION) {
return false;
}
// When we enable this feature, extensions should be installable on Android.
if (_config.get('enableFeatureMoreAndroidExtensions')) {
return true;
}
// Otherwise, only extensions that are recommended on android are considered
// compatible, see: https://github.com/mozilla/addons-frontend/issues/9713.
return (
getPromotedCategory({ addon, clientApp: CLIENT_APP_ANDROID }) ===
RECOMMENDED
);
return addon?.type === ADDON_TYPE_EXTENSION;
};
export type IsCompatibleWithUserAgentParams = {|

Просмотреть файл

@ -3,7 +3,6 @@
// eslint-disable-next-line testing-library/no-manual-cleanup
import { cleanup, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import config from 'config';
import { setViewContext } from 'amo/actions/viewContext';
import { createApiError } from 'amo/api/index';
@ -40,17 +39,11 @@ import {
fakeCategory,
getElement,
getElements,
getMockConfig,
getSearchErrorHandlerId,
renderPage as defaultRender,
screen,
} from 'tests/unit/helpers';
// We need to control the config, which is used by SearchFilters, but we are
// rendering the SearchPage component, so we have to control it via mocking as
// opposed to injecting a _config prop.
jest.mock('config');
describe(__filename, () => {
let history;
let store;
@ -60,11 +53,6 @@ describe(__filename, () => {
beforeEach(() => {
store = dispatchClientMetadata({ clientApp, lang }).store;
const mockConfig = getMockConfig({});
config.get.mockImplementation((key) => {
return mockConfig[key];
});
});
const getLocation = ({ category, query, tag, type }) => {
@ -847,33 +835,7 @@ describe(__filename, () => {
});
});
it('does not display the addonType or badging filters on Android when enableFeatureMoreAndroidExtensions is disabled', () => {
const mockConfig = getMockConfig({
enableFeatureMoreAndroidExtensions: false,
});
config.get.mockImplementation((key) => {
return mockConfig[key];
});
dispatchClientMetadata({ clientApp: CLIENT_APP_ANDROID, store });
render({ location: `/${lang}/${CLIENT_APP_ANDROID}/search/` });
expect(
screen.queryByRole('combobox', { name: 'Add-on Type' }),
).not.toBeInTheDocument();
expect(
screen.queryByRole('combobox', { name: 'Badging' }),
).not.toBeInTheDocument();
});
it('displays the badging filter but not the addonType one on Android when enableFeatureMoreAndroidExtensions is enabled', () => {
const mockConfig = getMockConfig({
enableFeatureMoreAndroidExtensions: true,
});
config.get.mockImplementation((key) => {
return mockConfig[key];
});
it('displays the badging filter but not the addonType one on Android', () => {
dispatchClientMetadata({ clientApp: CLIENT_APP_ANDROID, store });
render({ location: `/${lang}/${CLIENT_APP_ANDROID}/search/` });

Просмотреть файл

@ -6,7 +6,6 @@ import {
APPVERSION_FOR_ANDROID,
CLIENT_APP_ANDROID,
CLIENT_APP_FIREFOX,
RECOMMENDED,
} from 'amo/constants';
import {
addVersionCompatibilityToFilters,
@ -19,7 +18,6 @@ import {
} from 'amo/searchUtils';
import {
dispatchClientMetadata,
getFakeConfig,
userAgentsByPlatform,
} from 'tests/unit/helpers';
@ -104,39 +102,12 @@ describe(__filename, () => {
});
describe('when clientApp is CLIENT_APP_ANDROID', () => {
it('adds addonType, compatibleWithVersion and promoted', () => {
const _config = getFakeConfig({
enableFeatureMoreAndroidExtensions: false,
});
it('does not set promoted and does not override compatibleWithVersion when browser is Firefox for Android', () => {
const { state } = dispatchClientMetadata({
userAgent: userAgentsByPlatform.android.firefox70,
});
const newFilters = addVersionCompatibilityToFilters({
_config,
filters: { clientApp: CLIENT_APP_ANDROID, query: 'foo' },
userAgentInfo: state.api.userAgentInfo,
});
expect(newFilters).toEqual({
addonType: ADDON_TYPE_EXTENSION,
clientApp: CLIENT_APP_ANDROID,
compatibleWithVersion: '70.0',
promoted: RECOMMENDED,
query: 'foo',
});
});
it('does not set promoted and does not override compatibleWithVersion when enableFeatureMoreAndroidExtensions is enabled and browser is Firefox for Android', () => {
const _config = getFakeConfig({
enableFeatureMoreAndroidExtensions: true,
});
const { state } = dispatchClientMetadata({
userAgent: userAgentsByPlatform.android.firefox70,
});
const newFilters = addVersionCompatibilityToFilters({
_config,
filters: { clientApp: CLIENT_APP_ANDROID, query: 'foo' },
userAgentInfo: state.api.userAgentInfo,
});
@ -154,15 +125,11 @@ describe(__filename, () => {
userAgentsByPlatform.windows.firefox40,
userAgentsByPlatform.mac.chrome41,
])(
'does not set promoted but overrides compatibleWithVersion when enableFeatureMoreAndroidExtensions is enabled and browser is not Firefox for Android - userAgent: %s',
'does not set promoted but overrides compatibleWithVersion when browser is not Firefox for Android - userAgent: %s',
(userAgent) => {
const _config = getFakeConfig({
enableFeatureMoreAndroidExtensions: true,
});
const { state } = dispatchClientMetadata({ userAgent });
const newFilters = addVersionCompatibilityToFilters({
_config,
filters: { clientApp: CLIENT_APP_ANDROID, query: 'foo' },
userAgentInfo: state.api.userAgentInfo,
});

Просмотреть файл

@ -34,7 +34,6 @@ import {
createInternalVersionWithLang,
fakeAddon,
fakeVersion,
getFakeConfig,
getFakeLogger,
userAgents,
userAgentsByPlatform,
@ -907,141 +906,62 @@ describe(__filename, () => {
});
describe('isAndroidInstallable', () => {
describe('with enableFeatureMoreAndroidExtensions enabled', () => {
const _config = getFakeConfig({
enableFeatureMoreAndroidExtensions: true,
it('returns true if the add-on is recommended on android', () => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: { category: RECOMMENDED, apps: [CLIENT_APP_ANDROID] },
});
it('returns true if the add-on is recommended on android', () => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: { category: RECOMMENDED, apps: [CLIENT_APP_ANDROID] },
});
expect(isAndroidInstallable({ _config, addon })).toEqual(true);
});
it('returns true if the add-on is recommended on android and desktop', () => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: {
category: RECOMMENDED,
apps: [CLIENT_APP_ANDROID, CLIENT_APP_FIREFOX],
},
});
expect(isAndroidInstallable({ _config, addon })).toEqual(true);
});
it.each(validAddonTypes.filter((type) => type !== ADDON_TYPE_EXTENSION))(
'returns false for a %s, even if the add-on is recommended on android',
(type) => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: { category: RECOMMENDED, apps: [CLIENT_APP_ANDROID] },
type,
});
expect(isAndroidInstallable({ _config, addon })).toEqual(false);
},
);
it.each(
ALL_PROMOTED_CATEGORIES.filter((category) => category !== RECOMMENDED),
)('returns true when the add-on is %s on android', (category) => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: { category, apps: [CLIENT_APP_ANDROID] },
});
expect(isAndroidInstallable({ _config, addon })).toEqual(true);
});
it('returns true when add-on is not promoted', () => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: null,
});
expect(isAndroidInstallable({ _config, addon })).toEqual(true);
});
it('returns false if addon is null', () => {
expect(isAndroidInstallable({ _config, addon: null })).toEqual(false);
});
expect(isAndroidInstallable({ addon })).toEqual(true);
});
describe('with enableFeatureMoreAndroidExtensions disabled', () => {
const _config = getFakeConfig({
enableFeatureMoreAndroidExtensions: false,
it('returns true if the add-on is recommended on android and desktop', () => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: {
category: RECOMMENDED,
apps: [CLIENT_APP_ANDROID, CLIENT_APP_FIREFOX],
},
});
it('returns true if the add-on is recommended on android', () => {
expect(isAndroidInstallable({ addon })).toEqual(true);
});
it.each(validAddonTypes.filter((type) => type !== ADDON_TYPE_EXTENSION))(
'returns false for a %s, even if the add-on is recommended on android',
(type) => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: { category: RECOMMENDED, apps: [CLIENT_APP_ANDROID] },
type,
});
expect(isAndroidInstallable({ _config, addon })).toEqual(true);
expect(isAndroidInstallable({ addon })).toEqual(false);
},
);
it.each(
ALL_PROMOTED_CATEGORIES.filter((category) => category !== RECOMMENDED),
)('returns true when the add-on is %s on android', (category) => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: { category, apps: [CLIENT_APP_ANDROID] },
});
it('returns true if the add-on is recommended on android and desktop', () => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: {
category: RECOMMENDED,
apps: [CLIENT_APP_ANDROID, CLIENT_APP_FIREFOX],
},
});
expect(isAndroidInstallable({ addon })).toEqual(true);
});
expect(isAndroidInstallable({ _config, addon })).toEqual(true);
it('returns true when add-on is not promoted', () => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: null,
});
it.each(validAddonTypes.filter((type) => type !== ADDON_TYPE_EXTENSION))(
'returns false for a %s, even if the add-on is recommended on android',
(type) => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: { category: RECOMMENDED, apps: [CLIENT_APP_ANDROID] },
type,
});
expect(isAndroidInstallable({ addon })).toEqual(true);
});
expect(isAndroidInstallable({ _config, addon })).toEqual(false);
},
);
it('returns false if the add-on is recommended but not on android', () => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: { category: RECOMMENDED, apps: [CLIENT_APP_FIREFOX] },
});
expect(isAndroidInstallable({ _config, addon })).toEqual(false);
});
it.each(
ALL_PROMOTED_CATEGORIES.filter((category) => category !== RECOMMENDED),
)('returns false if the add-on is %s on android', (category) => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: { category, apps: [CLIENT_APP_ANDROID] },
});
expect(isAndroidInstallable({ _config, addon })).toEqual(false);
});
it('returns false if the add-on is not promoted', () => {
const addon = createInternalAddonWithLang({
...fakeAddon,
promoted: null,
});
expect(isAndroidInstallable({ _config, addon })).toEqual(false);
});
it('returns false if addon is null', () => {
expect(isAndroidInstallable({ _config, addon: null })).toEqual(false);
});
it('returns false if addon is null', () => {
expect(isAndroidInstallable({ addon: null })).toEqual(false);
});
});
});