diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-19 21:09:17 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-19 21:09:17 +0300 |
commit | 0eb4fd2f32e6804bc85868ba167170238e346279 (patch) | |
tree | c020e787ea29c77e1e9f53c21940f88a87a6e905 /spec | |
parent | 78d8830cec030ff12afed3c8ae1dddec454d0a24 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
9 files changed, 270 insertions, 9 deletions
diff --git a/spec/features/projects/environments_pod_logs_spec.rb b/spec/features/projects/environments_pod_logs_spec.rb new file mode 100644 index 00000000000..121a8e1705b --- /dev/null +++ b/spec/features/projects/environments_pod_logs_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Environment > Pod Logs', :js do + include KubernetesHelpers + + let(:pod_names) { %w(kube-pod) } + let(:pod_name) { pod_names.first } + let(:project) { create(:project, :repository) } + let(:environment) { create(:environment, project: project) } + let(:service) { create(:cluster_platform_kubernetes, :configured) } + + before do + create(:cluster, :provided_by_gcp, environment_scope: '*', projects: [project]) + create(:deployment, :success, environment: environment) + + stub_kubeclient_pods(environment.deployment_namespace) + stub_kubeclient_logs(pod_name, environment.deployment_namespace, container: 'container-0') + + sign_in(project.owner) + end + + it "shows environments in dropdown" do + create(:environment, project: project) + + visit project_logs_path(environment.project, environment_name: environment.name, pod_name: pod_name) + + wait_for_requests + + page.within('.js-environments-dropdown') do + toggle = find(".dropdown-menu-toggle:not([disabled])") + + expect(toggle).to have_content(environment.name) + + toggle.click + + dropdown_items = find(".dropdown-menu").all(".dropdown-item") + expect(dropdown_items.first).to have_content(environment.name) + expect(dropdown_items.size).to eq(2) + end + end + + context 'with logs', :use_clean_rails_memory_store_caching do + it "shows pod logs", :sidekiq_might_not_need_inline do + visit project_logs_path(environment.project, environment_name: environment.name, pod_name: pod_name) + + wait_for_requests + + page.within('.js-pods-dropdown') do + find(".dropdown-menu-toggle:not([disabled])").click + + dropdown_items = find(".dropdown-menu").all(".dropdown-item:not([disabled])") + expect(dropdown_items.size).to eq(1) + + dropdown_items.each_with_index do |item, i| + expect(item.text).to eq(pod_names[i]) + end + end + expect(page).to have_content("Dec 13 14:04:22.123Z | kube-pod | Log 1 Dec 13 14:04:23.123Z | kube-pod | Log 2 Dec 13 14:04:24.123Z | kube-pod | Log 3") + end + end +end diff --git a/spec/frontend/registry/explorer/components/project_empty_state_spec.js b/spec/frontend/registry/explorer/components/project_empty_state_spec.js index 8d4b6ca60a2..4b209646da9 100644 --- a/spec/frontend/registry/explorer/components/project_empty_state_spec.js +++ b/spec/frontend/registry/explorer/components/project_empty_state_spec.js @@ -3,6 +3,7 @@ import { shallowMount, createLocalVue } from '@vue/test-utils'; import { GlSprintf } from '@gitlab/ui'; import { GlEmptyState } from '../stubs'; import projectEmptyState from '~/registry/explorer/components/project_empty_state.vue'; +import * as getters from '~/registry/explorer/stores/getters'; const localVue = createLocalVue(); localVue.use(Vuex); @@ -23,6 +24,7 @@ describe('Registry Project Empty state', () => { noContainersImage: 'bazFoo', }, }, + getters, }); wrapper = shallowMount(projectEmptyState, { localVue, diff --git a/spec/frontend/registry/explorer/components/quickstart_dropdown_spec.js b/spec/frontend/registry/explorer/components/quickstart_dropdown_spec.js new file mode 100644 index 00000000000..3dfe50ebe13 --- /dev/null +++ b/spec/frontend/registry/explorer/components/quickstart_dropdown_spec.js @@ -0,0 +1,95 @@ +import Vuex from 'vuex'; +import { mount, createLocalVue } from '@vue/test-utils'; +import { GlDropdown, GlFormGroup, GlFormInputGroup } from '@gitlab/ui'; +import * as getters from '~/registry/explorer/stores/getters'; +import QuickstartDropdown from '~/registry/explorer/components/quickstart_dropdown.vue'; +import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; + +import { + QUICK_START, + LOGIN_COMMAND_LABEL, + COPY_LOGIN_TITLE, + BUILD_COMMAND_LABEL, + COPY_BUILD_TITLE, + PUSH_COMMAND_LABEL, + COPY_PUSH_TITLE, +} from '~/registry/explorer//constants'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +describe('quickstart_dropdown', () => { + let wrapper; + let store; + + const findDropdownButton = () => wrapper.find(GlDropdown); + const findFormGroups = () => wrapper.findAll(GlFormGroup); + + const mountComponent = () => { + store = new Vuex.Store({ + state: { + config: { + repositoryUrl: 'foo', + registryHostUrlWithPort: 'bar', + }, + }, + getters, + }); + wrapper = mount(QuickstartDropdown, { + localVue, + store, + }); + }; + + beforeEach(() => { + mountComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + store = null; + }); + + it('shows the correct text on the button', () => { + expect(findDropdownButton().text()).toContain(QUICK_START); + }); + + describe.each` + index | id | labelText | titleText | getter + ${0} | ${'docker-login-btn'} | ${LOGIN_COMMAND_LABEL} | ${COPY_LOGIN_TITLE} | ${'dockerLoginCommand'} + ${1} | ${'docker-build-btn'} | ${BUILD_COMMAND_LABEL} | ${COPY_BUILD_TITLE} | ${'dockerBuildCommand'} + ${2} | ${'docker-push-btn'} | ${PUSH_COMMAND_LABEL} | ${COPY_PUSH_TITLE} | ${'dockerPushCommand'} + `('form group at $index', ({ index, id, labelText, titleText, getter }) => { + let formGroup; + + const findFormInputGroup = parent => parent.find(GlFormInputGroup); + const findClipboardButton = parent => parent.find(ClipboardButton); + + beforeEach(() => { + formGroup = findFormGroups().at(index); + }); + + it('exists', () => { + expect(formGroup.exists()).toBe(true); + }); + + it(`has a label ${labelText}`, () => { + expect(formGroup.text()).toBe(labelText); + }); + + it(`contains a form input group with ${id} id and with value equal to ${getter} getter`, () => { + const formInputGroup = findFormInputGroup(formGroup); + expect(formInputGroup.exists()).toBe(true); + expect(formInputGroup.attributes('id')).toBe(id); + expect(formInputGroup.props('value')).toBe(store.getters[getter]); + }); + + it(`contains a clipboard button with title of ${titleText} and text equal to ${getter} getter`, () => { + const clipBoardButton = findClipboardButton(formGroup); + expect(clipBoardButton.exists()).toBe(true); + expect(clipBoardButton.props('title')).toBe(titleText); + expect(clipBoardButton.props('text')).toBe(store.getters[getter]); + }); + }); +}); diff --git a/spec/frontend/registry/explorer/pages/list_spec.js b/spec/frontend/registry/explorer/pages/list_spec.js index 91c3c242ed4..5b713778495 100644 --- a/spec/frontend/registry/explorer/pages/list_spec.js +++ b/spec/frontend/registry/explorer/pages/list_spec.js @@ -3,6 +3,9 @@ import { shallowMount, createLocalVue } from '@vue/test-utils'; import { GlPagination, GlSkeletonLoader, GlSprintf } from '@gitlab/ui'; import Tracking from '~/tracking'; import component from '~/registry/explorer/pages/list.vue'; +import QuickstartDropdown from '~/registry/explorer/components/quickstart_dropdown.vue'; +import GroupEmptyState from '~/registry/explorer/components/group_empty_state.vue'; +import ProjectEmptyState from '~/registry/explorer/components/project_empty_state.vue'; import store from '~/registry/explorer/stores/'; import { SET_MAIN_LOADING } from '~/registry/explorer/stores/mutation_types/'; import { imagesListResponse } from '../mock_data'; @@ -24,6 +27,9 @@ describe('List Page', () => { const findDetailsLink = () => wrapper.find({ ref: 'detailsLink' }); const findClipboardButton = () => wrapper.find({ ref: 'clipboardButton' }); const findPagination = () => wrapper.find(GlPagination); + const findQuickStartDropdown = () => wrapper.find(QuickstartDropdown); + const findProjectEmptyState = () => wrapper.find(ProjectEmptyState); + const findGroupEmptyState = () => wrapper.find(GroupEmptyState); beforeEach(() => { wrapper = shallowMount(component, { @@ -76,7 +82,7 @@ describe('List Page', () => { }); }); - describe('when isLoading is true', () => { + describe('isLoading is true', () => { beforeAll(() => store.commit(SET_MAIN_LOADING, true)); afterAll(() => store.commit(SET_MAIN_LOADING, false)); @@ -88,9 +94,49 @@ describe('List Page', () => { it('imagesList is not visible', () => { expect(findImagesList().exists()).toBe(false); }); + + it('quick start is not visible', () => { + expect(findQuickStartDropdown().exists()).toBe(false); + }); + }); + + describe('list is empty', () => { + beforeEach(() => { + store.dispatch('receiveImagesListSuccess', { data: [] }); + }); + + it('quick start is not visible', () => { + expect(findQuickStartDropdown().exists()).toBe(false); + }); + + it('project empty state is visible', () => { + expect(findProjectEmptyState().exists()).toBe(true); + }); + + describe('is group page is true', () => { + beforeAll(() => { + store.dispatch('setInitialState', { isGroupPage: true }); + }); + + afterAll(() => { + store.dispatch('setInitialState', { isGroupPage: undefined }); + }); + + it('group empty state is visible', () => { + expect(findGroupEmptyState().exists()).toBe(true); + }); + + it('quick start is not visible', () => { + expect(findQuickStartDropdown().exists()).toBe(false); + }); + }); }); - describe('list', () => { + describe('list is not empty', () => { + it('quick start is visible', () => { + expect(findQuickStartDropdown().exists()).toBe(true); + }); + describe('listElement', () => { let listElements; let firstElement; diff --git a/spec/frontend/registry/explorer/stores/getters_spec.js b/spec/frontend/registry/explorer/stores/getters_spec.js index c224f076d30..211b8169d82 100644 --- a/spec/frontend/registry/explorer/stores/getters_spec.js +++ b/spec/frontend/registry/explorer/stores/getters_spec.js @@ -31,4 +31,22 @@ describe('Getters RegistryExplorer store', () => { }); }); }); + + describe.each` + getter | prefix | configParameter | suffix + ${'dockerBuildCommand'} | ${'docker build -t'} | ${'repositoryUrl'} | ${'.'} + ${'dockerPushCommand'} | ${'docker push'} | ${'repositoryUrl'} | ${null} + ${'dockerLoginCommand'} | ${'docker login'} | ${'registryHostUrlWithPort'} | ${null} + `('$getter', ({ getter, prefix, configParameter, suffix }) => { + beforeEach(() => { + state = { + config: { repositoryUrl: 'foo', registryHostUrlWithPort: 'bar' }, + }; + }); + + it(`returns ${prefix} concatenated with ${configParameter} and optionally suffixed with ${suffix}`, () => { + const expectedPieces = [prefix, state.config[configParameter], suffix].filter(p => p); + expect(getters[getter](state)).toBe(expectedPieces.join(' ')); + }); + }); }); diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb index bd22458355c..f8b56b6002a 100644 --- a/spec/graphql/gitlab_schema_spec.rb +++ b/spec/graphql/gitlab_schema_spec.rb @@ -52,12 +52,6 @@ describe GitlabSchema do expect(connection).to eq(Gitlab::Graphql::Connections::FilterableArrayConnection) end - it 'paginates OffsetActiveRecordRelation using `Pagination::OffsetActiveRecordRelationConnection`' do - connection = implementations[Gitlab::Graphql::Pagination::Relations::OffsetActiveRecordRelation.name] - - expect(connection).to eq(Gitlab::Graphql::Pagination::OffsetActiveRecordRelationConnection) - end - describe '.execute' do context 'for different types of users' do context 'when no context' do diff --git a/spec/lib/gitlab/graphql/pagination/offset_active_record_relation_connection_spec.rb b/spec/lib/gitlab/graphql/pagination/offset_active_record_relation_connection_spec.rb index 2269b4def82..931b1e708de 100644 --- a/spec/lib/gitlab/graphql/pagination/offset_active_record_relation_connection_spec.rb +++ b/spec/lib/gitlab/graphql/pagination/offset_active_record_relation_connection_spec.rb @@ -4,6 +4,6 @@ require 'spec_helper' describe Gitlab::Graphql::Pagination::OffsetActiveRecordRelationConnection do it 'subclasses from GraphQL::Relay::RelationConnection' do - expect(described_class.superclass).to eq GraphQL::Relay::RelationConnection + expect(described_class.superclass).to eq GraphQL::Pagination::ActiveRecordRelationConnection end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 83f678ad2cb..8706b941e4f 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -726,6 +726,7 @@ describe API::Projects do issues_enabled: false, jobs_enabled: false, merge_requests_enabled: false, + forking_access_level: 'disabled', wiki_enabled: false, resolve_outdated_diff_discussions: false, remove_source_branch_after_merge: true, @@ -1400,6 +1401,7 @@ describe API::Projects do expect(json_response['repository_access_level']).to be_present expect(json_response['issues_access_level']).to be_present expect(json_response['merge_requests_access_level']).to be_present + expect(json_response['forking_access_level']).to be_present expect(json_response['wiki_access_level']).to be_present expect(json_response['builds_access_level']).to be_present expect(json_response).to have_key('emails_disabled') diff --git a/spec/views/admin/users/_user.html.haml_spec.rb b/spec/views/admin/users/_user.html.haml_spec.rb new file mode 100644 index 00000000000..96d84229d94 --- /dev/null +++ b/spec/views/admin/users/_user.html.haml_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'admin/users/_user.html.haml' do + before do + allow(view).to receive(:user).and_return(user) + end + + context 'internal users' do + context 'when showing a `Ghost User`' do + let(:user) { create(:user, ghost: true) } + + it 'does not render action buttons' do + render + + expect(rendered).not_to have_selector('.table-action-buttons') + end + end + + context 'when showing a `Bot User`' do + let(:user) { create(:user, user_type: :alert_bot) } + + it 'does not render action buttons' do + render + + expect(rendered).not_to have_selector('.table-action-buttons') + end + end + end + + context 'when showing an external user' do + let(:user) { create(:user) } + + it 'renders action buttons' do + render + + expect(rendered).to have_selector('.table-action-buttons') + end + end +end |