Skip to content

Add sudo mode acceptance tests, per #8210 feedback #8237

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

Merged
merged 2 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions app/components/header.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<Dropdown data-test-user-menu as |dd|>
<dd.Trigger local-class="dropdown-button" data-test-toggle>
{{#if this.session.isSudoEnabled}}
<div local-class="wizard-hat">🧙</div>
<div data-test-wizard-hat local-class="wizard-hat">🧙</div>
{{/if}}
<UserAvatar @user={{this.session.currentUser}} @size="small" local-class="avatar" data-test-avatar />
{{ this.session.currentUser.name }}
Expand All @@ -35,12 +35,12 @@
{{#if this.session.isAdmin}}
<menu.Item local-class='sudo'>
{{#if this.session.isSudoEnabled}}
<button local-class='sudo-menu-item' type='button' {{on 'click' this.disableSudo}}>
<button data-test-disable-admin-actions local-class='sudo-menu-item' type='button' {{on 'click' this.disableSudo}}>
Disable admin actions
<div local-class='expires-in'>expires at {{date-format this.session.sudoEnabledUntil 'HH:mm'}}</div>
</button>
{{else}}
<button local-class='sudo-menu-item' type='button' {{on 'click' this.enableSudo}}>
<button data-test-enable-admin-actions local-class='sudo-menu-item' type='button' {{on 'click' this.enableSudo}}>
Enable admin actions
</button>
{{/if}}
Expand Down
2 changes: 1 addition & 1 deletion app/components/privileged-action.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</div>
{{else}}
<div local-class='placeholder'>
<fieldset disabled="disabled">
<fieldset data-test-placeholder-fieldset disabled="disabled">
{{yield}}
</fieldset>
<EmberTooltip>
Expand Down
113 changes: 113 additions & 0 deletions tests/acceptance/sudo-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { click, find, waitFor } from '@ember/test-helpers';
import { module, test } from 'qunit';

import format from 'date-fns/format';

import { setupApplicationTest } from 'crates-io/tests/helpers';

import { visit } from '../helpers/visit-ignoring-abort';

module('Acceptance | sudo', function (hooks) {
setupApplicationTest(hooks);

function prepare(context, isAdmin) {
const user = context.server.create('user', {
login: 'johnnydee',
name: 'John Doe',
email: 'john@doe.com',
avatar: 'https://avatars2.githubusercontent.com/u/1234567?v=4',
isAdmin,
});

const crate = context.server.create('crate', {
name: 'foo',
newest_version: '0.1.0',
});

const version = context.server.create('version', {
crate,
num: '0.1.0',
});

context.authenticateAs(user);
return { user, crate, version };
}

test('non-admin users do not see any controls', async function (assert) {
prepare(this, false);

await visit('/crates/foo/versions');

// Test the various header elements.
assert.dom('[data-test-wizard-hat]').doesNotExist();
assert.dom('[data-test-disable-admin-actions]').doesNotExist();
assert.dom('[data-test-enable-admin-actions]').doesNotExist();

// Assert that there's no yank button, disabled, enabled, or in any state.
assert.dom('[data-test-version-yank-button="0.1.0"]').doesNotExist();
});

test('admin user is not initially in sudo mode', async function (assert) {
prepare(this, true);

await visit('/crates/foo/versions');

// Test the various header elements.
assert.dom('[data-test-wizard-hat]').doesNotExist();
assert.dom('[data-test-disable-admin-actions]').doesNotExist();
assert.dom('[data-test-enable-admin-actions]').exists();

// Test that the fieldset is present and disabled.
assert.dom('[data-test-placeholder-fieldset]').exists().isDisabled();

// From the perspective of the actual button, it isn't disabled, even though
// the fieldset effectively makes it unclickable.
assert.dom('[data-test-version-yank-button="0.1.0"]').exists();
});

test('admin user can enter sudo mode', async function (assert) {
prepare(this, true);

await visit('/crates/foo/versions');

const untilAbout = Date.now() + 6 * 60 * 60 * 1000;
await click('[data-test-enable-admin-actions]');

// Test the various header elements.
assert.dom('[data-test-wizard-hat]').exists();
assert.dom('[data-test-disable-admin-actions]').exists();
assert.dom('[data-test-enable-admin-actions]').doesNotExist();

// Test that the expiry time is sensible. We'll allow a minute either way in
// case of slow tests or slightly wonky clocks.
const disable = find('[data-test-disable-admin-actions] > div');
let seen = 0;
for (const ts of [untilAbout - 60 * 1000, untilAbout, untilAbout + 60 * 1000]) {
const time = format(new Date(ts), 'HH:mm');
if (disable.textContent.includes(time)) {
seen += 1;
}
}
assert.strictEqual(seen, 1);

// Test that the fieldset is not present.
assert.dom('[data-test-placeholder-fieldset]').doesNotExist();
assert.dom('[data-test-version-yank-button="0.1.0"]').exists();
});

test('admin can yank a crate in sudo mode', async function (assert) {
prepare(this, true);

await visit('/crates/foo/versions');
await click('[data-test-enable-admin-actions]');

await click('[data-test-version-yank-button="0.1.0"]');

await waitFor('[data-test-version-unyank-button="0.1.0"]');
assert.dom('[data-test-version-unyank-button="0.1.0"]').exists();
await click('[data-test-version-unyank-button="0.1.0"]');

await waitFor('[data-test-version-yank-button="0.1.0"]');
assert.dom('[data-test-version-yank-button="0.1.0"]').exists();
});
});