claire bontempo 31051ef1e4
UI: Implement api service in auth components (#31085)
* change entity_id to camel casing, remove "backends" key from stored auth data

* fix tokenExpirationEpoch returning NaN, use authSuccess in auth service tests

* camel case mfa_requirement references

* refactor auth service

* implement api service for token method

* implement api service in standard auth methods

* add lookupSelf request to persistAuthData method in auht service instead of calling in components

* implement api service in oidc-jwt component

* implement api service in okta component

* implement api service in saml component

* use api service for wrapped_token query param

* remaining test updates, enterprise tests and stabilize auth helpers

* upate renew() to use new persistAuthData method, add a test

* revert as this will be addressed upstream

* rename supported-login-methods to auth-form-helpers and delete old supported-auth-backends helper, update tests

* cleanup normalize after testing mfa validation for each auth method

* update type declarations, set displayName in each method component

* stabilize redirect tests by waiting for login before asserting url

* stabilize tests

* modernize typescript syntax, move error const to util

* use mirage instead of vault server to resolve test race conditions

* fix file import
2025-07-09 10:11:23 -07:00

80 lines
3.2 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import sinon from 'sinon';
import { setRunOptions } from 'ember-a11y-testing/test-support';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
module('Integration | Component | sidebar-user-menu', function (hooks) {
setupRenderingTest(hooks);
hooks.beforeEach(function () {
this.auth = this.owner.lookup('service:auth');
setRunOptions({
// TODO: fix this component
rules: {
'nested-interactive': { enabled: false },
// TODO: fix ConfirmAction rendered in toolbar not a list item
list: { enabled: false },
},
});
});
test('it should render trigger and open menu', async function (assert) {
await render(hbs`<Sidebar::UserMenu />`);
assert
.dom(`${GENERAL.button('user-menu-trigger')} [data-test-icon="user"]`)
.exists('Correct icon renders for menu trigger');
await click(GENERAL.button('user-menu-trigger'));
assert.dom('[data-test-user-menu-content]').exists('User menu content renders');
});
test('it should render default menu items', async function (assert) {
sinon.stub(this.auth, 'currentToken').value('root');
sinon.stub(this.auth, 'authData').value({ displayName: 'token' });
await render(hbs`<Sidebar::UserMenu />`);
await click(GENERAL.button('user-menu-trigger'));
assert.dom('.menu-label').hasText('Token', 'Auth data display name renders');
assert.dom('li').exists({ count: 2 }, 'Correct number of menu items render');
assert.dom(GENERAL.copyButton).exists('Copy token action renders');
assert.dom('#logout').hasText('Log out', 'Log out action renders');
});
test('it should render conditional menu items', async function (assert) {
const router = this.owner.lookup('service:router');
const transitionStub = sinon.stub(router, 'transitionTo');
const renewStub = sinon.stub(this.auth, 'renew').resolves();
const revokeStub = sinon.stub(this.auth, 'revokeCurrentToken').resolves();
const date = new Date();
sinon.stub(this.auth, 'tokenExpirationDate').value(date.setDate(date.getDate() + 1));
sinon.stub(this.auth, 'authData').value({ displayName: 'token', renewable: true, entityId: 'foo' });
this.auth.set('allowExpiration', true);
await render(hbs`<Sidebar::UserMenu />`);
await click(GENERAL.button('user-menu-trigger'));
assert.dom('[data-test-user-menu-item="token alert"]').exists('Token expiration alert renders');
assert.dom('[data-test-user-menu-item="mfa"]').hasText('Multi-factor authentication', 'MFA link renders');
await click('[data-test-user-menu-item="revoke token"]');
await click(GENERAL.confirmButton);
assert.true(revokeStub.calledOnce, 'Auth revoke token method called on revoke confirm');
assert.true(
transitionStub.calledWith('vault.cluster.logout'),
'Route transitions to log out on revoke success'
);
await click('[data-test-user-menu-item="renew token"]');
assert.true(renewStub.calledOnce, 'Auth renew token method called');
});
});