Skip to content

Commit

Permalink
[ENG-4648] Opt out of SHARE indexing (#1998)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
futa-ikeda authored Sep 25, 2023
1 parent 261ea17 commit 9722d5d
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
50 changes: 50 additions & 0 deletions app/settings/account/-components/opt-out/component.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
41 changes: 41 additions & 0 deletions app/settings/account/-components/opt-out/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<Panel
data-test-opt-out-panel
data-analytics-scope='Indexing opt out panel'
as |panel|
>
<panel.heading @title={{t 'settings.account.opt-out.title'}} />
<panel.body>
<p data-test-opt-out-help-text>
{{t 'settings.account.opt-out.description' htmlSafe=true}}
</p>
<label data-test-indexing-opt-out-label>
<input
name='indexingPreference'
type='radio'
value={{false}}
checked={{this.allowIndexingIsFalse}}
{{on 'click' (action (mut this.indexingPreference) false)}}
/>
{{t 'settings.account.opt-out.opt-out-label'}}
</label>
<br />
<label data-test-indexing-opt-in-label>
<input
name='indexingPreference'
type='radio'
value={{true}}
checked={{this.indexingPreference}}
{{on 'click' (action (mut this.indexingPreference) true)}}
/>
{{t 'settings.account.opt-out.opt-in-label'}}
</label>
<br />
<Button
data-test-update-indexing-preference-button
data-analytics-name='Submit'
{{on 'click' (perform this.updateIndexingPreference)}}
>
{{t 'settings.account.opt-out.button-label'}}
</Button>
</panel.body>
</Panel>
1 change: 1 addition & 0 deletions app/settings/account/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<Settings::Account::-Components::DefaultRegion />
<Settings::Account::-Components::ConnectedIdentities />
<Settings::Account::-Components::AffiliatedInstitutions />
<Settings::Account::-Components::OptOut />
<Settings::Account::-Components::ChangePassword />
<Settings::Account::-Components::Security />
<Settings::Account::-Components::RequestDeactivation />
1 change: 1 addition & 0 deletions mirage/factories/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export default Factory.extend<MirageUser & UserTraits>({
},
acceptedTermsOfService: true,
canViewReviews: false,
allowIndexing: null,
social: {},
employment() {
const employmentCount = faker.random.number({ min: 1, max: 3 });
Expand Down
Original file line number Diff line number Diff line change
@@ -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`<Settings::Account::-Components::OptOut />`);

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);
});
});
8 changes: 8 additions & 0 deletions translations/en-us.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2561,6 +2561,14 @@ settings:
confirm_button_text: Remove
remove_fail: 'Revocation request failed. Please contact <a href="mailto:{supportEmail}">{supportEmail}</a> 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. <br /> <a href="https://share.osf.io/">Learn more about SHARE</a>'
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 <a href="mailto:{supportEmail}">{supportEmail}</a>.'
button-label: 'Update'
addons:
title: 'Configure add-on accounts'
notifications:
Expand Down

0 comments on commit 9722d5d

Please sign in to comment.