ee/spec/features/admin/admin_credentials_spec.rb (228 lines of code) (raw):
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Admin::Credentials', :with_current_organization, feature_category: :user_management do
include Features::AdminUsersHelpers
let_it_be(:admin) { create(:admin, organizations: [current_organization]) }
before do
sign_in(admin)
enable_admin_mode!(admin)
stub_licensed_features(credentials_inventory: true)
end
describe 'GET /admin/credentials' do
before do
visit admin_credentials_path
end
it "is ok and shows no personal access tokens" do
expect(page).to have_current_path(admin_credentials_path)
expect(page).to have_content(s_('CredentialsInventory|No credentials found'))
end
describe 'search and filter', :js do
before_all do
create(:personal_access_token, name: 'my personal access token', user: admin, scopes: [:read_api],
expires_at: 10.days.from_now)
create(:personal_access_token, user: admin, scopes: [:manage_runner], revoked: true,
expires_at: 10.days.from_now)
create(:personal_access_token, user: admin, scopes: [:k8s_proxy], created_at: 1.day.ago,
expires_at: 10.days.from_now)
create(:personal_access_token, user: admin, scopes: [:read_repository], created_at: 1.day.from_now,
expires_at: 10.days.from_now)
create(:personal_access_token, user: admin, scopes: [:write_repository], last_used_at: 2.days.ago,
expires_at: 10.days.from_now)
create(:personal_access_token, user: admin, scopes: [:ai_features], last_used_at: 1.day.ago,
expires_at: 10.days.from_now)
create(:personal_access_token, user: admin, scopes: [:create_runner], expires_at: 2.days.from_now)
create(:personal_access_token, user: admin, scopes: [:sudo], expires_at: 200.days.from_now)
end
it 'searches by token name' do
expect_all_rows
input_filtered_search_keys('my personal access token')
expect_one_row_with_content('read_api')
end
it 'filters by type' do
expect_all_rows
input_filtered_search_filter_is_only(s_('CredentialsInventory|Type'), s_('CredentialsInventory|SSH keys'))
expect(page).to have_content(s_('CredentialsInventory|No credentials found'))
end
it 'filters by state' do
expect_all_rows
input_filtered_search_filter_is_only(s_('CredentialsInventory|State'), s_('CredentialsInventory|Inactive'))
expect_one_row_with_content('manage_runner')
end
it 'filters by revoke' do
expect_all_rows
input_filtered_search_filter_is_only(s_('CredentialsInventory|Revoked'), s_('CredentialsInventory|Yes'))
expect_one_row_with_content('manage_runner')
end
describe 'created date' do
it 'filters date before' do
expect_all_rows
input_filtered_search_filter_is_before(s_('CredentialsInventory|Created date'), 0.days.ago.to_date)
expect_one_row_with_content('k8s_proxy')
end
it 'filters by date after' do
expect_all_rows
input_filtered_search_filter_is_after(s_('CredentialsInventory|Created date'), 1.day.from_now.to_date)
expect_one_row_with_content('read_repository')
end
end
describe 'expiration date' do
it 'filters date before' do
expect_all_rows
input_filtered_search_filter_is_before(s_('CredentialsInventory|Expiration date'), 3.days.from_now.to_date)
expect_one_row_with_content('create_runner')
end
it 'filters by date after' do
expect_all_rows
input_filtered_search_filter_is_after(s_('CredentialsInventory|Expiration date'), 200.days.from_now.to_date)
expect_one_row_with_content('sudo')
end
end
describe 'last used date' do
it 'filters date before' do
expect_all_rows
input_filtered_search_filter_is_before(s_('CredentialsInventory|Last used date'), 1.day.ago.to_date)
expect_one_row_with_content('write_repository')
end
it 'filters by date after' do
expect_all_rows
input_filtered_search_filter_is_after(s_('CredentialsInventory|Last used date'), 1.day.ago.to_date)
expect_one_row_with_content('ai_features')
end
end
describe 'shows correct search and filters based on the URL parameters' do
it 'shows search' do
visit admin_credentials_path(search: 'my personal access token')
within_testid(filtered_search) do
expect(page).to have_content('my personal access token')
end
end
it 'shows type filter' do
visit admin_credentials_path(filter: 'personal_access_tokens')
within_testid(filtered_search) do
expect(page).to have_content(
"#{s_('CredentialsInventory|Type')} = #{s_('CredentialsInventory|Personal access tokens')}")
end
end
it 'shows state filter' do
visit admin_credentials_path(state: 'active')
within_testid(filtered_search) do
expect(page).to have_content("#{s_('CredentialsInventory|State')} = #{s_('CredentialsInventory|Active')}")
end
end
it 'shows revoked filter' do
visit admin_credentials_path(revoked: 'true')
within_testid(filtered_search) do
expect(page).to have_content("#{s_('CredentialsInventory|Revoked')} = #{s_('CredentialsInventory|Yes')}")
end
end
describe 'created date' do
it 'shows created date before filter' do
visit admin_credentials_path(created_before: '2025-01-01')
within_testid(filtered_search) do
expect(page).to have_content("#{s_('CredentialsInventory|Created date')} < 2025-01-01")
end
end
it 'shows created date before filter' do
visit admin_credentials_path(created_after: '2025-01-01')
within_testid(filtered_search) do
expect(page).to have_content("#{s_('CredentialsInventory|Created date')} ≥ 2025-01-01")
end
end
end
describe 'expiration date' do
it 'shows created date before filter' do
visit admin_credentials_path(expires_before: '2025-01-01')
within_testid(filtered_search) do
expect(page).to have_content("#{s_('CredentialsInventory|Expiration date')} < 2025-01-01")
end
end
it 'shows created date before filter' do
visit admin_credentials_path(expires_after: '2025-01-01')
within_testid(filtered_search) do
expect(page).to have_content("#{s_('CredentialsInventory|Expiration date')} ≥ 2025-01-01")
end
end
end
describe 'last used date' do
it 'shows last used date before filter' do
visit admin_credentials_path(last_used_before: '2025-01-01')
within_testid(filtered_search) do
expect(page).to have_content("#{s_('CredentialsInventory|Last used date')} < 2025-01-01")
end
end
it 'shows last used date before filter' do
visit admin_credentials_path(last_used_after: '2025-01-01')
within_testid(filtered_search) do
expect(page).to have_content("#{s_('CredentialsInventory|Last used date')} ≥ 2025-01-01")
end
end
end
it 'ignores unknown filters' do
visit admin_credentials_path(my_filter: 'true')
within_testid(filtered_search) do
expect(page).to have_content('')
end
end
end
end
end
def content_body
'#content-body'
end
def expect_all_rows
within(content_body) do
expect(all_rows.size).to eq(8)
end
end
def expect_one_row_with_content(content)
within(content_body) do
expect(all_rows.size).to eq(1)
expect(page).to have_content(content)
end
end
def all_rows
page.all('.table-holder .gl-responsive-table-row:not(.table-row-header)[role="row"]')
end
def filtered_search
'filtered-search-input'
end
# The filters must be clicked first to be able to receive events
# See: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1493
def focus_filtered_search
page.find('.gl-filtered-search-term-token').click
end
def input_filtered_search_keys(search_term)
within_testid(filtered_search) do
focus_filtered_search
send_keys(search_term)
send_keys(:enter)
click_on 'Search'
end
end
def input_filtered_search_filter_is_only(filter, value)
within_testid(filtered_search) do
focus_filtered_search
click_on filter
# For OPERATORS_IS, clicking the filter
# immediately preselects "=" operator
send_keys(value)
send_keys(:enter)
click_on 'Search'
end
end
def input_filtered_search_filter_is_before(filter, value)
within_testid(filtered_search) do
focus_filtered_search
click_on filter
send_keys('<')
send_keys(value)
send_keys(:enter)
click_on 'Search'
end
end
def input_filtered_search_filter_is_after(filter, value)
within_testid(filtered_search) do
focus_filtered_search
click_on filter
send_keys('≥')
send_keys(value)
send_keys(:enter)
click_on 'Search'
end
end
end