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

CC-1296 add refresh from github button #1867

Merged
merged 8 commits into from
Jun 21, 2024
22 changes: 15 additions & 7 deletions app/components/settings/profile-page/username-section.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,32 @@
{{#if @user.hasAnonymousModeEnabled}}
<EmberTooltip @text="Your profile has anonymous mode enabled. Your GitHub username is not visible to others." />
{{else}}
{{! activate this once implemented }}
{{! <EmberTooltip @text="This value is synced with your GitHub account. Click on the refresh button below to update your username." /> }}
<EmberTooltip @text="This value is synced with your GitHub account." />
<EmberTooltip @text="This value is synced with your GitHub account. Click on the refresh button below to update your username." />
{{/if}}
</div>
<div class="text-gray-400 text-xs mt-1">
{{#if @user.hasAnonymousModeEnabled}}
Your profile has anonymous mode enabled. Your GitHub username is not visible to others.
{{else}}
This value is synced with your GitHub account.
This value is synced with your GitHub account. Click on the refresh button below to update your username.
{{/if}}
</div>

{{!-- TODO: Bring this back once implemented }}
{{!-- <TertiaryButtonWithSpinner @size="extra-small" class="mt-4" @shouldShowSpinner={{false}}>
<TertiaryButtonWithSpinner
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a user has anonymous mode enabled, should we show this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a user has anonymous mode enabled and clicked on this, what would happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense. user shouldn't be able to change github username if anonymous

@size="extra-small"
class="mt-4"
@shouldShowSpinner={{this.isSyncingUsernameFromGitHub}}
@isDisabled={{this.currentUser.hasAnonymousModeEnabled}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@libmartinito let's add a tooltip when this button is disabled:

Your profile has anonymous mode enabled. Your GitHub username is not visible to others.

{{on "click" this.refreshFromGitHub}}
data-test-refresh-from-github-button
>
<div class="flex items-center gap-1">
{{svg-jar "refresh" class="w-4 h-4 text-gray-400"}}
Refresh from GitHub
</div>
</TertiaryButtonWithSpinner> --}}

{{#if this.currentUser.hasAnonymousModeEnabled}}
<EmberTooltip @text="Your profile has anonymous mode enabled. Your GitHub username is not visible to others." />
{{/if}}
</TertiaryButtonWithSpinner>
</Settings::FormSection>
25 changes: 24 additions & 1 deletion app/components/settings/profile-page/username-section.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Component from '@glimmer/component';
import type AuthenticatorService from 'codecrafters-frontend/services/authenticator';
import type UserModel from 'codecrafters-frontend/models/user';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';

interface Signature {
Element: HTMLDivElement;
Expand All @@ -9,7 +13,26 @@ interface Signature {
};
}

export default class UsernameSectionComponent extends Component<Signature> {}
export default class UsernameSectionComponent extends Component<Signature> {
@service declare authenticator: AuthenticatorService;

@tracked isSyncingUsernameFromGitHub = false;

get currentUser() {
return this.authenticator.currentUser as UserModel;
}

@action
async refreshFromGitHub() {
if (this.currentUser.hasAnonymousModeEnabled) {
return;
}

this.isSyncingUsernameFromGitHub = true;
await this.currentUser.syncUsernameFromGitHub(null);
this.isSyncingUsernameFromGitHub = false;
}
}

declare module '@glint/environment-ember-loose/registry' {
export default interface Registry {
Expand Down
28 changes: 19 additions & 9 deletions app/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,17 +210,9 @@
declare fetchCurrent: (this: Model, payload: unknown) => Promise<UserModel | null>;
declare fetchNextInvoicePreview: (this: Model, payload: unknown) => Promise<InvoiceModel | null>;
declare syncFeatureFlags: (this: Model, payload: unknown) => Promise<void>;
declare syncUsernameFromGitHub: (this: Model, payload: unknown) => Promise<void>;
}

UserModel.prototype.syncFeatureFlags = memberAction({
path: 'sync-feature-flags',
type: 'post',

after(response) {
this.store.pushPayload(response);
},
});

UserModel.prototype.fetchNextInvoicePreview = memberAction({
path: 'next-invoice-preview',
type: 'get',
Expand Down Expand Up @@ -251,3 +243,21 @@
}
},
});

UserModel.prototype.syncFeatureFlags = memberAction({
path: 'sync-feature-flags',
type: 'post',

after(response) {
this.store.pushPayload(response);

Check warning on line 252 in app/models/user.ts

View check run for this annotation

Codecov / codecov/patch

app/models/user.ts#L252

Added line #L252 was not covered by tests
},
});

UserModel.prototype.syncUsernameFromGitHub = memberAction({
path: 'sync-username-from-github',
type: 'post',

after(response) {
this.store.pushPayload(response);
},
});
7 changes: 7 additions & 0 deletions mirage/handlers/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ export default function (server) {
});
});

server.post('/users/:id/sync-username-from-github', function (schema, request) {
let user = schema.users.find(request.params.id);
user.update({ username: 'updated-username' });

return user;
});

server.patch('/users/:id', function (schema, request) {
const { id } = request.params;
const attrs = this.normalizedRequestAttrs();
Expand Down
33 changes: 33 additions & 0 deletions tests/acceptance/settings-page/profile-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,37 @@ module('Acceptance | settings-page | profile-test', function (hooks) {
assert.strictEqual(userPage.githubDetails.username, 'rohitpaulk');
assert.strictEqual(userPage.githubDetails.link, 'https://github.com/rohitpaulk');
});

test('can refresh github username', async function (assert) {
testScenario(this.server);
signInAsSubscriber(this.owner, this.server);

let currentUser = this.server.schema.users.first();

assert.strictEqual(currentUser.username, 'rohitpaulk');

await profilePage.visit();
await profilePage.refreshFromGitHubButton.click();

assert.strictEqual(currentUser.reload().username, 'updated-username');
});

test('users with anonymous mode toggled should not be able to refresh github username', async function (assert) {
testScenario(this.server);
signInAsSubscriber(this.owner, this.server);

await profilePage.visit();
await profilePage.anonymousModeToggle.toggle();
await profilePage.accountDropdown.toggle();
await profilePage.accountDropdown.clickOnLink('Your Profile');

assert.strictEqual(userPage.githubDetails.username, 'Anonymous');

await profilePage.visit();
await profilePage.refreshFromGitHubButton.click();
await profilePage.accountDropdown.toggle();
await profilePage.accountDropdown.clickOnLink('Your Profile');

assert.strictEqual(userPage.githubDetails.username, 'Anonymous', 'should not have updated username');
});
});
4 changes: 4 additions & 0 deletions tests/pages/settings/profile-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,9 @@ export default createPage({
},
},

refreshFromGitHubButton: {
scope: '[data-test-refresh-from-github-button]',
},

visit: visitable('/settings/profile'),
});
Loading