Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-19 12:11:29 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-19 12:11:29 +0300
commit39e7e7beda5ab61c707eb050304a68bffa91dabd (patch)
treec024ee27baa67beddb8d5e19d564d56bbe4acf94 /spec
parent8c68904468d88beaeb618bfe81289a6c1eb8538c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb1
-rw-r--r--spec/controllers/projects/cycle_analytics_controller_spec.rb12
-rw-r--r--spec/controllers/projects/graphs_controller_spec.rb15
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb12
-rw-r--r--spec/features/cycle_analytics_spec.rb4
-rw-r--r--spec/features/groups_spec.rb3
-rw-r--r--spec/features/profiles/user_visits_profile_spec.rb8
-rw-r--r--spec/features/project_variables_spec.rb30
-rw-r--r--spec/features/projects_spec.rb11
-rw-r--r--spec/frontend/ci_variable_list/components/ci_project_variables_spec.js215
-rw-r--r--spec/frontend/ci_variable_list/mocks.js9
-rw-r--r--spec/frontend/vue_merge_request_widget/components/widget/app_spec.js4
-rw-r--r--spec/helpers/storage_helper_spec.rb16
13 files changed, 319 insertions, 21 deletions
diff --git a/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb b/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb
index 8903592ba15..b9e569b1647 100644
--- a/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb
+++ b/spec/controllers/projects/analytics/cycle_analytics/stages_controller_spec.rb
@@ -16,7 +16,6 @@ RSpec.describe Projects::Analytics::CycleAnalytics::StagesController do
end
before do
- stub_feature_flags(use_vsa_aggregated_tables: false)
sign_in(user)
end
diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb
index ccd213fdffa..f5dd8abd67b 100644
--- a/spec/controllers/projects/cycle_analytics_controller_spec.rb
+++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb
@@ -30,6 +30,18 @@ RSpec.describe Projects::CycleAnalyticsController do
let(:request_params) { { namespace_id: project.namespace, project_id: project } }
let(:target_id) { 'p_analytics_valuestream' }
end
+
+ it_behaves_like 'Snowplow event tracking' do
+ subject { get :show, params: request_params, format: :html }
+
+ let(:request_params) { { namespace_id: project.namespace, project_id: project } }
+ let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+ let(:category) { described_class.name }
+ let(:action) { 'perform_analytics_usage_action' }
+ let(:namespace) { project.namespace }
+ let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' }
+ let(:property) { 'p_analytics_valuestream' }
+ end
end
include_examples GracefulTimeoutHandling
diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb
index be89fa0d361..9227c7dd70a 100644
--- a/spec/controllers/projects/graphs_controller_spec.rb
+++ b/spec/controllers/projects/graphs_controller_spec.rb
@@ -89,6 +89,21 @@ RSpec.describe Projects::GraphsController do
let(:request_params) { { namespace_id: project.namespace.path, project_id: project.path, id: 'master' } }
let(:target_id) { 'p_analytics_repo' }
end
+
+ it_behaves_like 'Snowplow event tracking' do
+ subject do
+ sign_in(user)
+ get :charts, params: request_params, format: :html
+ end
+
+ let(:request_params) { { namespace_id: project.namespace.path, project_id: project.path, id: 'master' } }
+ let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+ let(:category) { described_class.name }
+ let(:action) { 'perform_analytics_usage_action' }
+ let(:namespace) { project.namespace }
+ let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' }
+ let(:property) { 'p_analytics_repo' }
+ end
end
context 'when languages were previously detected' do
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index 06930d8727b..48aaff67c95 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -841,6 +841,18 @@ RSpec.describe Projects::PipelinesController do
let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } }
let(:target_id) { ['p_analytics_pipelines', tab[:event]] }
end
+
+ it_behaves_like 'Snowplow event tracking' do
+ subject { get :charts, params: request_params, format: :html }
+
+ let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } }
+ let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
+ let(:category) { described_class.name }
+ let(:action) { 'perform_analytics_usage_action' }
+ let(:namespace) { project.namespace }
+ let(:label) { 'redis_hll_counters.analytics.analytics_total_unique_counts_monthly' }
+ let(:property) { 'p_analytics_pipelines' }
+ end
end
end
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index 7714783172f..488a4f84297 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -36,10 +36,6 @@ RSpec.describe 'Value Stream Analytics', :js do
wait_for_all_requests
end
- before do
- stub_feature_flags(use_vsa_aggregated_tables: false)
- end
-
context 'as an allowed user' do
context 'when project is new' do
before do
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index c93ed01b873..65cb8770662 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -519,10 +519,11 @@ RSpec.describe 'Group' do
end
describe 'storage_enforcement_banner', :js do
- let_it_be(:group) { create(:group) }
+ let_it_be_with_refind(:group) { create(:group, :with_root_storage_statistics) }
let_it_be_with_refind(:user) { create(:user) }
before do
+ group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE)
group.add_owner(user)
sign_in(user)
end
diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb
index 7dd2e6aafa3..4859e796954 100644
--- a/spec/features/profiles/user_visits_profile_spec.rb
+++ b/spec/features/profiles/user_visits_profile_spec.rb
@@ -89,6 +89,14 @@ RSpec.describe 'User visits their profile' do
end
describe 'storage_enforcement_banner', :js do
+ let_it_be(:root_storage_statistics) do
+ create(
+ :namespace_root_storage_statistics,
+ namespace: user.namespace,
+ storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE
+ )
+ end
+
before do
stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
end
diff --git a/spec/features/project_variables_spec.rb b/spec/features/project_variables_spec.rb
index 89dbd1afc6b..d3bedbf3a75 100644
--- a/spec/features/project_variables_spec.rb
+++ b/spec/features/project_variables_spec.rb
@@ -14,8 +14,6 @@ RSpec.describe 'Project variables', :js do
project.variables << variable
end
- # TODO: Add same tests but with FF enabled context when
- # the new graphQL app for variable settings is enabled.
context 'with disabled ff `ci_variable_settings_graphql' do
before do
stub_feature_flags(ci_variable_settings_graphql: false)
@@ -44,4 +42,32 @@ RSpec.describe 'Project variables', :js do
end
end
end
+
+ context 'with enabled ff `ci_variable_settings_graphql' do
+ before do
+ visit page_path
+ end
+
+ it_behaves_like 'variable list'
+
+ it 'adds a new variable with an environment scope' do
+ click_button('Add variable')
+
+ page.within('#add-ci-variable') do
+ fill_in 'Key', with: 'akey'
+ find('#ci-variable-value').set('akey_value')
+ find('[data-testid="environment-scope"]').click
+ find('[data-testid="ci-environment-search"]').set('review/*')
+ find('[data-testid="create-wildcard-button"]').click
+
+ click_button('Add variable')
+ end
+
+ wait_for_requests
+
+ page.within('[data-testid="ci-variable-table"]') do
+ expect(find('.js-ci-variable-row:first-child [data-label="Environments"]').text).to eq('review/*')
+ end
+ end
+ end
end
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index d228fb084c3..d9030b9ec89 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -441,11 +441,12 @@ RSpec.describe 'Project' do
end
describe 'storage_enforcement_banner', :js do
- let_it_be(:group) { create(:group) }
+ let_it_be_with_refind(:group) { create(:group, :with_root_storage_statistics) }
let_it_be_with_refind(:user) { create(:user) }
let_it_be(:project) { create(:project, group: group) }
before do
+ group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE)
group.add_maintainer(user)
sign_in(user)
end
@@ -475,9 +476,15 @@ RSpec.describe 'Project' do
end
context 'when in a user namespace project page' do
- let_it_be(:project) { create(:project, namespace: user.namespace) }
+ let_it_be_with_refind(:project) { create(:project, namespace: user.namespace) }
before do
+ create(
+ :namespace_root_storage_statistics,
+ namespace: user.namespace,
+ storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE
+ )
+
allow_next_found_instance_of(Namespaces::UserNamespace) do |user_namespace|
allow(user_namespace).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
diff --git a/spec/frontend/ci_variable_list/components/ci_project_variables_spec.js b/spec/frontend/ci_variable_list/components/ci_project_variables_spec.js
new file mode 100644
index 00000000000..867f8e0cf8f
--- /dev/null
+++ b/spec/frontend/ci_variable_list/components/ci_project_variables_spec.js
@@ -0,0 +1,215 @@
+import Vue, { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import { GlLoadingIcon, GlTable } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createFlash from '~/flash';
+import { resolvers } from '~/ci_variable_list/graphql/resolvers';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
+
+import ciProjectVariables from '~/ci_variable_list/components/ci_project_variables.vue';
+import ciVariableSettings from '~/ci_variable_list/components/ci_variable_settings.vue';
+import ciVariableTable from '~/ci_variable_list/components/ci_variable_table.vue';
+import getProjectEnvironments from '~/ci_variable_list/graphql/queries/project_environments.query.graphql';
+import getProjectVariables from '~/ci_variable_list/graphql/queries/project_variables.query.graphql';
+
+import addProjectVariable from '~/ci_variable_list/graphql/mutations/project_add_variable.mutation.graphql';
+import deleteProjectVariable from '~/ci_variable_list/graphql/mutations/project_delete_variable.mutation.graphql';
+import updateProjectVariable from '~/ci_variable_list/graphql/mutations/project_update_variable.mutation.graphql';
+
+import {
+ environmentFetchErrorText,
+ genericMutationErrorText,
+ variableFetchErrorText,
+} from '~/ci_variable_list/constants';
+
+import {
+ devName,
+ mockProjectEnvironments,
+ mockProjectVariables,
+ newVariable,
+ prodName,
+} from '../mocks';
+
+jest.mock('~/flash');
+
+Vue.use(VueApollo);
+
+const mockProvide = {
+ endpoint: '/variables',
+ projectFullPath: '/namespace/project',
+ projectId: 1,
+};
+
+describe('Ci Project Variable list', () => {
+ let wrapper;
+
+ let mockApollo;
+ let mockEnvironments;
+ let mockVariables;
+
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findCiTable = () => wrapper.findComponent(GlTable);
+ const findCiSettings = () => wrapper.findComponent(ciVariableSettings);
+
+ // eslint-disable-next-line consistent-return
+ const createComponentWithApollo = async ({ isLoading = false } = {}) => {
+ const handlers = [
+ [getProjectEnvironments, mockEnvironments],
+ [getProjectVariables, mockVariables],
+ ];
+
+ mockApollo = createMockApollo(handlers, resolvers);
+
+ wrapper = shallowMount(ciProjectVariables, {
+ provide: mockProvide,
+ apolloProvider: mockApollo,
+ stubs: { ciVariableSettings, ciVariableTable },
+ });
+
+ if (!isLoading) {
+ return waitForPromises();
+ }
+ };
+
+ beforeEach(() => {
+ mockEnvironments = jest.fn();
+ mockVariables = jest.fn();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('while queries are being fetch', () => {
+ beforeEach(() => {
+ createComponentWithApollo({ isLoading: true });
+ });
+
+ it('shows a loading icon', () => {
+ expect(findLoadingIcon().exists()).toBe(true);
+ expect(findCiTable().exists()).toBe(false);
+ });
+ });
+
+ describe('when queries are resolved', () => {
+ describe('successfuly', () => {
+ beforeEach(async () => {
+ mockEnvironments.mockResolvedValue(mockProjectEnvironments);
+ mockVariables.mockResolvedValue(mockProjectVariables);
+
+ await createComponentWithApollo();
+ });
+
+ it('passes down the expected environments as props', () => {
+ expect(findCiSettings().props('environments')).toEqual([prodName, devName]);
+ });
+
+ it('passes down the expected variables as props', () => {
+ expect(findCiSettings().props('variables')).toEqual(
+ mockProjectVariables.data.project.ciVariables.nodes,
+ );
+ });
+
+ it('createFlash was not called', () => {
+ expect(createFlash).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('with an error for variables', () => {
+ beforeEach(async () => {
+ mockEnvironments.mockResolvedValue(mockProjectEnvironments);
+ mockVariables.mockRejectedValue();
+
+ await createComponentWithApollo();
+ });
+
+ it('calls createFlash with the expected error message', () => {
+ expect(createFlash).toHaveBeenCalledWith({ message: variableFetchErrorText });
+ });
+ });
+
+ describe('with an error for environments', () => {
+ beforeEach(async () => {
+ mockEnvironments.mockRejectedValue();
+ mockVariables.mockResolvedValue(mockProjectVariables);
+
+ await createComponentWithApollo();
+ });
+
+ it('calls createFlash with the expected error message', () => {
+ expect(createFlash).toHaveBeenCalledWith({ message: environmentFetchErrorText });
+ });
+ });
+ });
+
+ describe('mutations', () => {
+ beforeEach(async () => {
+ mockEnvironments.mockResolvedValue(mockProjectEnvironments);
+ mockVariables.mockResolvedValue(mockProjectVariables);
+
+ await createComponentWithApollo();
+ });
+ it.each`
+ actionName | mutation | event
+ ${'add'} | ${addProjectVariable} | ${'add-variable'}
+ ${'update'} | ${updateProjectVariable} | ${'update-variable'}
+ ${'delete'} | ${deleteProjectVariable} | ${'delete-variable'}
+ `(
+ 'calls the right mutation when user performs $actionName variable',
+ async ({ event, mutation }) => {
+ jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue();
+ await findCiSettings().vm.$emit(event, newVariable);
+
+ expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
+ mutation,
+ variables: {
+ endpoint: mockProvide.endpoint,
+ fullPath: mockProvide.projectFullPath,
+ projectId: convertToGraphQLId('Project', mockProvide.projectId),
+ variable: newVariable,
+ },
+ });
+ },
+ );
+
+ it.each`
+ actionName | event | mutationName
+ ${'add'} | ${'add-variable'} | ${'addProjectVariable'}
+ ${'update'} | ${'update-variable'} | ${'updateProjectVariable'}
+ ${'delete'} | ${'delete-variable'} | ${'deleteProjectVariable'}
+ `(
+ 'throws with the specific graphql error if present when user performs $actionName variable',
+ async ({ event, mutationName }) => {
+ const graphQLErrorMessage = 'There is a problem with this graphQL action';
+ jest
+ .spyOn(wrapper.vm.$apollo, 'mutate')
+ .mockResolvedValue({ data: { [mutationName]: { errors: [graphQLErrorMessage] } } });
+ await findCiSettings().vm.$emit(event, newVariable);
+ await nextTick();
+
+ expect(wrapper.vm.$apollo.mutate).toHaveBeenCalled();
+ expect(createFlash).toHaveBeenCalledWith({ message: graphQLErrorMessage });
+ },
+ );
+
+ it.each`
+ actionName | event
+ ${'add'} | ${'add-variable'}
+ ${'update'} | ${'update-variable'}
+ ${'delete'} | ${'delete-variable'}
+ `(
+ 'throws generic error when the mutation fails with no graphql errors and user performs $actionName variable',
+ async ({ event }) => {
+ jest.spyOn(wrapper.vm.$apollo, 'mutate').mockImplementationOnce(() => {
+ throw new Error();
+ });
+ await findCiSettings().vm.$emit(event, newVariable);
+
+ expect(wrapper.vm.$apollo.mutate).toHaveBeenCalled();
+ expect(createFlash).toHaveBeenCalledWith({ message: genericMutationErrorText });
+ },
+ );
+ });
+});
diff --git a/spec/frontend/ci_variable_list/mocks.js b/spec/frontend/ci_variable_list/mocks.js
index 89ba77858dc..b030005cb8d 100644
--- a/spec/frontend/ci_variable_list/mocks.js
+++ b/spec/frontend/ci_variable_list/mocks.js
@@ -1,4 +1,9 @@
-import { variableTypes, groupString, instanceString } from '~/ci_variable_list/constants';
+import {
+ variableTypes,
+ groupString,
+ instanceString,
+ projectString,
+} from '~/ci_variable_list/constants';
export const devName = 'dev';
export const prodName = 'prod';
@@ -77,7 +82,7 @@ export const mockProjectVariables = {
project: {
__typename: 'Project',
id: 1,
- ciVariables: createDefaultVars(),
+ ciVariables: createDefaultVars({ kind: projectString }),
},
},
};
diff --git a/spec/frontend/vue_merge_request_widget/components/widget/app_spec.js b/spec/frontend/vue_merge_request_widget/components/widget/app_spec.js
index 6bb718082a4..8dbee9b370c 100644
--- a/spec/frontend/vue_merge_request_widget/components/widget/app_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/widget/app_spec.js
@@ -12,8 +12,8 @@ describe('MR Widget App', () => {
});
};
- it('mounts the component', () => {
+ it('does not mount if widgets array is empty', () => {
createComponent();
- expect(wrapper.findByTestId('mr-widget-app').exists()).toBe(true);
+ expect(wrapper.findByTestId('mr-widget-app').exists()).toBe(false);
});
});
diff --git a/spec/helpers/storage_helper_spec.rb b/spec/helpers/storage_helper_spec.rb
index 6c3556c874b..e0628fe9235 100644
--- a/spec/helpers/storage_helper_spec.rb
+++ b/spec/helpers/storage_helper_spec.rb
@@ -53,8 +53,8 @@ RSpec.describe StorageHelper do
describe "storage_enforcement_banner" do
let_it_be_with_refind(:current_user) { create(:user) }
- let_it_be(:free_group) { create(:group) }
- let_it_be(:paid_group) { create(:group) }
+ let_it_be(:free_group) { create(:group, :with_root_storage_statistics) }
+ let_it_be(:paid_group) { create(:group, :with_root_storage_statistics) }
before do
allow(helper).to receive(:can?).with(current_user, :maintainer_access, free_group).and_return(true)
@@ -62,6 +62,9 @@ RSpec.describe StorageHelper do
allow(helper).to receive(:current_user) { current_user }
allow(paid_group).to receive(:paid?).and_return(true)
+ free_group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE)
+ paid_group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE)
+
stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
end
@@ -110,13 +113,13 @@ RSpec.describe StorageHelper do
})
end
- context 'when namespace has used storage' do
+ context 'when namespace is under MIN_STORAGE_ENFORCEMENT_USAGE limit' do
before do
- create(:namespace_root_storage_statistics, namespace: free_group, storage_size: 102400)
+ free_group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE - 1)
end
- it 'returns a hash with the correct storage size text' do
- expect(helper.storage_enforcement_banner_info(free_group)[:text_paragraph_2]).to eql("The namespace is currently using <strong>100 KB</strong> of namespace storage. Group owners can view namespace storage usage and purchase more from <strong>Group settings &gt; Usage quotas</strong>. <a href=\"/help/user/usage_quotas#manage-your-storage-usage\" >Learn more.</a>")
+ it 'returns nil' do
+ expect(helper.storage_enforcement_banner_info(free_group)).to be(nil)
end
end
@@ -141,7 +144,6 @@ RSpec.describe StorageHelper do
end
it 'returns the enforcement info' do
- puts helper.storage_enforcement_banner_info(free_group)[:text_paragraph_1]
expect(helper.storage_enforcement_banner_info(free_group)[:text_paragraph_1]).to include("Effective #{Date.current}, namespace storage limits will apply")
end
end