From 9722d5d540acad87247fc309029f5294bc3e2b26 Mon Sep 17 00:00:00 2001 From: futa-ikeda <51409893+futa-ikeda@users.noreply.github.com> Date: Mon, 25 Sep 2023 09:16:00 -0400 Subject: [PATCH] [ENG-4648] Opt out of SHARE indexing (#1998) * Add allowIndexing attr to user model * Add opt-out panel to user-settings * Add test * Update wording * Use constructor; Match mirage default with BE default --- app/models/user.ts | 1 + .../account/-components/opt-out/component.ts | 50 +++++++++++++++++++ .../account/-components/opt-out/template.hbs | 41 +++++++++++++++ app/settings/account/template.hbs | 1 + mirage/factories/user.ts | 1 + .../account/-components/opt-out-test.ts | 42 ++++++++++++++++ translations/en-us.yml | 8 +++ 7 files changed, 144 insertions(+) create mode 100644 app/settings/account/-components/opt-out/component.ts create mode 100644 app/settings/account/-components/opt-out/template.hbs create mode 100644 tests/integration/routes/settings/account/-components/opt-out-test.ts diff --git a/app/models/user.ts b/app/models/user.ts index aa7552b400c..55854658823 100644 --- a/app/models/user.ts +++ b/app/models/user.ts @@ -94,6 +94,7 @@ export default class UserModel extends OsfModel.extend(Validations) { @attr('object') social!: {}; @attr('array') employment!: Employment[]; @attr('array') education!: Education[]; + @attr('boolean', { allowNull: true }) allowIndexing?: boolean; @belongsTo('region', { async: false }) defaultRegion!: RegionModel; diff --git a/app/settings/account/-components/opt-out/component.ts b/app/settings/account/-components/opt-out/component.ts new file mode 100644 index 00000000000..be65de027c3 --- /dev/null +++ b/app/settings/account/-components/opt-out/component.ts @@ -0,0 +1,50 @@ +import Component from '@glimmer/component'; +import { inject as service } from '@ember/service'; +import { tracked } from '@glimmer/tracking'; +import CurrentUserService from 'ember-osf-web/services/current-user'; +import { restartableTask } from 'ember-concurrency'; +import { waitFor } from '@ember/test-waiters'; +import config from 'ember-get-config'; +import IntlService from 'ember-intl/services/intl'; + +import captureException, { getApiErrorMessage } from 'ember-osf-web/utils/capture-exception'; + +const { support: { supportEmail } } = config; + +export default class OptOutComponent extends Component { + @service currentUser!: CurrentUserService; + @service intl!: IntlService; + @service toast!: Toastr; + + @tracked indexingPreference?: boolean; + + get allowIndexingIsFalse() { + // allowIndexing is null by default + return this.currentUser.user?.allowIndexing === false; + } + + constructor(owner: unknown, args: any) { + super(owner, args); + this.indexingPreference = this.currentUser.user?.allowIndexing; + } + + @restartableTask + @waitFor + async updateIndexingPreference() { + if (!this.currentUser.user) { + return; + } + try { + this.currentUser.user.allowIndexing = this.indexingPreference; + await this.currentUser.user.save(); + this.toast.success(this.intl.t('settings.account.opt-out.success')); + } catch (e) { + const errorMessage = this.intl.t( + 'settings.account.opt-out.error', + { supportEmail, htmlSafe: true }, + ); + captureException(e, { errorMessage: errorMessage.toString() }); + this.toast.error(getApiErrorMessage(e), errorMessage as string); + } + } +} diff --git a/app/settings/account/-components/opt-out/template.hbs b/app/settings/account/-components/opt-out/template.hbs new file mode 100644 index 00000000000..2cdb2d3e626 --- /dev/null +++ b/app/settings/account/-components/opt-out/template.hbs @@ -0,0 +1,41 @@ + + + +

+ {{t 'settings.account.opt-out.description' htmlSafe=true}} +

+ +
+ +
+ +
+
diff --git a/app/settings/account/template.hbs b/app/settings/account/template.hbs index 26e17808f1f..4853aedb702 100644 --- a/app/settings/account/template.hbs +++ b/app/settings/account/template.hbs @@ -3,6 +3,7 @@ + diff --git a/mirage/factories/user.ts b/mirage/factories/user.ts index 5404f19779c..33fa6b1db7d 100644 --- a/mirage/factories/user.ts +++ b/mirage/factories/user.ts @@ -52,6 +52,7 @@ export default Factory.extend({ }, acceptedTermsOfService: true, canViewReviews: false, + allowIndexing: null, social: {}, employment() { const employmentCount = faker.random.number({ min: 1, max: 3 }); diff --git a/tests/integration/routes/settings/account/-components/opt-out-test.ts b/tests/integration/routes/settings/account/-components/opt-out-test.ts new file mode 100644 index 00000000000..2d08da0253a --- /dev/null +++ b/tests/integration/routes/settings/account/-components/opt-out-test.ts @@ -0,0 +1,42 @@ +import { TestContext } from 'ember-test-helpers'; +import Service from '@ember/service'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; +import { percySnapshot } from 'ember-percy'; +import { setupRenderingTest } from 'ember-qunit'; +import { module, test } from 'qunit'; + +const currentUserStub = Service.extend({ + user: { + allowIndexing: null, + }, +}); + +module('Integration | routes | settings | account | -components | opt-out', hooks => { + setupRenderingTest(hooks); + + test('default allowIndexing: null', async function(this: TestContext, assert) { + this.owner.register('service:currentUser', currentUserStub); + await render(hbs``); + + assert.dom('[data-test-opt-out-panel]').exists('opt-out panel exists'); + assert.dom('[data-test-opt-out-panel] [data-test-panel-heading]') + .hasText( + 'Opt out of SHARE indexing', + 'title is correct', + ); + assert.dom('[data-test-opt-out-help-text]').exists('description exists'); + assert.dom('[data-test-indexing-opt-out-label]').containsText( + 'Opt out of SHARE indexing', 'opt out label is correct', + ); + assert.dom('[data-test-indexing-opt-in-label]').containsText( + 'Opt in to SHARE indexing', 'opt in label is correct', + ); + assert.dom('[data-test-indexing-opt-out-label] input').isNotChecked('Opt out radio button is not checked'); + assert.dom('[data-test-indexing-opt-in-label] input').isNotChecked('Opt in radio button is not checked'); + assert.dom('[data-test-update-indexing-preference-button]').containsText( + 'Update', 'update button is correct', + ); + await percySnapshot(assert); + }); +}); diff --git a/translations/en-us.yml b/translations/en-us.yml index 3b56eca5f12..b9efbeffea6 100644 --- a/translations/en-us.yml +++ b/translations/en-us.yml @@ -2561,6 +2561,14 @@ settings: confirm_button_text: Remove remove_fail: 'Revocation request failed. Please contact {supportEmail} if the problem persists.' remove_success: 'You have revoked this connected identity.' + opt-out: + title: 'Opt out of SHARE indexing' + description: 'By default, OSF users are indexed into SHARE, a free, open dataset of research metadata. This allows SHARE to include your user profile and research in its database, which is used by search engines and other services to make research more discoverable. You can opt out of this indexing by checking the box below. NOTE: Public projects, files, registrations, and preprints will still be indexed in SHARE.
Learn more about SHARE' + opt-out-label: 'Opt out of SHARE indexing' + opt-in-label: 'Opt in to SHARE indexing' + success: 'Successfully updated SHARE indexing preference.' + error: 'Could not update SHARE indexing preference. Try again in a few minutes. If the issue persists, please report it to {supportEmail}.' + button-label: 'Update' addons: title: 'Configure add-on accounts' notifications: