Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
4b8939db3d
commit
65688a5092
|
@ -22,6 +22,273 @@ Graphql/Descriptions:
|
|||
- 'ee/app/graphql/types/vulnerability_report_type_enum.rb'
|
||||
- 'ee/app/graphql/types/vulnerability_severity_enum.rb'
|
||||
- 'ee/app/graphql/types/vulnerability_state_enum.rb'
|
||||
- 'app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb'
|
||||
- 'app/graphql/mutations/alert_management/alerts/set_assignees.rb'
|
||||
- 'app/graphql/mutations/alert_management/base.rb'
|
||||
- 'app/graphql/mutations/alert_management/http_integration/create.rb'
|
||||
- 'app/graphql/mutations/alert_management/http_integration/destroy.rb'
|
||||
- 'app/graphql/mutations/alert_management/http_integration/http_integration_base.rb'
|
||||
- 'app/graphql/mutations/alert_management/http_integration/reset_token.rb'
|
||||
- 'app/graphql/mutations/alert_management/http_integration/update.rb'
|
||||
- 'app/graphql/mutations/alert_management/prometheus_integration/create.rb'
|
||||
- 'app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb'
|
||||
- 'app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb'
|
||||
- 'app/graphql/mutations/alert_management/prometheus_integration/update.rb'
|
||||
- 'app/graphql/mutations/alert_management/update_alert_status.rb'
|
||||
- 'app/graphql/mutations/award_emojis/base.rb'
|
||||
- 'app/graphql/mutations/boards/common_mutation_arguments.rb'
|
||||
- 'app/graphql/mutations/boards/create.rb'
|
||||
- 'app/graphql/mutations/boards/destroy.rb'
|
||||
- 'app/graphql/mutations/boards/lists/destroy.rb'
|
||||
- 'app/graphql/mutations/boards/update.rb'
|
||||
- 'app/graphql/mutations/ci/ci_cd_settings_update.rb'
|
||||
- 'app/graphql/mutations/ci/job/base.rb'
|
||||
- 'app/graphql/mutations/ci/job/play.rb'
|
||||
- 'app/graphql/mutations/ci/job/retry.rb'
|
||||
- 'app/graphql/mutations/ci/job_token_scope/add_project.rb'
|
||||
- 'app/graphql/mutations/ci/job_token_scope/remove_project.rb'
|
||||
- 'app/graphql/mutations/ci/pipeline/base.rb'
|
||||
- 'app/graphql/mutations/ci/pipeline/retry.rb'
|
||||
- 'app/graphql/mutations/ci/runner/update.rb'
|
||||
- 'app/graphql/mutations/ci/runners_registration_token/reset.rb'
|
||||
- 'app/graphql/mutations/commits/create.rb'
|
||||
- 'app/graphql/mutations/concerns/mutations/assignable.rb'
|
||||
- 'app/graphql/mutations/concerns/mutations/can_mutate_spammable.rb'
|
||||
- 'app/graphql/mutations/concerns/mutations/resolves_subscription.rb'
|
||||
- 'app/graphql/mutations/container_expiration_policies/update.rb'
|
||||
- 'app/graphql/mutations/container_repositories/destroy.rb'
|
||||
- 'app/graphql/mutations/custom_emoji/create.rb'
|
||||
- 'app/graphql/mutations/design_management/base.rb'
|
||||
- 'app/graphql/mutations/design_management/delete.rb'
|
||||
- 'app/graphql/mutations/design_management/move.rb'
|
||||
- 'app/graphql/mutations/design_management/upload.rb'
|
||||
- 'app/graphql/mutations/discussions/toggle_resolve.rb'
|
||||
- 'app/graphql/mutations/environments/canary_ingress/update.rb'
|
||||
- 'app/graphql/mutations/groups/update.rb'
|
||||
- 'app/graphql/mutations/issues/base.rb'
|
||||
- 'app/graphql/mutations/issues/create.rb'
|
||||
- 'app/graphql/mutations/issues/move.rb'
|
||||
- 'app/graphql/mutations/issues/set_due_date.rb'
|
||||
- 'app/graphql/mutations/issues/set_subscription.rb'
|
||||
- 'app/graphql/mutations/issues/update.rb'
|
||||
- 'app/graphql/mutations/jira_import/import_users.rb'
|
||||
- 'app/graphql/mutations/jira_import/start.rb'
|
||||
- 'app/graphql/mutations/labels/create.rb'
|
||||
- 'app/graphql/mutations/merge_requests/accept.rb'
|
||||
- 'app/graphql/mutations/merge_requests/base.rb'
|
||||
- 'app/graphql/mutations/merge_requests/create.rb'
|
||||
- 'app/graphql/mutations/merge_requests/reviewer_rereview.rb'
|
||||
- 'app/graphql/mutations/merge_requests/set_labels.rb'
|
||||
- 'app/graphql/mutations/merge_requests/set_milestone.rb'
|
||||
- 'app/graphql/mutations/merge_requests/set_subscription.rb'
|
||||
- 'app/graphql/mutations/merge_requests/update.rb'
|
||||
- 'app/graphql/mutations/metrics/dashboard/annotations/create.rb'
|
||||
- 'app/graphql/mutations/namespace/package_settings/update.rb'
|
||||
- 'app/graphql/mutations/notes/base.rb'
|
||||
- 'app/graphql/mutations/notes/create/base.rb'
|
||||
- 'app/graphql/mutations/notes/create/note.rb'
|
||||
- 'app/graphql/mutations/notes/destroy.rb'
|
||||
- 'app/graphql/mutations/notes/reposition_image_diff_note.rb'
|
||||
- 'app/graphql/mutations/notes/update/base.rb'
|
||||
- 'app/graphql/mutations/notes/update/note.rb'
|
||||
- 'app/graphql/mutations/release_asset_links/create.rb'
|
||||
- 'app/graphql/mutations/release_asset_links/delete.rb'
|
||||
- 'app/graphql/mutations/release_asset_links/update.rb'
|
||||
- 'app/graphql/mutations/releases/create.rb'
|
||||
- 'app/graphql/mutations/releases/delete.rb'
|
||||
- 'app/graphql/mutations/releases/update.rb'
|
||||
- 'app/graphql/mutations/snippets/base.rb'
|
||||
- 'app/graphql/mutations/snippets/create.rb'
|
||||
- 'app/graphql/mutations/snippets/destroy.rb'
|
||||
- 'app/graphql/mutations/snippets/mark_as_spam.rb'
|
||||
- 'app/graphql/mutations/snippets/update.rb'
|
||||
- 'app/graphql/mutations/todos/create.rb'
|
||||
- 'app/graphql/mutations/todos/mark_done.rb'
|
||||
- 'app/graphql/mutations/todos/restore.rb'
|
||||
- 'app/graphql/mutations/todos/restore_many.rb'
|
||||
- 'app/graphql/mutations/user_callouts/create.rb'
|
||||
- 'app/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver.rb'
|
||||
- 'app/graphql/resolvers/blobs_resolver.rb'
|
||||
- 'app/graphql/resolvers/board_resolver.rb'
|
||||
- 'app/graphql/resolvers/ci/config_resolver.rb'
|
||||
- 'app/graphql/resolvers/concerns/resolves_snippets.rb'
|
||||
- 'app/graphql/resolvers/design_management/design_at_version_resolver.rb'
|
||||
- 'app/graphql/resolvers/design_management/version/design_at_version_resolver.rb'
|
||||
- 'app/graphql/resolvers/design_management/version_in_collection_resolver.rb'
|
||||
- 'app/graphql/resolvers/design_management/version_resolver.rb'
|
||||
- 'app/graphql/resolvers/design_management/versions_resolver.rb'
|
||||
- 'app/graphql/resolvers/full_path_resolver.rb'
|
||||
- 'app/graphql/resolvers/labels_resolver.rb'
|
||||
- 'app/graphql/resolvers/merge_requests_resolver.rb'
|
||||
- 'app/graphql/resolvers/milestones_resolver.rb'
|
||||
- 'app/graphql/resolvers/package_details_resolver.rb'
|
||||
- 'app/graphql/resolvers/paginated_tree_resolver.rb'
|
||||
- 'app/graphql/resolvers/release_resolver.rb'
|
||||
- 'app/graphql/resolvers/repository_branch_names_resolver.rb'
|
||||
- 'app/graphql/resolvers/snippets_resolver.rb'
|
||||
- 'app/graphql/resolvers/todo_resolver.rb'
|
||||
- 'app/graphql/resolvers/tree_resolver.rb'
|
||||
- 'app/graphql/resolvers/users/snippets_resolver.rb'
|
||||
- 'app/graphql/types/admin/analytics/usage_trends/measurement_type.rb'
|
||||
- 'app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb'
|
||||
- 'app/graphql/types/alert_management/alert_type.rb'
|
||||
- 'app/graphql/types/award_emojis/award_emoji_type.rb'
|
||||
- 'app/graphql/types/ci/config/job_restriction_type.rb'
|
||||
- 'app/graphql/types/ci/config/status_enum.rb'
|
||||
- 'app/graphql/types/ci/pipeline_type.rb'
|
||||
- 'app/graphql/types/ci_configuration/sast/ui_component_size_enum.rb'
|
||||
- 'app/graphql/types/commit_action_type.rb'
|
||||
- 'app/graphql/types/container_repository_cleanup_status_enum.rb'
|
||||
- 'app/graphql/types/container_repository_tag_type.rb'
|
||||
- 'app/graphql/types/container_repository_type.rb'
|
||||
- 'app/graphql/types/custom_emoji_type.rb'
|
||||
- 'app/graphql/types/design_management/design_at_version_type.rb'
|
||||
- 'app/graphql/types/design_management/design_fields.rb'
|
||||
- 'app/graphql/types/diff_paths_input_type.rb'
|
||||
- 'app/graphql/types/environment_type.rb'
|
||||
- 'app/graphql/types/eventable_type.rb'
|
||||
- 'app/graphql/types/group_type.rb'
|
||||
- 'app/graphql/types/merge_request_type.rb'
|
||||
- 'app/graphql/types/metadata/kas_type.rb'
|
||||
- 'app/graphql/types/milestone_wildcard_id_enum.rb'
|
||||
- 'app/graphql/types/namespace_type.rb'
|
||||
- 'app/graphql/types/notes/note_type.rb'
|
||||
- 'app/graphql/types/notes/position_type_enum.rb'
|
||||
- 'app/graphql/types/packages/composer/json_type.rb'
|
||||
- 'app/graphql/types/packages/package_details_type.rb'
|
||||
- 'app/graphql/types/packages/package_file_type.rb'
|
||||
- 'app/graphql/types/packages/package_tag_type.rb'
|
||||
- 'app/graphql/types/packages/package_type.rb'
|
||||
- 'app/graphql/types/project_type.rb'
|
||||
- 'app/graphql/types/prometheus_alert_type.rb'
|
||||
- 'app/graphql/types/query_type.rb'
|
||||
- 'app/graphql/types/range_input_type.rb'
|
||||
- 'app/graphql/types/release_asset_link_shared_input_arguments.rb'
|
||||
- 'app/graphql/types/release_assets_input_type.rb'
|
||||
- 'app/graphql/types/release_type.rb'
|
||||
- 'app/graphql/types/repository/blob_type.rb'
|
||||
- 'app/graphql/types/root_storage_statistics_type.rb'
|
||||
- 'app/graphql/types/snippet_type.rb'
|
||||
- 'app/graphql/types/snippets/blob_type.rb'
|
||||
- 'app/graphql/types/snippets/visibility_scopes_enum.rb'
|
||||
- 'app/graphql/types/terraform/state_type.rb'
|
||||
- 'app/graphql/types/terraform/state_version_type.rb'
|
||||
- 'app/graphql/types/timelog_type.rb'
|
||||
- 'app/graphql/types/todo_state_enum.rb'
|
||||
- 'app/graphql/types/todo_target_enum.rb'
|
||||
- 'app/graphql/types/todo_type.rb'
|
||||
- 'app/graphql/types/user_interface.rb'
|
||||
- 'app/graphql/types/user_merge_request_interaction_type.rb'
|
||||
- 'app/graphql/types/user_state_enum.rb'
|
||||
- 'ee/app/graphql/ee/mutations/alert_management/http_integration/create.rb'
|
||||
- 'ee/app/graphql/ee/mutations/alert_management/http_integration/update.rb'
|
||||
- 'ee/app/graphql/ee/mutations/boards/issues/issue_move_list.rb'
|
||||
- 'ee/app/graphql/ee/mutations/issues/create.rb'
|
||||
- 'ee/app/graphql/ee/mutations/issues/update.rb'
|
||||
- 'ee/app/graphql/ee/types/alert_management/http_integration_type.rb'
|
||||
- 'ee/app/graphql/ee/types/board_list_type.rb'
|
||||
- 'ee/app/graphql/ee/types/board_type.rb'
|
||||
- 'ee/app/graphql/ee/types/group_type.rb'
|
||||
- 'ee/app/graphql/ee/types/project_type.rb'
|
||||
- 'ee/app/graphql/ee/types/query_type.rb'
|
||||
- 'ee/app/graphql/mutations/app_sec/fuzzing/api/ci_configuration/create.rb'
|
||||
- 'ee/app/graphql/mutations/boards/epic_boards/create.rb'
|
||||
- 'ee/app/graphql/mutations/boards/epic_boards/epic_move_list.rb'
|
||||
- 'ee/app/graphql/mutations/boards/epic_boards/update.rb'
|
||||
- 'ee/app/graphql/mutations/boards/epic_lists/destroy.rb'
|
||||
- 'ee/app/graphql/mutations/boards/lists/update_limit_metrics.rb'
|
||||
- 'ee/app/graphql/mutations/boards/update_epic_user_preferences.rb'
|
||||
- 'ee/app/graphql/mutations/compliance_management/frameworks/create.rb'
|
||||
- 'ee/app/graphql/mutations/compliance_management/frameworks/destroy.rb'
|
||||
- 'ee/app/graphql/mutations/compliance_management/frameworks/update.rb'
|
||||
- 'ee/app/graphql/mutations/concerns/mutations/shared_epic_arguments.rb'
|
||||
- 'ee/app/graphql/mutations/dast/profiles/create.rb'
|
||||
- 'ee/app/graphql/mutations/dast/profiles/update.rb'
|
||||
- 'ee/app/graphql/mutations/dast_on_demand_scans/create.rb'
|
||||
- 'ee/app/graphql/mutations/dast_scanner_profiles/create.rb'
|
||||
- 'ee/app/graphql/mutations/dast_scanner_profiles/update.rb'
|
||||
- 'ee/app/graphql/mutations/dast_site_profiles/create.rb'
|
||||
- 'ee/app/graphql/mutations/dast_site_profiles/delete.rb'
|
||||
- 'ee/app/graphql/mutations/dast_site_profiles/update.rb'
|
||||
- 'ee/app/graphql/mutations/dast_site_tokens/create.rb'
|
||||
- 'ee/app/graphql/mutations/dast_site_validations/create.rb'
|
||||
- 'ee/app/graphql/mutations/dast_site_validations/revoke.rb'
|
||||
- 'ee/app/graphql/mutations/epic_tree/reorder.rb'
|
||||
- 'ee/app/graphql/mutations/epics/add_issue.rb'
|
||||
- 'ee/app/graphql/mutations/epics/base.rb'
|
||||
- 'ee/app/graphql/mutations/epics/create.rb'
|
||||
- 'ee/app/graphql/mutations/epics/set_subscription.rb'
|
||||
- 'ee/app/graphql/mutations/gitlab_subscriptions/activate.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/escalation_policy/base.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/escalation_policy/create.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/escalation_policy/destroy.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/escalation_policy/update.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/oncall_rotation/base.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/oncall_rotation/create.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/oncall_rotation/destroy.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/oncall_rotation/update.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/oncall_schedule/create.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/oncall_schedule/destroy.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/oncall_schedule/oncall_schedule_base.rb'
|
||||
- 'ee/app/graphql/mutations/incident_management/oncall_schedule/update.rb'
|
||||
- 'ee/app/graphql/mutations/issues/common_ee_mutation_arguments.rb'
|
||||
- 'ee/app/graphql/mutations/issues/promote_to_epic.rb'
|
||||
- 'ee/app/graphql/mutations/issues/set_iteration.rb'
|
||||
- 'ee/app/graphql/mutations/iterations/cadences/create.rb'
|
||||
- 'ee/app/graphql/mutations/iterations/cadences/update.rb'
|
||||
- 'ee/app/graphql/mutations/iterations/create.rb'
|
||||
- 'ee/app/graphql/mutations/namespaces/base.rb'
|
||||
- 'ee/app/graphql/mutations/quality_management/test_cases/create.rb'
|
||||
- 'ee/app/graphql/mutations/requirements_management/update_requirement.rb'
|
||||
- 'ee/app/graphql/mutations/vulnerabilities/confirm.rb'
|
||||
- 'ee/app/graphql/mutations/vulnerabilities/create_external_issue_link.rb'
|
||||
- 'ee/app/graphql/mutations/vulnerabilities/destroy_external_issue_link.rb'
|
||||
- 'ee/app/graphql/mutations/vulnerabilities/dismiss.rb'
|
||||
- 'ee/app/graphql/mutations/vulnerabilities/resolve.rb'
|
||||
- 'ee/app/graphql/mutations/vulnerabilities/revert_to_detected.rb'
|
||||
- 'ee/app/graphql/resolvers/dora_metrics_resolver.rb'
|
||||
- 'ee/app/graphql/resolvers/geo/geo_node_resolver.rb'
|
||||
- 'ee/app/graphql/resolvers/network_policy_resolver.rb'
|
||||
- 'ee/app/graphql/resolvers/requirements_management/requirements_resolver.rb'
|
||||
- 'ee/app/graphql/types/alert_management/payload_alert_field_input_type.rb'
|
||||
- 'ee/app/graphql/types/alert_management/payload_alert_mapping_field_type.rb'
|
||||
- 'ee/app/graphql/types/analytics/devops_adoption/snapshot_type.rb'
|
||||
- 'ee/app/graphql/types/app_sec/fuzzing/api/scan_profile_type.rb'
|
||||
- 'ee/app/graphql/types/ci/code_quality_degradation_type.rb'
|
||||
- 'ee/app/graphql/types/ci/minutes/namespace_monthly_usage_type.rb'
|
||||
- 'ee/app/graphql/types/ci/minutes/project_monthly_usage_type.rb'
|
||||
- 'ee/app/graphql/types/clusters/agent_token_type.rb'
|
||||
- 'ee/app/graphql/types/clusters/agent_type.rb'
|
||||
- 'ee/app/graphql/types/dast/profile_branch_type.rb'
|
||||
- 'ee/app/graphql/types/dast/profile_type.rb'
|
||||
- 'ee/app/graphql/types/dast/site_profile_auth_input_type.rb'
|
||||
- 'ee/app/graphql/types/dast/site_profile_auth_type.rb'
|
||||
- 'ee/app/graphql/types/dast_scanner_profile_type.rb'
|
||||
- 'ee/app/graphql/types/dast_site_profile_type.rb'
|
||||
- 'ee/app/graphql/types/epic_tree/epic_tree_node_input_type.rb'
|
||||
- 'ee/app/graphql/types/epic_type.rb'
|
||||
- 'ee/app/graphql/types/geo/geo_node_type.rb'
|
||||
- 'ee/app/graphql/types/incident_management/escalation_policy_type.rb'
|
||||
- 'ee/app/graphql/types/incident_management/escalation_rule_input_type.rb'
|
||||
- 'ee/app/graphql/types/incident_management/escalation_rule_type.rb'
|
||||
- 'ee/app/graphql/types/incident_management/oncall_participant_type.rb'
|
||||
- 'ee/app/graphql/types/incident_management/oncall_rotation_active_period_input_type.rb'
|
||||
- 'ee/app/graphql/types/incident_management/oncall_rotation_active_period_type.rb'
|
||||
- 'ee/app/graphql/types/incident_management/oncall_rotation_date_input_type.rb'
|
||||
- 'ee/app/graphql/types/incident_management/oncall_rotation_length_input_type.rb'
|
||||
- 'ee/app/graphql/types/incident_management/oncall_user_input_type.rb'
|
||||
- 'ee/app/graphql/types/move_type_enum.rb'
|
||||
- 'ee/app/graphql/types/network_policy_kind_enum.rb'
|
||||
- 'ee/app/graphql/types/path_lock_type.rb'
|
||||
- 'ee/app/graphql/types/pipeline_security_report_finding_type.rb'
|
||||
- 'ee/app/graphql/types/scanned_resource_type.rb'
|
||||
- 'ee/app/graphql/types/security_report_summary_section_type.rb'
|
||||
- 'ee/app/graphql/types/timebox_metrics_type.rb'
|
||||
- 'ee/app/graphql/types/vulnerability/issue_link_type.rb'
|
||||
- 'ee/app/graphql/types/vulnerability_details/commit_type.rb'
|
||||
- 'ee/app/graphql/types/vulnerability_type.rb'
|
||||
- 'ee/app/graphql/types/vulnerable_dependency_type.rb'
|
||||
- 'ee/app/graphql/types/vulnerable_package_type.rb'
|
||||
|
||||
# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040
|
||||
Rails/SaveBang:
|
||||
|
|
|
@ -1 +1 @@
|
|||
3af862d452b894f08d1651944d763834a5c35ab8
|
||||
23842e500b6c90e1f462c78b497a8af8d1d6c8a6
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script>
|
||||
import { GlModal, GlIcon, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { GlButton, GlModal, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { mapActions } from 'vuex';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import ListItem from './list_item.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlIcon,
|
||||
GlButton,
|
||||
ListItem,
|
||||
GlModal,
|
||||
},
|
||||
|
@ -70,7 +70,7 @@ export default {
|
|||
<div class="d-flex align-items-center flex-fill">
|
||||
<strong> {{ titleText }} </strong>
|
||||
<div class="d-flex ml-auto">
|
||||
<button
|
||||
<gl-button
|
||||
v-if="!stagedList"
|
||||
v-gl-tooltip
|
||||
:title="__('Discard all changes')"
|
||||
|
@ -79,15 +79,14 @@ export default {
|
|||
:class="{
|
||||
'disabled-content': !filesLength,
|
||||
}"
|
||||
type="button"
|
||||
class="d-flex ide-staged-action-btn p-0 border-0 align-items-center"
|
||||
class="gl-shadow-none!"
|
||||
category="tertiary"
|
||||
icon="remove-all"
|
||||
data-placement="bottom"
|
||||
data-container="body"
|
||||
data-boundary="viewport"
|
||||
@click="openDiscardModal"
|
||||
>
|
||||
<gl-icon :size="16" name="remove-all" class="ml-auto mr-auto position-top-0" />
|
||||
</button>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
|
|
@ -4,14 +4,12 @@ import { FILTERED_SEARCH } from '~/pages/constants';
|
|||
import initFilteredSearch from '~/pages/search/init_filtered_search';
|
||||
import projectSelect from '~/project_select';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys, true);
|
||||
addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys, true);
|
||||
|
||||
initFilteredSearch({
|
||||
page: FILTERED_SEARCH.MERGE_REQUESTS,
|
||||
filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
|
||||
useDefaultState: true,
|
||||
});
|
||||
|
||||
projectSelect();
|
||||
initFilteredSearch({
|
||||
page: FILTERED_SEARCH.MERGE_REQUESTS,
|
||||
filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
|
||||
useDefaultState: true,
|
||||
});
|
||||
|
||||
projectSelect();
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import projectSelect from '~/project_select';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', projectSelect);
|
||||
projectSelect();
|
||||
|
|
|
@ -2,7 +2,7 @@ import GroupsList from '~/groups_list';
|
|||
import Landing from '~/landing';
|
||||
import initGroupsList from '../../../groups';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
function exploreGroups() {
|
||||
new GroupsList(); // eslint-disable-line no-new
|
||||
initGroupsList();
|
||||
const landingElement = document.querySelector('.js-explore-groups-landing');
|
||||
|
@ -13,4 +13,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
'explore_groups_landing_dismissed',
|
||||
);
|
||||
exploreGroupsLanding.toggle();
|
||||
});
|
||||
}
|
||||
|
||||
exploreGroups();
|
||||
|
|
|
@ -2,7 +2,5 @@ import $ from 'jquery';
|
|||
import docs from '~/docs/docs_bundle';
|
||||
import VersionCheckImage from '~/version_check_image';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
docs();
|
||||
VersionCheckImage.bindErrorEvent($('img.js-version-status-badge'));
|
||||
});
|
||||
docs();
|
||||
VersionCheckImage.bindErrorEvent($('img.js-version-status-badge'));
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import initUIKit from '~/ui_development_kit';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initUIKit);
|
||||
initUIKit();
|
||||
|
|
|
@ -2,7 +2,7 @@ import Vue from 'vue';
|
|||
import { initStoreFromElement, initPropsFromElement } from '~/import_entities/import_projects';
|
||||
import BitbucketStatusTable from '~/import_entities/import_projects/components/bitbucket_status_table.vue';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
function importBitBucket() {
|
||||
const mountElement = document.getElementById('import-projects-mount-element');
|
||||
if (!mountElement) return undefined;
|
||||
|
||||
|
@ -16,4 +16,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
return createElement(BitbucketStatusTable, { attrs });
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
importBitBucket();
|
||||
|
|
|
@ -2,7 +2,7 @@ import Vue from 'vue';
|
|||
import { initStoreFromElement, initPropsFromElement } from '~/import_entities/import_projects';
|
||||
import BitbucketServerStatusTable from './components/bitbucket_server_status_table.vue';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
function BitbucketServerStatus() {
|
||||
const mountElement = document.getElementById('import-projects-mount-element');
|
||||
if (!mountElement) return undefined;
|
||||
|
||||
|
@ -19,4 +19,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
BitbucketServerStatus();
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import mountImportProjectsTable from '~/import_entities/import_projects';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const mountElement = document.getElementById('import-projects-mount-element');
|
||||
const mountElement = document.getElementById('import-projects-mount-element');
|
||||
|
||||
mountImportProjectsTable(mountElement);
|
||||
});
|
||||
mountImportProjectsTable(mountElement);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import mountImportProjectsTable from '~/import_entities/import_projects';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const mountElement = document.getElementById('import-projects-mount-element');
|
||||
const mountElement = document.getElementById('import-projects-mount-element');
|
||||
|
||||
mountImportProjectsTable(mountElement);
|
||||
});
|
||||
mountImportProjectsTable(mountElement);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import initGitLabImportProject from '~/projects/project_import_gitlab_project';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initGitLabImportProject);
|
||||
initGitLabImportProject();
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import mountImportProjectsTable from '~/import_entities/import_projects';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const mountElement = document.getElementById('import-projects-mount-element');
|
||||
const mountElement = document.getElementById('import-projects-mount-element');
|
||||
|
||||
mountImportProjectsTable(mountElement);
|
||||
});
|
||||
mountImportProjectsTable(mountElement);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import { mount2faAuthentication } from '~/authentication/mount_2fa';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', mount2faAuthentication);
|
||||
mount2faAuthentication();
|
||||
|
|
|
@ -2,16 +2,14 @@ import IntegrationSettingsForm from '~/integrations/integration_settings_form';
|
|||
import PrometheusAlerts from '~/prometheus_alerts';
|
||||
import CustomMetrics from '~/prometheus_metrics/custom_metrics';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form');
|
||||
integrationSettingsForm.init();
|
||||
const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form');
|
||||
integrationSettingsForm.init();
|
||||
|
||||
const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring';
|
||||
const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector);
|
||||
if (prometheusSettingsWrapper) {
|
||||
const customMetrics = new CustomMetrics(prometheusSettingsSelector);
|
||||
customMetrics.init();
|
||||
}
|
||||
const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring';
|
||||
const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector);
|
||||
if (prometheusSettingsWrapper) {
|
||||
const customMetrics = new CustomMetrics(prometheusSettingsSelector);
|
||||
customMetrics.init();
|
||||
}
|
||||
|
||||
PrometheusAlerts();
|
||||
});
|
||||
PrometheusAlerts();
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import { mount2faAuthentication } from '~/authentication/mount_2fa';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', mount2faAuthentication);
|
||||
mount2faAuthentication();
|
||||
|
|
|
@ -7,18 +7,16 @@ import preserveUrlFragment from './preserve_url_fragment';
|
|||
import SigninTabsMemoizer from './signin_tabs_memoizer';
|
||||
import UsernameValidator from './username_validator';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new UsernameValidator(); // eslint-disable-line no-new
|
||||
new LengthValidator(); // eslint-disable-line no-new
|
||||
new SigninTabsMemoizer(); // eslint-disable-line no-new
|
||||
new NoEmojiValidator(); // eslint-disable-line no-new
|
||||
new UsernameValidator(); // eslint-disable-line no-new
|
||||
new LengthValidator(); // eslint-disable-line no-new
|
||||
new SigninTabsMemoizer(); // eslint-disable-line no-new
|
||||
new NoEmojiValidator(); // eslint-disable-line no-new
|
||||
|
||||
new OAuthRememberMe({
|
||||
container: $('.omniauth-container'),
|
||||
}).bindEvents();
|
||||
new OAuthRememberMe({
|
||||
container: $('.omniauth-container'),
|
||||
}).bindEvents();
|
||||
|
||||
// Save the URL fragment from the current window location. This will be present if the user was
|
||||
// redirected to sign-in after attempting to access a protected URL that included a fragment.
|
||||
preserveUrlFragment(window.location.hash);
|
||||
initVueAlerts();
|
||||
});
|
||||
// Save the URL fragment from the current window location. This will be present if the user was
|
||||
// redirected to sign-in after attempting to access a protected URL that included a fragment.
|
||||
preserveUrlFragment(window.location.hash);
|
||||
initVueAlerts();
|
||||
|
|
|
@ -26,9 +26,10 @@ class Admin::UsersController < Admin::ApplicationController
|
|||
def show
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def projects
|
||||
@personal_projects = user.personal_projects
|
||||
@joined_projects = user.projects.joined(@user)
|
||||
@personal_projects = user.personal_projects.includes(:topics)
|
||||
@joined_projects = user.projects.joined(@user).includes(:topics)
|
||||
end
|
||||
|
||||
def keys
|
||||
|
|
|
@ -81,7 +81,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
|
|||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def preload_associations(projects)
|
||||
projects.includes(:route, :creator, :group, namespace: [:route, :owner]).preload(:project_feature)
|
||||
projects.includes(:route, :creator, :group, :topics, namespace: [:route, :owner]).preload(:project_feature)
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ class Explore::ProjectsController < Explore::ApplicationController
|
|||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def preload_associations(projects)
|
||||
projects.includes(:route, :creator, :group, :project_feature, namespace: [:route, :owner])
|
||||
projects.includes(:route, :creator, :group, :project_feature, :topics, namespace: [:route, :owner])
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
|
|
|
@ -65,17 +65,13 @@ class JiraConnect::AppDescriptorController < JiraConnect::ApplicationController
|
|||
|
||||
# See https://developer.atlassian.com/cloud/jira/software/modules/development-tool/
|
||||
def development_tool_module
|
||||
actions = {}
|
||||
|
||||
if JiraConnect::BranchesController.feature_enabled?(current_user)
|
||||
actions[:createBranch] = {
|
||||
templateUrl: new_jira_connect_branch_url + '?issue_key={issue.key}&issue_summary={issue.summary}'
|
||||
}
|
||||
end
|
||||
|
||||
{
|
||||
jiraDevelopmentTool: {
|
||||
actions: actions,
|
||||
actions: {
|
||||
createBranch: {
|
||||
templateUrl: new_jira_connect_branch_url + '?issue_key={issue.key}&issue_summary={issue.summary}'
|
||||
}
|
||||
},
|
||||
key: 'gitlab-development-tool',
|
||||
application: { value: 'GitLab' },
|
||||
name: { value: 'GitLab' },
|
||||
|
|
|
@ -3,18 +3,12 @@
|
|||
# NOTE: This controller does not inherit from JiraConnect::ApplicationController
|
||||
# because we don't receive a JWT for this action, so we rely on standard GitLab authentication.
|
||||
class JiraConnect::BranchesController < ApplicationController
|
||||
before_action :feature_enabled!
|
||||
|
||||
feature_category :integrations
|
||||
|
||||
def new
|
||||
@new_branch_data = new_branch_data
|
||||
end
|
||||
|
||||
def self.feature_enabled?(user)
|
||||
Feature.enabled?(:jira_connect_create_branch, user, default_enabled: :yaml)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initial_branch_name
|
||||
|
@ -32,8 +26,4 @@ class JiraConnect::BranchesController < ApplicationController
|
|||
success_state_svg_path: ActionController::Base.helpers.image_path('illustrations/merge_requests.svg')
|
||||
}
|
||||
end
|
||||
|
||||
def feature_enabled!
|
||||
render_404 unless self.class.feature_enabled?(current_user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -99,7 +99,7 @@ class Projects::ForksController < Projects::ApplicationController
|
|||
current_user: current_user
|
||||
).execute
|
||||
|
||||
forks.includes(:route, :creator, :group, namespace: [:route, :owner])
|
||||
forks.includes(:route, :creator, :group, :topics, namespace: [:route, :owner])
|
||||
end
|
||||
|
||||
def fork_service
|
||||
|
|
|
@ -434,9 +434,9 @@ class Event < ApplicationRecord
|
|||
|
||||
def design_action_names
|
||||
{
|
||||
created: _('uploaded'),
|
||||
updated: _('revised'),
|
||||
destroyed: _('deleted')
|
||||
created: _('added'),
|
||||
updated: _('updated'),
|
||||
destroyed: _('removed')
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -397,16 +397,16 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
|||
end
|
||||
|
||||
def topics_to_show
|
||||
project.topic_list.take(MAX_TOPICS_TO_SHOW) # rubocop: disable CodeReuse/ActiveRecord
|
||||
project_topic_list.take(MAX_TOPICS_TO_SHOW) # rubocop: disable CodeReuse/ActiveRecord
|
||||
end
|
||||
|
||||
def topics_not_shown
|
||||
project.topic_list - topics_to_show
|
||||
project_topic_list - topics_to_show
|
||||
end
|
||||
|
||||
def count_of_extra_topics_not_shown
|
||||
if project.topic_list.count > MAX_TOPICS_TO_SHOW
|
||||
project.topic_list.count - MAX_TOPICS_TO_SHOW
|
||||
if project_topic_list.count > MAX_TOPICS_TO_SHOW
|
||||
project_topic_list.count - MAX_TOPICS_TO_SHOW
|
||||
else
|
||||
0
|
||||
end
|
||||
|
@ -486,6 +486,12 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
|||
**additional_params
|
||||
)
|
||||
end
|
||||
|
||||
def project_topic_list
|
||||
strong_memoize(:project_topic_list) do
|
||||
project.topics.map(&:name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ProjectPresenter.prepend_mod_with('ProjectPresenter')
|
||||
|
|
|
@ -22,8 +22,9 @@ module Search
|
|||
filters: { state: params[:state], confidential: params[:confidential] })
|
||||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def projects
|
||||
@projects ||= ProjectsFinder.new(params: { non_archived: true }, current_user: current_user).execute
|
||||
@projects ||= ProjectsFinder.new(params: { non_archived: true }, current_user: current_user).execute.includes(:topics, :taggings)
|
||||
end
|
||||
|
||||
def allowed_scopes
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
- empty_repo = @project.empty_repo?
|
||||
- show_auto_devops_callout = show_auto_devops_callout?(@project)
|
||||
- max_project_topic_length = 15
|
||||
- emails_disabled = @project.emails_disabled?
|
||||
- cache_enabled = Feature.enabled?(:cache_home_panel, @project, type: :development, default_enabled: :yaml)
|
||||
|
||||
|
@ -25,24 +24,8 @@
|
|||
%span.access-request-links.gl-ml-3
|
||||
= render 'shared/members/access_request_links', source: @project
|
||||
|
||||
- if @project.topic_list.present?
|
||||
= cache_if(cache_enabled, [@project, :topic_list], expires_in: 1.day) do
|
||||
%span.home-panel-topic-list.mt-2.w-100.d-inline-flex.gl-font-base.gl-font-weight-normal.gl-align-items-center
|
||||
= sprite_icon('tag', css_class: 'icon gl-relative gl-mr-2')
|
||||
|
||||
- @project.topics_to_show.each do |topic|
|
||||
- project_topics_classes = "badge badge-pill badge-secondary gl-mr-2"
|
||||
- explore_project_topic_path = explore_projects_path(topic: topic)
|
||||
- if topic.length > max_project_topic_length
|
||||
%a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
|
||||
= topic.titleize
|
||||
- else
|
||||
%a{ class: project_topics_classes, href: explore_project_topic_path, itemprop: 'keywords' }
|
||||
= topic.titleize
|
||||
|
||||
- if @project.has_extra_topics?
|
||||
.text-nowrap.has-tooltip{ data: { container: 'body' }, title: @project.has_extra_topics? ? @project.topics_not_shown.join(', ') : nil }
|
||||
= _("+ %{count} more") % { count: @project.count_of_extra_topics_not_shown }
|
||||
.gl-mt-3.gl-pl-3.gl-w-full
|
||||
= render "shared/projects/topics", project: @project, cache_enabled: cache_enabled
|
||||
|
||||
= cache_if(cache_enabled, [@project, :buttons, current_user, @notification_setting], expires_in: 1.day) do
|
||||
.project-repo-buttons.gl-display-flex.gl-justify-content-md-end.gl-align-items-start.gl-flex-wrap.gl-mt-5
|
||||
|
|
|
@ -65,6 +65,10 @@
|
|||
.description.d-none.d-sm-block.gl-mr-3
|
||||
= markdown_field(project, :description)
|
||||
|
||||
- if project.topics.any?
|
||||
.gl-mt-2
|
||||
= render "shared/projects/topics", project: project.present(current_user: current_user)
|
||||
|
||||
= render_if_exists 'shared/projects/removed', project: project
|
||||
|
||||
.controls.d-flex.flex-sm-column.align-items-center.align-items-sm-end.flex-wrap.flex-shrink-0.text-secondary{ class: css_controls_class.join(" ") }
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
- cache_enabled = false unless local_assigns[:cache_enabled] == true
|
||||
- max_project_topic_length = 15
|
||||
- project_topics_classes = "badge badge-pill badge-secondary gl-mr-2"
|
||||
|
||||
- if project.topics.present?
|
||||
= cache_if(cache_enabled, [project, :topic_list], expires_in: 1.day) do
|
||||
%span.gl-w-full.gl-display-inline-flex.gl-font-base.gl-font-weight-normal.gl-align-items-center{ 'data-testid': 'project_topic_list' }
|
||||
= sprite_icon('tag', css_class: 'icon gl-relative gl-mr-2')
|
||||
|
||||
- project.topics_to_show.each do |topic|
|
||||
- explore_project_topic_path = explore_projects_path(topic: topic)
|
||||
- if topic.length > max_project_topic_length
|
||||
%a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
|
||||
= truncate(topic, length: max_project_topic_length)
|
||||
- else
|
||||
%a{ class: project_topics_classes, href: explore_project_topic_path, itemprop: 'keywords' }
|
||||
= topic
|
||||
|
||||
- if project.has_extra_topics?
|
||||
- title = _('More topics')
|
||||
- content = capture do
|
||||
%span.gl-display-inline-flex
|
||||
- project.topics_not_shown.each do |topic|
|
||||
- explore_project_topic_path = explore_projects_path(topic: topic)
|
||||
- if topic.length > max_project_topic_length
|
||||
%a{ class: "#{ project_topics_classes } gl-mb-3 str-truncated has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
|
||||
= truncate(topic, length: max_project_topic_length)
|
||||
- else
|
||||
%a{ class: "#{ project_topics_classes } gl-mb-3", href: explore_project_topic_path, itemprop: 'keywords' }
|
||||
= topic
|
||||
.text-nowrap{ role: 'button', tabindex: 0, data: { toggle: 'popover', html: 'true', placement: 'top', title: title, content: content } }
|
||||
= _("+ %{count} more") % { count: project.count_of_extra_topics_not_shown }
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: jira_connect_create_branch
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66032
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336191
|
||||
milestone: '14.2'
|
||||
type: development
|
||||
group: group::ecosystem
|
||||
default_enabled: false
|
|
@ -837,7 +837,7 @@ descriptions:
|
|||
- Mention the name of the resource in the description. Example:
|
||||
`'Labels of the issue'` (issue being the resource).
|
||||
- Use `"{x} of the {y}"` where possible. Example: `'Title of the issue'`.
|
||||
Do not start descriptions with `The`.
|
||||
Do not start descriptions with `The` or `A`, for consistency and conciseness.
|
||||
- Descriptions of `GraphQL::Types::Boolean` fields should answer the question: "What does
|
||||
this field do?". Example: `'Indicates project has a Git repository'`.
|
||||
- Always include the word `"timestamp"` when describing an argument or
|
||||
|
|
|
@ -1145,3 +1145,7 @@ Note that the metrics linked here are GitLab-internal only:
|
|||
- [Size](https://thanos.gitlab.net/graph?g0.range_input=2h&g0.max_source_resolution=0s&g0.expr=topk(500%2C%20max%20by%20(relname)%20(pg_total_relation_size_bytes%7Benvironment%3D%22gprd%22%7D))&g0.tab=1) is greater than 10 GB
|
||||
|
||||
Any table which has some high read operation compared to current [high-traffic tables](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L4) might be a good candidate.
|
||||
|
||||
As a general rule, we discourage adding columns to high-traffic tables that are purely for
|
||||
analytics or reporting of GitLab.com. This can have negative performance impacts for all
|
||||
self-managed instances without providing direct feature value to them.
|
||||
|
|
|
@ -37,7 +37,8 @@ After the integration is [set up on GitLab and Jira](#configure-the-integration)
|
|||
|
||||
- Refer to any Jira issue by its ID (in uppercase) in GitLab branch names,
|
||||
commit messages, and merge request titles.
|
||||
- See the linked branches, commits, and merge requests in Jira issues:
|
||||
- See the linked branches, commits, and merge requests in Jira issues.
|
||||
- Create GitLab branches from Jira issues ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66032) in GitLab 14.2).
|
||||
|
||||
At this time, merge requests are called "pull requests" in Jira issues.
|
||||
This name may change in a future Jira release.
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 78 KiB |
|
@ -49,13 +49,14 @@ To set up the Jira development panel integration:
|
|||
| Capability | Jira integration | Jira Development panel integration |
|
||||
|-|-|-|
|
||||
| Mention a Jira issue ID in a GitLab commit or merge request, and a link to the Jira issue is created. | Yes. | No. |
|
||||
| Mention a Jira issue ID in GitLab and the Jira issue shows the GitLab issue or merge request. | Yes. A Jira comment with the GitLab issue or MR title links to GitLab. The first mention is also added to the Jira issue under **Web links**. | Yes, in the issue's Development panel. |
|
||||
| Mention a Jira issue ID in a GitLab commit message and the Jira issue shows the commit message. | Yes. The entire commit message is displayed in the Jira issue as a comment and under **Web links**. Each message links back to the commit in GitLab. | Yes, in the issue's Development panel and optionally with a custom comment on the Jira issue using Jira [Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html). |
|
||||
| Mention a Jira issue ID in GitLab and the Jira issue shows the GitLab issue or merge request. | Yes. A Jira comment with the GitLab issue or MR title links to GitLab. The first mention is also added to the Jira issue under **Web links**. | Yes, in the issue's [development panel](https://support.atlassian.com/jira-software-cloud/docs/view-development-information-for-an-issue/). |
|
||||
| Mention a Jira issue ID in a GitLab commit message and the Jira issue shows the commit message. | Yes. The entire commit message is displayed in the Jira issue as a comment and under **Web links**. Each message links back to the commit in GitLab. | Yes, in the issue's [development panel](https://support.atlassian.com/jira-software-cloud/docs/view-development-information-for-an-issue/) and optionally with a custom comment on the Jira issue using Jira [Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html). |
|
||||
| Mention a Jira issue ID in a GitLab branch name and the Jira issue shows the branch name. | No. | Yes, in the issue's [development panel](https://support.atlassian.com/jira-software-cloud/docs/view-development-information-for-an-issue/). |
|
||||
| Add Jira time tracking to an issue. | No. | Yes. Time can be specified using Jira Smart Commits. |
|
||||
| Use a Git commit or merge request to transition or close a Jira issue. | Yes. Only a single transition type, typically configured to close the issue by setting it to Done. | Yes. Transition to any state using Jira Smart Commits. |
|
||||
| Display a list of Jira issues. | Yes. **(PREMIUM)** | No. |
|
||||
| Create a Jira issue from a vulnerability or finding. | Yes. **(ULTIMATE)** | No. |
|
||||
| Create a GitLab branch from a Jira issue. | No. | Yes, in the issue's [development panel](https://support.atlassian.com/jira-software-cloud/docs/view-development-information-for-an-issue/). |
|
||||
|
||||
## Authentication in Jira
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ module Gitlab
|
|||
# balancer with said hosts. Requests may continue to use the old hosts
|
||||
# until they complete.
|
||||
class ServiceDiscovery
|
||||
attr_reader :interval, :record, :record_type, :disconnect_timeout
|
||||
attr_reader :interval, :record, :record_type, :disconnect_timeout,
|
||||
:load_balancer
|
||||
|
||||
MAX_SLEEP_ADJUSTMENT = 10
|
||||
|
||||
|
@ -40,7 +41,17 @@ module Gitlab
|
|||
# disconnect_timeout - The time after which an old host should be
|
||||
# forcefully disconnected.
|
||||
# use_tcp - Use TCP instaed of UDP to look up resources
|
||||
def initialize(nameserver:, port:, record:, record_type: 'A', interval: 60, disconnect_timeout: 120, use_tcp: false)
|
||||
# load_balancer - The load balancer instance to use
|
||||
def initialize(
|
||||
nameserver:,
|
||||
port:,
|
||||
record:,
|
||||
record_type: 'A',
|
||||
interval: 60,
|
||||
disconnect_timeout: 120,
|
||||
use_tcp: false,
|
||||
load_balancer: LoadBalancing.proxy.load_balancer
|
||||
)
|
||||
@nameserver = nameserver
|
||||
@port = port
|
||||
@record = record
|
||||
|
@ -48,6 +59,7 @@ module Gitlab
|
|||
@interval = interval
|
||||
@disconnect_timeout = disconnect_timeout
|
||||
@use_tcp = use_tcp
|
||||
@load_balancer = load_balancer
|
||||
end
|
||||
|
||||
def start
|
||||
|
@ -147,10 +159,6 @@ module Gitlab
|
|||
end.sort
|
||||
end
|
||||
|
||||
def load_balancer
|
||||
LoadBalancing.proxy.load_balancer
|
||||
end
|
||||
|
||||
def resolver
|
||||
@resolver ||= Net::DNS::Resolver.new(
|
||||
nameservers: Resolver.new(@nameserver).resolve,
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
namespace :gitlab do
|
||||
namespace :product_intelligence do
|
||||
# @example
|
||||
# bundle exec rake gitlab:product_intelligence:activate_metrics MILESTONE=14.0
|
||||
|
||||
desc 'GitLab | Product Intelligence | Update milestone metrics status to data_available'
|
||||
task activate_metrics: :environment do
|
||||
milestone = ENV['MILESTONE']
|
||||
raise "Please supply the MILESTONE env var".color(:red) unless milestone.present?
|
||||
|
||||
Gitlab::Usage::MetricDefinition.definitions.values.each do |metric|
|
||||
next if metric.attributes[:milestone] != milestone || metric.attributes[:status] != 'implemented'
|
||||
|
||||
metric.attributes[:status] = 'data_available'
|
||||
path = metric.path
|
||||
File.open(path, "w") { |file| file << metric.to_h.deep_stringify_keys.to_yaml }
|
||||
end
|
||||
|
||||
puts "Task completed successfully"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21619,6 +21619,9 @@ msgstr ""
|
|||
msgid "More than %{number_commits_distance} commits different with %{default_branch}"
|
||||
msgstr ""
|
||||
|
||||
msgid "More topics"
|
||||
msgstr ""
|
||||
|
||||
msgid "Most relevant"
|
||||
msgstr ""
|
||||
|
||||
|
@ -38487,6 +38490,9 @@ msgstr[1] ""
|
|||
msgid "access:"
|
||||
msgstr ""
|
||||
|
||||
msgid "added"
|
||||
msgstr ""
|
||||
|
||||
msgid "added %{created_at_timeago}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -39849,6 +39855,9 @@ msgstr ""
|
|||
msgid "remove weight"
|
||||
msgstr ""
|
||||
|
||||
msgid "removed"
|
||||
msgstr ""
|
||||
|
||||
msgid "removed a Zoom call from this issue"
|
||||
msgstr ""
|
||||
|
||||
|
@ -39869,9 +39878,6 @@ msgstr ""
|
|||
msgid "reset it."
|
||||
msgstr ""
|
||||
|
||||
msgid "revised"
|
||||
msgstr ""
|
||||
|
||||
msgid "satisfied"
|
||||
msgstr ""
|
||||
|
||||
|
@ -40043,9 +40049,6 @@ msgstr ""
|
|||
msgid "updated %{time_ago}"
|
||||
msgstr ""
|
||||
|
||||
msgid "uploaded"
|
||||
msgstr ""
|
||||
|
||||
msgid "uploads"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
$:.unshift(File.expand_path('lib', __dir__))
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = 'chemlab-library-gitlab'
|
||||
spec.version = '0.1.1'
|
||||
spec.authors = ['GitLab Quality']
|
||||
spec.email = ['quality@gitlab.com']
|
||||
|
||||
spec.required_ruby_version = '>= 2.5' # rubocop:disable Gemspec/RequiredRubyVersion
|
||||
|
||||
spec.summary = 'Chemlab Page Libraries for GitLab'
|
||||
spec.homepage = 'https://gitlab.com/'
|
||||
spec.license = 'MIT'
|
||||
|
||||
spec.files = `git ls-files -- lib/*`.split("\n")
|
||||
|
||||
spec.require_paths = ['lib']
|
||||
|
||||
spec.add_runtime_dependency 'chemlab', '~> 0.7'
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Chemlab Page Libraries for GitLab
|
||||
module Gitlab
|
||||
module Page
|
||||
module Main
|
||||
autoload :Login, 'gitlab/page/main/login'
|
||||
end
|
||||
|
||||
module Subscriptions
|
||||
autoload :New, 'gitlab/page/subscriptions/new'
|
||||
end
|
||||
|
||||
module Group
|
||||
module Settings
|
||||
autoload :Billing, 'gitlab/page/group/settings/billing'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Page
|
||||
module Group
|
||||
module Settings
|
||||
class Billing < Chemlab::Page
|
||||
# TODO: Supplant with data-qa-selectors
|
||||
h4 :billing_plan_header, css: 'div.billing-plan-header h4'
|
||||
|
||||
link :start_your_free_trial
|
||||
|
||||
link :upgrade_to_premium, css: '[data-testid="plan-card-premium"] a.billing-cta-purchase-new'
|
||||
link :upgrade_to_ultimate, css: '[data-testid="plan-card-ultimate"] a.billing-cta-purchase-new'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,107 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Page
|
||||
module Group
|
||||
module Settings
|
||||
module Billing
|
||||
# @note Defined as +h4 :billing_plan_header+
|
||||
# @return [String] The text content or value of +billing_plan_header+
|
||||
def billing_plan_header
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::Billing.perform do |billing|
|
||||
# expect(billing.billing_plan_header_element).to exist
|
||||
# end
|
||||
# @return [Watir::H4] The raw +H4+ element
|
||||
def billing_plan_header_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::Billing.perform do |billing|
|
||||
# expect(billing).to be_billing_plan_header
|
||||
# end
|
||||
# @return [Boolean] true if the +billing_plan_header+ element is present on the page
|
||||
def billing_plan_header?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +link :start_your_free_trial+
|
||||
# Clicks +start_your_free_trial+
|
||||
def start_your_free_trial
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::Billing.perform do |billing|
|
||||
# expect(billing.start_your_free_trial_element).to exist
|
||||
# end
|
||||
# @return [Watir::Link] The raw +Link+ element
|
||||
def start_your_free_trial_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::Billing.perform do |billing|
|
||||
# expect(billing).to be_start_your_free_trial
|
||||
# end
|
||||
# @return [Boolean] true if the +start_your_free_trial+ element is present on the page
|
||||
def start_your_free_trial?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +link :upgrade_to_premium+
|
||||
# Clicks +upgrade_to_premium+
|
||||
def upgrade_to_premium
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::Billing.perform do |billing|
|
||||
# expect(billing.upgrade_to_premium_element).to exist
|
||||
# end
|
||||
# @return [Watir::Link] The raw +Link+ element
|
||||
def upgrade_to_premium_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::Billing.perform do |billing|
|
||||
# expect(billing).to be_upgrade_to_premium
|
||||
# end
|
||||
# @return [Boolean] true if the +upgrade_to_premium+ element is present on the page
|
||||
def upgrade_to_premium?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +link :upgrade_to_ultimate+
|
||||
# Clicks +upgrade_to_ultimate+
|
||||
def upgrade_to_ultimate
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::Billing.perform do |billing|
|
||||
# expect(billing.upgrade_to_ultimate_element).to exist
|
||||
# end
|
||||
# @return [Watir::Link] The raw +Link+ element
|
||||
def upgrade_to_ultimate_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::Billing.perform do |billing|
|
||||
# expect(billing).to be_upgrade_to_ultimate
|
||||
# end
|
||||
# @return [Boolean] true if the +upgrade_to_ultimate+ element is present on the page
|
||||
def upgrade_to_ultimate?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Page
|
||||
module Main
|
||||
class Login < Chemlab::Page
|
||||
path '/users/sign_in'
|
||||
|
||||
text_field :login_field
|
||||
text_field :password_field
|
||||
button :sign_in_button
|
||||
|
||||
def sign_in_as(username:, password:)
|
||||
self.login_field = username
|
||||
self.password_field = password
|
||||
|
||||
sign_in_button
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,101 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Page
|
||||
module Main
|
||||
module Login
|
||||
# @note Defined as +text_field :login_field+
|
||||
# @return [String] The text content or value of +login_field+
|
||||
def login_field
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of login_field
|
||||
# @example
|
||||
# Gitlab::Page::Main::Login.perform do |login|
|
||||
# login.login_field = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def login_field=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Main::Login.perform do |login|
|
||||
# expect(login.login_field_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def login_field_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Main::Login.perform do |login|
|
||||
# expect(login).to be_login_field
|
||||
# end
|
||||
# @return [Boolean] true if the +login_field+ element is present on the page
|
||||
def login_field?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +text_field :password_field+
|
||||
# @return [String] The text content or value of +password_field+
|
||||
def password_field
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of password_field
|
||||
# @example
|
||||
# Gitlab::Page::Main::Login.perform do |login|
|
||||
# login.password_field = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def password_field=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Main::Login.perform do |login|
|
||||
# expect(login.password_field_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def password_field_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Main::Login.perform do |login|
|
||||
# expect(login).to be_password_field
|
||||
# end
|
||||
# @return [Boolean] true if the +password_field+ element is present on the page
|
||||
def password_field?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +button :sign_in_button+
|
||||
# Clicks +sign_in_button+
|
||||
def sign_in_button
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Main::Login.perform do |login|
|
||||
# expect(login.sign_in_button_element).to exist
|
||||
# end
|
||||
# @return [Watir::Button] The raw +Button+ element
|
||||
def sign_in_button_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Main::Login.perform do |login|
|
||||
# expect(login).to be_sign_in_button
|
||||
# end
|
||||
# @return [Boolean] true if the +sign_in_button+ element is present on the page
|
||||
def sign_in_button?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Page
|
||||
module Subscriptions
|
||||
class New < Chemlab::Page
|
||||
path '/subscriptions/new'
|
||||
|
||||
# Subscription Details
|
||||
select :plan_name
|
||||
select :group_name
|
||||
text_field :number_of_users
|
||||
button :continue_to_billing, text: /Continue to billing/
|
||||
|
||||
# Billing address
|
||||
select :country
|
||||
text_field :street_address_1
|
||||
text_field :street_address_2
|
||||
text_field :city
|
||||
select :state
|
||||
text_field :zip_code
|
||||
button :continue_to_payment, text: /Continue to payment/
|
||||
|
||||
# Payment method
|
||||
# TODO: Revisit when https://gitlab.com/gitlab-org/quality/chemlab/-/issues/6 is closed
|
||||
iframe :payment_form, id: 'z_hppm_iframe'
|
||||
|
||||
text_field(:name_on_card) { payment_form_element.text_field(id: 'input-creditCardHolderName') }
|
||||
text_field(:card_number) { payment_form_element.text_field(id: 'input-creditCardNumber') }
|
||||
select(:expiration_month) { payment_form_element.select(id: 'input-creditCardExpirationMonth') }
|
||||
select(:expiration_year) { payment_form_element.select(id: 'input-creditCardExpirationYear') }
|
||||
text_field(:cvv) { payment_form_element.text_field(id: 'input-cardSecurityCode') }
|
||||
link(:review_your_order) { payment_form_element.link(text: /Review your order/) }
|
||||
# ENDTODO
|
||||
|
||||
# Confirmation
|
||||
button :confirm_purchase, text: /Confirm purchase/
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,545 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Page
|
||||
module Subscriptions
|
||||
module New
|
||||
# @note Defined as +select :plan_name+
|
||||
# @return [String] The text content or value of +plan_name+
|
||||
def plan_name
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.plan_name_element).to exist
|
||||
# end
|
||||
# @return [Watir::Select] The raw +Select+ element
|
||||
def plan_name_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_plan_name
|
||||
# end
|
||||
# @return [Boolean] true if the +plan_name+ element is present on the page
|
||||
def plan_name?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +select :group_name+
|
||||
# @return [String] The text content or value of +group_name+
|
||||
def group_name
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.group_name_element).to exist
|
||||
# end
|
||||
# @return [Watir::Select] The raw +Select+ element
|
||||
def group_name_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_group_name
|
||||
# end
|
||||
# @return [Boolean] true if the +group_name+ element is present on the page
|
||||
def group_name?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +text_field :number_of_users+
|
||||
# @return [String] The text content or value of +number_of_users+
|
||||
def number_of_users
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of number_of_users
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# new.number_of_users = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def number_of_users=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.number_of_users_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def number_of_users_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_number_of_users
|
||||
# end
|
||||
# @return [Boolean] true if the +number_of_users+ element is present on the page
|
||||
def number_of_users?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +button :continue_to_billing+
|
||||
# Clicks +continue_to_billing+
|
||||
def continue_to_billing
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.continue_to_billing_element).to exist
|
||||
# end
|
||||
# @return [Watir::Button] The raw +Button+ element
|
||||
def continue_to_billing_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_continue_to_billing
|
||||
# end
|
||||
# @return [Boolean] true if the +continue_to_billing+ element is present on the page
|
||||
def continue_to_billing?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +select :country+
|
||||
# @return [String] The text content or value of +country+
|
||||
def country
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.country_element).to exist
|
||||
# end
|
||||
# @return [Watir::Select] The raw +Select+ element
|
||||
def country_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_country
|
||||
# end
|
||||
# @return [Boolean] true if the +country+ element is present on the page
|
||||
def country?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +text_field :street_address_1+
|
||||
# @return [String] The text content or value of +street_address_1+
|
||||
def street_address_1
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of street_address_1
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# new.street_address_1 = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def street_address_1=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.street_address_1_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def street_address_1_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_street_address_1
|
||||
# end
|
||||
# @return [Boolean] true if the +street_address_1+ element is present on the page
|
||||
def street_address_1?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +text_field :street_address_2+
|
||||
# @return [String] The text content or value of +street_address_2+
|
||||
def street_address_2
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of street_address_2
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# new.street_address_2 = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def street_address_2=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.street_address_2_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def street_address_2_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_street_address_2
|
||||
# end
|
||||
# @return [Boolean] true if the +street_address_2+ element is present on the page
|
||||
def street_address_2?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +text_field :city+
|
||||
# @return [String] The text content or value of +city+
|
||||
def city
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of city
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# new.city = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def city=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.city_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def city_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_city
|
||||
# end
|
||||
# @return [Boolean] true if the +city+ element is present on the page
|
||||
def city?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +select :state+
|
||||
# @return [String] The text content or value of +state+
|
||||
def state
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.state_element).to exist
|
||||
# end
|
||||
# @return [Watir::Select] The raw +Select+ element
|
||||
def state_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_state
|
||||
# end
|
||||
# @return [Boolean] true if the +state+ element is present on the page
|
||||
def state?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +text_field :zip_code+
|
||||
# @return [String] The text content or value of +zip_code+
|
||||
def zip_code
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of zip_code
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# new.zip_code = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def zip_code=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.zip_code_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def zip_code_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_zip_code
|
||||
# end
|
||||
# @return [Boolean] true if the +zip_code+ element is present on the page
|
||||
def zip_code?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +button :continue_to_payment+
|
||||
# Clicks +continue_to_payment+
|
||||
def continue_to_payment
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.continue_to_payment_element).to exist
|
||||
# end
|
||||
# @return [Watir::Button] The raw +Button+ element
|
||||
def continue_to_payment_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_continue_to_payment
|
||||
# end
|
||||
# @return [Boolean] true if the +continue_to_payment+ element is present on the page
|
||||
def continue_to_payment?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +iframe :payment_form+
|
||||
# @return [String] The text content or value of +payment_form+
|
||||
def payment_form
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.payment_form_element).to exist
|
||||
# end
|
||||
# @return [Watir::Iframe] The raw +Iframe+ element
|
||||
def payment_form_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_payment_form
|
||||
# end
|
||||
# @return [Boolean] true if the +payment_form+ element is present on the page
|
||||
def payment_form?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +text_field :name_on_card+
|
||||
# @return [String] The text content or value of +name_on_card+
|
||||
def name_on_card
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of name_on_card
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# new.name_on_card = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def name_on_card=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.name_on_card_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def name_on_card_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_name_on_card
|
||||
# end
|
||||
# @return [Boolean] true if the +name_on_card+ element is present on the page
|
||||
def name_on_card?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +text_field :card_number+
|
||||
# @return [String] The text content or value of +card_number+
|
||||
def card_number
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of card_number
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# new.card_number = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def card_number=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.card_number_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def card_number_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_card_number
|
||||
# end
|
||||
# @return [Boolean] true if the +card_number+ element is present on the page
|
||||
def card_number?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +select :expiration_month+
|
||||
# @return [String] The text content or value of +expiration_month+
|
||||
def expiration_month
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.expiration_month_element).to exist
|
||||
# end
|
||||
# @return [Watir::Select] The raw +Select+ element
|
||||
def expiration_month_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_expiration_month
|
||||
# end
|
||||
# @return [Boolean] true if the +expiration_month+ element is present on the page
|
||||
def expiration_month?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +select :expiration_year+
|
||||
# @return [String] The text content or value of +expiration_year+
|
||||
def expiration_year
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.expiration_year_element).to exist
|
||||
# end
|
||||
# @return [Watir::Select] The raw +Select+ element
|
||||
def expiration_year_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_expiration_year
|
||||
# end
|
||||
# @return [Boolean] true if the +expiration_year+ element is present on the page
|
||||
def expiration_year?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +text_field :cvv+
|
||||
# @return [String] The text content or value of +cvv+
|
||||
def cvv
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# Set the value of cvv
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# new.cvv = 'value'
|
||||
# end
|
||||
# @param value [String] The value to set.
|
||||
def cvv=(value)
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.cvv_element).to exist
|
||||
# end
|
||||
# @return [Watir::TextField] The raw +TextField+ element
|
||||
def cvv_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_cvv
|
||||
# end
|
||||
# @return [Boolean] true if the +cvv+ element is present on the page
|
||||
def cvv?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +link :review_your_order+
|
||||
# Clicks +review_your_order+
|
||||
def review_your_order
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.review_your_order_element).to exist
|
||||
# end
|
||||
# @return [Watir::Link] The raw +Link+ element
|
||||
def review_your_order_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_review_your_order
|
||||
# end
|
||||
# @return [Boolean] true if the +review_your_order+ element is present on the page
|
||||
def review_your_order?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +button :confirm_purchase+
|
||||
# Clicks +confirm_purchase+
|
||||
def confirm_purchase
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new.confirm_purchase_element).to exist
|
||||
# end
|
||||
# @return [Watir::Button] The raw +Button+ element
|
||||
def confirm_purchase_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Subscriptions::New.perform do |new|
|
||||
# expect(new).to be_confirm_purchase
|
||||
# end
|
||||
# @return [Boolean] true if the +confirm_purchase+ element is present on the page
|
||||
def confirm_purchase?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
2
qa/qa.rb
2
qa/qa.rb
|
@ -8,6 +8,8 @@ require_relative '../lib/gitlab'
|
|||
require_relative '../lib/gitlab/utils'
|
||||
require_relative '../config/initializers/0_inject_enterprise_edition_module'
|
||||
|
||||
require_relative 'lib/gitlab'
|
||||
|
||||
require 'chemlab'
|
||||
|
||||
module QA
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
module Page
|
||||
module Group
|
||||
module Settings
|
||||
class Billing < Chemlab::Page
|
||||
link :start_your_free_trial
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -25,6 +25,7 @@ module Matchers
|
|||
@duration = options[:duration]
|
||||
@attempts = options[:attempts]
|
||||
@interval = options[:interval]
|
||||
@reload_page = options[:reload_page]
|
||||
end
|
||||
|
||||
def supports_block_expectations?
|
||||
|
@ -59,7 +60,8 @@ module Matchers
|
|||
QA::Support::Retrier.retry_until(
|
||||
max_attempts: @attempts,
|
||||
max_duration: @duration,
|
||||
sleep_interval: @interval || 0.5
|
||||
sleep_interval: @interval || 0.5,
|
||||
reload_page: @reload_page
|
||||
) do
|
||||
QA::Runtime::Logger.debug("evaluating expectation, attempt: #{attempt += 1}")
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#
|
||||
# field :some_field,
|
||||
# GraphQL::Types::String,
|
||||
# description: "A thorough and compelling description."
|
||||
# description: "Thorough and compelling description."
|
||||
# end
|
||||
#
|
||||
# class GoodEnum
|
||||
|
@ -43,8 +43,10 @@ module RuboCop
|
|||
module Cop
|
||||
module Graphql
|
||||
class Descriptions < RuboCop::Cop::Cop
|
||||
MSG_NO_DESCRIPTION = 'Please add a `description` property.'
|
||||
MSG_NO_PERIOD = '`description` strings must end with a `.`.'
|
||||
MSG_STYLE_GUIDE_LINK = 'See the description style guide: https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#description-style-guide'
|
||||
MSG_NO_DESCRIPTION = "Please add a `description` property. #{MSG_STYLE_GUIDE_LINK}"
|
||||
MSG_NO_PERIOD = "`description` strings must end with a `.`. #{MSG_STYLE_GUIDE_LINK}"
|
||||
MSG_BAD_START = "`description` strings should not start with \"A...\" or \"The...\". #{MSG_STYLE_GUIDE_LINK}"
|
||||
|
||||
def_node_matcher :graphql_describable?, <<~PATTERN
|
||||
(send nil? {:field :argument :value} ...)
|
||||
|
@ -75,6 +77,7 @@ module RuboCop
|
|||
return add_offense(node, location: :expression, message: MSG_NO_DESCRIPTION) unless description
|
||||
|
||||
add_offense(node, location: :expression, message: MSG_NO_PERIOD) if no_period?(description)
|
||||
add_offense(node, location: :expression, message: MSG_BAD_START) if bad_start?(description)
|
||||
end
|
||||
|
||||
# Autocorrect missing periods at end of description.
|
||||
|
@ -100,12 +103,19 @@ module RuboCop
|
|||
end
|
||||
|
||||
def no_period?(description)
|
||||
# Test that the description node is a `:str` (as opposed to
|
||||
# a `#copy_field_description` call) before checking.
|
||||
description.type == :str && !description.value.strip.end_with?('.')
|
||||
string?(description) && !description.value.strip.end_with?('.')
|
||||
end
|
||||
|
||||
# Returns a Parser::Source::Range that ends just before the final String delimiter.
|
||||
def bad_start?(description)
|
||||
string?(description) && description.value.strip.downcase.start_with?('a ', 'the ')
|
||||
end
|
||||
|
||||
# Returns true if `description` node is a `:str` (as opposed to a `#copy_field_description` call)
|
||||
def string?(description)
|
||||
description.type == :str
|
||||
end
|
||||
|
||||
# Returns a `Parser::Source::Range` that ends just before the final `String` delimiter.
|
||||
def before_end_quote(string)
|
||||
return string.source_range.adjust(end_pos: -1) unless string.heredoc?
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ RSpec.describe Dashboard::ProjectsController, :aggregate_failures do
|
|||
expect(response).to render_template('dashboard/projects/index')
|
||||
expect(response.body).to include(
|
||||
"pushed to project",
|
||||
"uploaded design #{design.to_reference}",
|
||||
"added design #{design.to_reference}",
|
||||
"created wiki page #{wiki_page.title}",
|
||||
"joined project #{project.full_name}",
|
||||
"closed issue #{issue.to_reference}"
|
||||
|
|
|
@ -86,18 +86,5 @@ RSpec.describe JiraConnect::AppDescriptorController do
|
|||
)
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the jira_connect_create_branch feature is disabled' do
|
||||
before do
|
||||
stub_feature_flags(jira_connect_create_branch: false)
|
||||
end
|
||||
|
||||
it 'does not include the create branch action' do
|
||||
get :show
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(descriptor[:modules][:jiraDevelopmentTool][:actions]).not_to include(:createBranch)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,18 +34,6 @@ RSpec.describe JiraConnect::BranchesController do
|
|||
expect(response).to be_successful
|
||||
expect(assigns(:new_branch_data)).to include('initial_branch_name': nil)
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(jira_connect_create_branch: false)
|
||||
end
|
||||
|
||||
it 'renders a 404 error' do
|
||||
get :new
|
||||
|
||||
expect(response).to be_not_found
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not logged in' do
|
||||
|
|
|
@ -194,6 +194,29 @@ RSpec.describe 'Dashboard Projects' do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'with topics' do
|
||||
context 'when project has topics' do
|
||||
before do
|
||||
project.update_attribute(:topic_list, 'topic1')
|
||||
end
|
||||
|
||||
it 'shows project topics if exist' do
|
||||
visit dashboard_projects_path
|
||||
|
||||
expect(page).to have_selector('[data-testid="project_topic_list"]')
|
||||
expect(page).to have_link('topic1', href: explore_projects_path(topic: 'topic1'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project does not have topics' do
|
||||
it 'does not show project topics' do
|
||||
visit dashboard_projects_path
|
||||
|
||||
expect(page).not_to have_selector('[data-testid="project_topic_list"]')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'last push widget', :use_clean_rails_memory_store_caching do
|
||||
before do
|
||||
event = create(:push_event, project: project, author: user)
|
||||
|
|
|
@ -34,26 +34,26 @@ RSpec.describe 'Projects > Activity > User sees design Activity', :js do
|
|||
visit activity_project_path(project)
|
||||
|
||||
expect(page).to have_content('joined project')
|
||||
expect(page).to have_content(design_activity(uploader, 'uploaded'))
|
||||
expect(page).to have_content(design_activity(editor, 'revised'))
|
||||
expect(page).to have_content(design_activity(deleter, 'deleted'))
|
||||
expect(page).to have_content(design_activity(uploader, 'added'))
|
||||
expect(page).to have_content(design_activity(editor, 'updated'))
|
||||
expect(page).to have_content(design_activity(deleter, 'removed'))
|
||||
end
|
||||
|
||||
it 'allows filtering out the design events', :aggregate_failures do
|
||||
visit activity_project_path(project, event_filter: EventFilter::ISSUE)
|
||||
|
||||
expect(page).not_to have_content(design_activity(uploader, 'uploaded'))
|
||||
expect(page).not_to have_content(design_activity(editor, 'revised'))
|
||||
expect(page).not_to have_content(design_activity(deleter, 'deleted'))
|
||||
expect(page).not_to have_content(design_activity(uploader, 'added'))
|
||||
expect(page).not_to have_content(design_activity(editor, 'updated'))
|
||||
expect(page).not_to have_content(design_activity(deleter, 'removed'))
|
||||
end
|
||||
|
||||
it 'allows filtering in the design events', :aggregate_failures do
|
||||
visit activity_project_path(project, event_filter: EventFilter::DESIGNS)
|
||||
|
||||
expect(page).not_to have_content('joined project')
|
||||
expect(page).to have_content(design_activity(uploader, 'uploaded'))
|
||||
expect(page).to have_content(design_activity(editor, 'revised'))
|
||||
expect(page).to have_content(design_activity(deleter, 'deleted'))
|
||||
expect(page).to have_content(design_activity(uploader, 'added'))
|
||||
expect(page).to have_content(design_activity(editor, 'updated'))
|
||||
expect(page).to have_content(design_activity(deleter, 'removed'))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ RSpec.describe 'Projects > Show > Schema Markup' do
|
|||
expect(page).to have_selector('[itemprop="identifier"]', text: "Project ID: #{project.id}")
|
||||
expect(page).to have_selector('[itemprop="description"]', text: project.description)
|
||||
expect(page).to have_selector('[itemprop="license"]', text: project.repository.license.name)
|
||||
expect(find_all('[itemprop="keywords"]').map(&:text)).to match_array(project.topic_list.map(&:capitalize))
|
||||
expect(find_all('[itemprop="keywords"]').map(&:text)).to match_array(project.topic_list)
|
||||
expect(page).to have_selector('[itemprop="about"]')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -132,8 +132,8 @@ RSpec.describe 'Project' do
|
|||
|
||||
visit path
|
||||
|
||||
expect(page).to have_css('.home-panel-topic-list')
|
||||
expect(page).to have_link('Topic1', href: explore_projects_path(topic: 'topic1'))
|
||||
expect(page).to have_selector('[data-testid="project_topic_list"]')
|
||||
expect(page).to have_link('topic1', href: explore_projects_path(topic: 'topic1'))
|
||||
end
|
||||
|
||||
it 'shows up to 3 project topics' do
|
||||
|
@ -141,10 +141,10 @@ RSpec.describe 'Project' do
|
|||
|
||||
visit path
|
||||
|
||||
expect(page).to have_css('.home-panel-topic-list')
|
||||
expect(page).to have_link('Topic1', href: explore_projects_path(topic: 'topic1'))
|
||||
expect(page).to have_link('Topic2', href: explore_projects_path(topic: 'topic2'))
|
||||
expect(page).to have_link('Topic3', href: explore_projects_path(topic: 'topic3'))
|
||||
expect(page).to have_selector('[data-testid="project_topic_list"]')
|
||||
expect(page).to have_link('topic1', href: explore_projects_path(topic: 'topic1'))
|
||||
expect(page).to have_link('topic2', href: explore_projects_path(topic: 'topic2'))
|
||||
expect(page).to have_link('topic3', href: explore_projects_path(topic: 'topic3'))
|
||||
expect(page).to have_content('+ 1 more')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { GlButton } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import LockButton from 'ee_component/repository/components/lock_button.vue';
|
||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||
import BlobButtonGroup from '~/repository/components/blob_button_group.vue';
|
||||
import DeleteBlobModal from '~/repository/components/delete_blob_modal.vue';
|
||||
|
@ -19,7 +18,6 @@ const DEFAULT_PROPS = {
|
|||
};
|
||||
|
||||
const DEFAULT_INJECT = {
|
||||
glFeatures: { fileLocks: true },
|
||||
targetBranch: 'master',
|
||||
originalBranch: 'master',
|
||||
};
|
||||
|
@ -49,7 +47,6 @@ describe('BlobButtonGroup component', () => {
|
|||
const findDeleteBlobModal = () => wrapper.findComponent(DeleteBlobModal);
|
||||
const findUploadBlobModal = () => wrapper.findComponent(UploadBlobModal);
|
||||
const findReplaceButton = () => wrapper.find('[data-testid="replace"]');
|
||||
const findLockButton = () => wrapper.findComponent(LockButton);
|
||||
|
||||
it('renders component', () => {
|
||||
createComponent();
|
||||
|
@ -67,18 +64,6 @@ describe('BlobButtonGroup component', () => {
|
|||
createComponent();
|
||||
});
|
||||
|
||||
it('renders the lock button', () => {
|
||||
expect(findLockButton().exists()).toBe(true);
|
||||
|
||||
expect(findLockButton().props()).toMatchObject({
|
||||
canLock: true,
|
||||
isLocked: false,
|
||||
name: 'some name',
|
||||
path: 'some/path',
|
||||
projectPath: 'some/project/path',
|
||||
});
|
||||
});
|
||||
|
||||
it('renders both the replace and delete button', () => {
|
||||
expect(wrapper.findAll(GlButton)).toHaveLength(2);
|
||||
});
|
||||
|
|
|
@ -3,8 +3,14 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
|
||||
let(:load_balancer) { Gitlab::Database::LoadBalancing::LoadBalancer.new([]) }
|
||||
let(:service) do
|
||||
described_class.new(nameserver: 'localhost', port: 8600, record: 'foo')
|
||||
described_class.new(
|
||||
nameserver: 'localhost',
|
||||
port: 8600,
|
||||
record: 'foo',
|
||||
load_balancer: load_balancer
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
|
@ -18,7 +24,15 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
|
|||
|
||||
describe '#initialize' do
|
||||
describe ':record_type' do
|
||||
subject { described_class.new(nameserver: 'localhost', port: 8600, record: 'foo', record_type: record_type) }
|
||||
subject do
|
||||
described_class.new(
|
||||
nameserver: 'localhost',
|
||||
port: 8600,
|
||||
record: 'foo',
|
||||
record_type: record_type,
|
||||
load_balancer: load_balancer
|
||||
)
|
||||
end
|
||||
|
||||
context 'with a supported type' do
|
||||
let(:record_type) { 'SRV' }
|
||||
|
@ -162,7 +176,16 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
|
|||
end
|
||||
|
||||
describe '#addresses_from_dns' do
|
||||
let(:service) { described_class.new(nameserver: 'localhost', port: 8600, record: 'foo', record_type: record_type) }
|
||||
let(:service) do
|
||||
described_class.new(
|
||||
nameserver: 'localhost',
|
||||
port: 8600,
|
||||
record: 'foo',
|
||||
record_type: record_type,
|
||||
load_balancer: load_balancer
|
||||
)
|
||||
end
|
||||
|
||||
let(:packet) { double(:packet, answer: [res1, res2]) }
|
||||
|
||||
before do
|
||||
|
@ -234,13 +257,11 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
|
|||
end
|
||||
|
||||
describe '#addresses_from_load_balancer' do
|
||||
let(:load_balancer) do
|
||||
Gitlab::Database::LoadBalancing::LoadBalancer.new(%w[b a])
|
||||
end
|
||||
|
||||
it 'returns the ordered host names of the load balancer' do
|
||||
load_balancer = Gitlab::Database::LoadBalancing::LoadBalancer.new(%w[b a])
|
||||
|
||||
allow(service)
|
||||
.to receive(:load_balancer)
|
||||
.and_return(load_balancer)
|
||||
|
||||
addresses = [
|
||||
described_class::Address.new('a'),
|
||||
described_class::Address.new('b')
|
||||
|
|
|
@ -982,9 +982,9 @@ RSpec.describe Event do
|
|||
build(:design_event, trait).action_name
|
||||
end
|
||||
|
||||
expect(created).to eq('uploaded')
|
||||
expect(updated).to eq('revised')
|
||||
expect(destroyed).to eq('deleted')
|
||||
expect(created).to eq('added')
|
||||
expect(updated).to eq('updated')
|
||||
expect(destroyed).to eq('removed')
|
||||
end
|
||||
|
||||
it 'handles correct push_action' do
|
||||
|
|
|
@ -12,7 +12,7 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
module Types
|
||||
class FakeType < BaseObject
|
||||
field :a_thing,
|
||||
^^^^^^^^^^^^^^^ Please add a `description` property.
|
||||
^^^^^^^^^^^^^^^ #{described_class::MSG_NO_DESCRIPTION}
|
||||
GraphQL::Types::String,
|
||||
null: false
|
||||
end
|
||||
|
@ -25,10 +25,38 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
module Types
|
||||
class FakeType < BaseObject
|
||||
field :a_thing,
|
||||
^^^^^^^^^^^^^^^ `description` strings must end with a `.`.
|
||||
^^^^^^^^^^^^^^^ #{described_class::MSG_NO_PERIOD}
|
||||
GraphQL::Types::String,
|
||||
null: false,
|
||||
description: 'A descriptive description'
|
||||
description: 'Description of a thing'
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
end
|
||||
|
||||
it 'adds an offense when description begins with "A"' do
|
||||
expect_offense(<<~TYPE)
|
||||
module Types
|
||||
class FakeType < BaseObject
|
||||
field :a_thing,
|
||||
^^^^^^^^^^^^^^^ #{described_class::MSG_BAD_START}
|
||||
GraphQL::Types::String,
|
||||
null: false,
|
||||
description: 'A description of the thing.'
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
end
|
||||
|
||||
it 'adds an offense when description begins with "The"' do
|
||||
expect_offense(<<~TYPE)
|
||||
module Types
|
||||
class FakeType < BaseObject
|
||||
field :a_thing,
|
||||
^^^^^^^^^^^^^^^ #{described_class::MSG_BAD_START}
|
||||
GraphQL::Types::String,
|
||||
null: false,
|
||||
description: 'The description of the thing.'
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
|
@ -41,7 +69,7 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
field :a_thing,
|
||||
GraphQL::Types::String,
|
||||
null: false,
|
||||
description: 'A descriptive description.'
|
||||
description: 'Description of a thing.'
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
|
@ -64,7 +92,7 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
module Types
|
||||
class FakeType < BaseObject
|
||||
argument :a_thing,
|
||||
^^^^^^^^^^^^^^^^^^ Please add a `description` property.
|
||||
^^^^^^^^^^^^^^^^^^ #{described_class::MSG_NO_DESCRIPTION}
|
||||
GraphQL::Types::String,
|
||||
null: false
|
||||
end
|
||||
|
@ -77,7 +105,7 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
module Types
|
||||
class FakeType < BaseObject
|
||||
argument :a_thing,
|
||||
^^^^^^^^^^^^^^^^^^ `description` strings must end with a `.`.
|
||||
^^^^^^^^^^^^^^^^^^ #{described_class::MSG_NO_PERIOD}
|
||||
GraphQL::Types::String,
|
||||
null: false,
|
||||
description: 'Behold! A description'
|
||||
|
@ -86,6 +114,34 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
TYPE
|
||||
end
|
||||
|
||||
it 'adds an offense when description begins with "A"' do
|
||||
expect_offense(<<~TYPE)
|
||||
module Types
|
||||
class FakeType < BaseObject
|
||||
argument :a_thing,
|
||||
^^^^^^^^^^^^^^^^^^ #{described_class::MSG_BAD_START}
|
||||
GraphQL::Types::String,
|
||||
null: false,
|
||||
description: 'A description.'
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
end
|
||||
|
||||
it 'adds an offense when description begins with "The"' do
|
||||
expect_offense(<<~TYPE)
|
||||
module Types
|
||||
class FakeType < BaseObject
|
||||
argument :a_thing,
|
||||
^^^^^^^^^^^^^^^^^^ #{described_class::MSG_BAD_START}
|
||||
GraphQL::Types::String,
|
||||
null: false,
|
||||
description: 'The description.'
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
end
|
||||
|
||||
it 'does not add an offense when description is correct' do
|
||||
expect_no_offenses(<<~TYPE.strip)
|
||||
module Types
|
||||
|
@ -106,7 +162,7 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
module Types
|
||||
class FakeEnum < BaseEnum
|
||||
value 'FOO', value: 'foo'
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^ Please add a `description` property.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^ #{described_class::MSG_NO_DESCRIPTION}
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
|
@ -117,7 +173,29 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
module Types
|
||||
class FakeEnum < BaseEnum
|
||||
value 'FOO', value: 'foo', description: 'bar'
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `description` strings must end with a `.`.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{described_class::MSG_NO_PERIOD}
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
end
|
||||
|
||||
it 'adds an offense when description begins with "The"' do
|
||||
expect_offense(<<~TYPE.strip)
|
||||
module Types
|
||||
class FakeEnum < BaseEnum
|
||||
value 'FOO', value: 'foo', description: 'The description.'
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{described_class::MSG_BAD_START}
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
end
|
||||
|
||||
it 'adds an offense when description begins with "A"' do
|
||||
expect_offense(<<~TYPE.strip)
|
||||
module Types
|
||||
class FakeEnum < BaseEnum
|
||||
value 'FOO', value: 'foo', description: 'A description.'
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{described_class::MSG_BAD_START}
|
||||
end
|
||||
end
|
||||
TYPE
|
||||
|
@ -150,7 +228,7 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
module Types
|
||||
class FakeType < BaseObject
|
||||
field :a_thing,
|
||||
^^^^^^^^^^^^^^^ `description` strings must end with a `.`.
|
||||
^^^^^^^^^^^^^^^ #{described_class::MSG_NO_PERIOD}
|
||||
GraphQL::Types::String,
|
||||
null: false,
|
||||
description: 'Behold! A description'
|
||||
|
@ -175,7 +253,7 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
|
|||
module Types
|
||||
class FakeType < BaseObject
|
||||
field :a_thing,
|
||||
^^^^^^^^^^^^^^^ `description` strings must end with a `.`.
|
||||
^^^^^^^^^^^^^^^ #{described_class::MSG_NO_PERIOD}
|
||||
GraphQL::Types::String,
|
||||
null: false,
|
||||
description: <<~DESC
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rake_helper'
|
||||
|
||||
RSpec.describe 'gitlab:product_intelligence:activate_metrics', :silence_stdout do
|
||||
def fake_metric(key_path, milestone: 'test_milestone', status: 'implemented')
|
||||
Gitlab::Usage::MetricDefinition.new(key_path, { key_path: key_path, milestone: milestone, status: status })
|
||||
end
|
||||
|
||||
before do
|
||||
Rake.application.rake_require 'tasks/gitlab/product_intelligence'
|
||||
stub_warn_user_is_not_gitlab
|
||||
end
|
||||
|
||||
describe 'activate_metrics' do
|
||||
it 'fails if the MILESTONE env var is not set' do
|
||||
stub_env('MILESTONE' => nil)
|
||||
|
||||
expect { run_rake_task('gitlab:product_intelligence:activate_metrics') }.to raise_error(RuntimeError, 'Please supply the MILESTONE env var')
|
||||
end
|
||||
|
||||
context 'with MILESTONE env var' do
|
||||
subject do
|
||||
updated_metrics = []
|
||||
|
||||
file = double('file')
|
||||
allow(file).to receive(:<<) { |contents| updated_metrics << YAML.safe_load(contents) }
|
||||
allow(File).to receive(:open).and_yield(file)
|
||||
|
||||
stub_env('MILESTONE' => 'test_milestone')
|
||||
run_rake_task('gitlab:product_intelligence:activate_metrics')
|
||||
|
||||
updated_metrics
|
||||
end
|
||||
|
||||
let(:metric_definitions) do
|
||||
{
|
||||
matching_metric: fake_metric('matching_metric'),
|
||||
matching_metric2: fake_metric('matching_metric2'),
|
||||
other_status_metric: fake_metric('other_status_metric', status: 'deprecated'),
|
||||
other_milestone_metric: fake_metric('other_milestone_metric', milestone: 'other_milestone')
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Gitlab::Usage::MetricDefinition).to receive(:definitions).and_return(metric_definitions)
|
||||
end
|
||||
|
||||
context 'with metric matching status and milestone' do
|
||||
it 'updates matching_metric yaml file' do
|
||||
expect(subject).to eq([
|
||||
{ 'key_path' => 'matching_metric', 'milestone' => 'test_milestone', 'status' => 'data_available' },
|
||||
{ 'key_path' => 'matching_metric2', 'milestone' => 'test_milestone', 'status' => 'data_available' }
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
context 'without metrics definitions' do
|
||||
let(:metric_definitions) { {} }
|
||||
|
||||
it 'runs successfully with no updates' do
|
||||
expect(subject).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
context 'without matching metrics' do
|
||||
let(:metric_definitions) do
|
||||
{
|
||||
other_status_metric: fake_metric('other_status_metric', status: 'deprecated'),
|
||||
other_milestone_metric: fake_metric('other_milestone_metric', milestone: 'other_milestone')
|
||||
}
|
||||
end
|
||||
|
||||
it 'runs successfully with no updates' do
|
||||
expect(subject).to eq([])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue