diff options
28 files changed, 370 insertions, 52 deletions
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index 2c51252be39..f6f119d4463 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -8,6 +8,7 @@ import { GlDropdownItem, GlFormGroup, GlModal, + GlSearchBoxByType, GlModalDirective, GlTooltipDirective, } from '@gitlab/ui'; @@ -15,6 +16,7 @@ import PanelType from 'ee_else_ce/monitoring/components/panel_type.vue'; import { s__ } from '~/locale'; import createFlash from '~/flash'; import Icon from '~/vue_shared/components/icon.vue'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { getParameterValues, mergeUrlParams, redirectTo } from '~/lib/utils/url_utility'; import invalidUrl from '~/lib/utils/invalid_url'; @@ -38,6 +40,7 @@ export default { GlButton, GlDropdown, GlDropdownItem, + GlSearchBoxByType, GlFormGroup, GlModal, @@ -52,6 +55,7 @@ export default { GlTooltip: GlTooltipDirective, TrackEvent: TrackEventDirective, }, + mixins: [glFeatureFlagsMixin()], props: { externalDashboardUrl: { type: String, @@ -198,13 +202,12 @@ export default { 'dashboard', 'emptyState', 'showEmptyState', - 'environments', 'deploymentData', 'useDashboardEndpoint', 'allDashboards', 'additionalPanelTypesEnabled', ]), - ...mapGetters('monitoringDashboard', ['getMetricStates']), + ...mapGetters('monitoringDashboard', ['getMetricStates', 'filteredEnvironments']), firstDashboard() { return this.environmentsEndpoint.length > 0 && this.allDashboards.length > 0 ? this.allDashboards[0] @@ -227,6 +230,9 @@ export default { this.externalDashboardUrl.length ); }, + shouldRenderSearchableEnvironmentsDropdown() { + return this.glFeatures.searchableEnvironmentsDropdown; + }, }, created() { this.setEndpoints({ @@ -255,6 +261,7 @@ export default { 'setGettingStartedEmptyState', 'setEndpoints', 'setPanelGroupMetrics', + 'setEnvironmentsSearchTerm', ]), updatePanels(key, panels) { this.setPanelGroupMetrics({ @@ -296,6 +303,9 @@ export default { setFormValidity(isValid) { this.formIsValid = isValid; }, + debouncedEnvironmentsSearch: _.debounce(function environmentsSearchOnInput(searchTerm) { + this.setEnvironmentsSearchTerm(searchTerm); + }, 500), submitCustomMetricsForm() { this.$refs.customMetricsForm.submit(); }, @@ -374,17 +384,36 @@ export default { data-qa-selector="environments_dropdown" class="mb-0 d-flex" toggle-class="dropdown-menu-toggle" + menu-class="monitor-environment-dropdown-menu" :text="currentEnvironmentName" - :disabled="environments.length === 0" + :disabled="filteredEnvironments.length === 0" > - <gl-dropdown-item - v-for="environment in environments" - :key="environment.id" - :active="environment.name === currentEnvironmentName" - active-class="is-active" - :href="environment.metrics_path" - >{{ environment.name }}</gl-dropdown-item - > + <div class="d-flex flex-column overflow-hidden"> + <gl-search-box-by-type + v-if="shouldRenderSearchableEnvironmentsDropdown" + ref="monitorEnvironmentsDropdownSearch" + class="m-2" + @input="debouncedEnvironmentsSearch" + /> + <div class="flex-fill overflow-auto"> + <gl-dropdown-item + v-for="environment in filteredEnvironments" + :key="environment.id" + :active="environment.name === currentEnvironmentName" + active-class="is-active" + :href="environment.metrics_path" + >{{ environment.name }}</gl-dropdown-item + > + </div> + <div + v-if="shouldRenderSearchableEnvironmentsDropdown" + v-show="filteredEnvironments.length === 0" + ref="monitorEnvironmentsDropdownMsg" + class="text-secondary no-matches-message" + > + {{ s__('No matching results') }} + </div> + </div> </gl-dropdown> </gl-form-group> @@ -415,18 +444,16 @@ export default { variant="default" class="mr-2 mt-1 js-rearrange-button" @click="toggleRearrangingPanels" + >{{ __('Arrange charts') }}</gl-button > - {{ __('Arrange charts') }} - </gl-button> <gl-button v-if="addingMetricsAvailable" ref="addMetricBtn" v-gl-modal="$options.addMetric.modalId" variant="outline-success" class="mr-2 mt-1" + >{{ $options.addMetric.title }}</gl-button > - {{ $options.addMetric.title }} - </gl-button> <gl-modal v-if="addingMetricsAvailable" ref="addMetricModal" @@ -448,9 +475,8 @@ export default { :disabled="!formIsValid" variant="success" @click="submitCustomMetricsForm" + >{{ __('Save changes') }}</gl-button > - {{ __('Save changes') }} - </gl-button> </div> </gl-modal> @@ -458,9 +484,8 @@ export default { v-if="selectedDashboard.can_edit" class="mt-1 js-edit-link" :href="selectedDashboard.project_blob_path" + >{{ __('Edit dashboard') }}</gl-button > - {{ __('Edit dashboard') }} - </gl-button> <gl-button v-if="externalDashboardUrl.length" @@ -506,9 +531,9 @@ export default { class="draggable-remove js-draggable-remove p-2 w-100 position-absolute d-flex justify-content-end" @click="removePanel(groupData.key, groupData.panels, graphIndex)" > - <a class="mx-2 p-2 draggable-remove-link" :aria-label="__('Remove')" - ><icon name="close" - /></a> + <a class="mx-2 p-2 draggable-remove-link" :aria-label="__('Remove')"> + <icon name="close" /> + </a> </div> <panel-type diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js index 61cd8621902..6303ed2b82f 100644 --- a/app/assets/javascripts/monitoring/stores/actions.js +++ b/app/assets/javascripts/monitoring/stores/actions.js @@ -30,6 +30,10 @@ export const setEndpoints = ({ commit }, endpoints) => { commit(types.SET_ENDPOINTS, endpoints); }; +export const setEnvironmentsSearchTerm = ({ commit }, searchTerm) => { + commit(types.SET_ENVIRONMENTS_SEARCH_TERM, searchTerm); +}; + export const setShowErrorBanner = ({ commit }, enabled) => { commit(types.SET_SHOW_ERROR_BANNER, enabled); }; diff --git a/app/assets/javascripts/monitoring/stores/getters.js b/app/assets/javascripts/monitoring/stores/getters.js index a13157c6f87..ed1e3e3ffec 100644 --- a/app/assets/javascripts/monitoring/stores/getters.js +++ b/app/assets/javascripts/monitoring/stores/getters.js @@ -58,5 +58,20 @@ export const metricsWithData = state => groupKey => { return res; }; +/** + * Filter environments by names. + * + * This is used in the environments dropdown with searchable input. + * Also, this searchable dropdown is behind `searchable_environments_dropdown` + * feature flag + * + * @param {Object} state + * @returns {Array} List of environments + */ +export const filteredEnvironments = state => + state.environments.filter(env => + env.name.toLowerCase().includes((state.environmentsSearchTerm || '').trim().toLowerCase()), + ); + // prevent babel-plugin-rewire from generating an invalid default during karma tests export default () => {}; diff --git a/app/assets/javascripts/monitoring/stores/mutation_types.js b/app/assets/javascripts/monitoring/stores/mutation_types.js index 74068e1d846..73d402ac6df 100644 --- a/app/assets/javascripts/monitoring/stores/mutation_types.js +++ b/app/assets/javascripts/monitoring/stores/mutation_types.js @@ -21,3 +21,5 @@ export const SET_GETTING_STARTED_EMPTY_STATE = 'SET_GETTING_STARTED_EMPTY_STATE' export const SET_NO_DATA_EMPTY_STATE = 'SET_NO_DATA_EMPTY_STATE'; export const SET_SHOW_ERROR_BANNER = 'SET_SHOW_ERROR_BANNER'; export const SET_PANEL_GROUP_METRICS = 'SET_PANEL_GROUP_METRICS'; + +export const SET_ENVIRONMENTS_SEARCH_TERM = 'SET_ENVIRONMENTS_SEARCH_TERM'; diff --git a/app/assets/javascripts/monitoring/stores/mutations.js b/app/assets/javascripts/monitoring/stores/mutations.js index 506a30ae619..e14425d7c6c 100644 --- a/app/assets/javascripts/monitoring/stores/mutations.js +++ b/app/assets/javascripts/monitoring/stores/mutations.js @@ -196,4 +196,7 @@ export default { const panelGroup = state.dashboard.panel_groups.find(pg => payload.key === pg.key); panelGroup.panels = payload.panels; }, + [types.SET_ENVIRONMENTS_SEARCH_TERM](state, searchTerm) { + state.environmentsSearchTerm = searchTerm; + }, }; diff --git a/app/assets/javascripts/monitoring/stores/state.js b/app/assets/javascripts/monitoring/stores/state.js index ee8a85ea222..2c6758dfce2 100644 --- a/app/assets/javascripts/monitoring/stores/state.js +++ b/app/assets/javascripts/monitoring/stores/state.js @@ -15,6 +15,7 @@ export default () => ({ deploymentData: [], environments: [], + environmentsSearchTerm: '', allDashboards: [], currentDashboard: null, projectPath: null, diff --git a/app/assets/stylesheets/pages/experimental_separate_sign_up.scss b/app/assets/stylesheets/pages/experimental_separate_sign_up.scss index 5a80ea79600..aeeb8b7384d 100644 --- a/app/assets/stylesheets/pages/experimental_separate_sign_up.scss +++ b/app/assets/stylesheets/pages/experimental_separate_sign_up.scss @@ -12,6 +12,7 @@ max-width: 900px; &.navless-container { + padding: 35px $gl-padding; // overriding .devise-layout-html.navless-container to support the sticky footer // without having a header on size xs @include media-breakpoint-down(xs) { @@ -24,6 +25,7 @@ .signup-heading h2 { font-weight: $gl-font-weight-bold; padding: 0 $gl-padding; + font-size: $gl-font-size-28; @include media-breakpoint-down(md) { font-size: $gl-font-size-large; @@ -49,4 +51,35 @@ color: $red-700; } } + + .omniauth-divider { + &::before, + &::after { + content: ''; + flex: 1; + border-bottom: 1px solid $gray-dark; + margin: $gl-padding-24 0; + } + + &::before { + margin-right: $gl-padding; + } + + &::after { + margin-left: $gl-padding; + } + } + + .omniauth-btn { + width: 48%; + + @include media-breakpoint-down(md) { + width: 100%; + } + + img { + width: $default-icon-size; + height: $default-icon-size; + } + } } diff --git a/app/assets/stylesheets/pages/prometheus.scss b/app/assets/stylesheets/pages/prometheus.scss index e20e58e21cf..e759423f6e5 100644 --- a/app/assets/stylesheets/pages/prometheus.scss +++ b/app/assets/stylesheets/pages/prometheus.scss @@ -58,6 +58,18 @@ .custom-time-range-form-group > label { padding-bottom: $gl-padding; } + + .monitor-environment-dropdown-menu { + &.show { + display: flex; + flex-direction: column; + overflow: hidden; + } + + .no-matches-message { + padding: $gl-padding-8 $gl-padding-12; + } + } } .prometheus-panel { diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 70c4b536854..b4b2bf01831 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -14,6 +14,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController before_action :expire_etag_cache, only: [:index], unless: -> { request.format.json? } before_action only: [:metrics, :additional_metrics, :metrics_dashboard] do push_frontend_feature_flag(:prometheus_computed_alerts) + push_frontend_feature_flag(:searchable_environments_dropdown) end before_action do push_frontend_feature_flag(:auto_stop_environments) diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb index a9c4cfe7dcc..e8d3d5f62cb 100644 --- a/app/helpers/auth_helper.rb +++ b/app/helpers/auth_helper.rb @@ -89,7 +89,17 @@ module AuthHelper def enabled_button_based_providers disabled_providers = Gitlab::CurrentSettings.disabled_oauth_sign_in_sources || [] - button_based_providers.map(&:to_s) - disabled_providers + providers = button_based_providers.map(&:to_s) - disabled_providers + providers.sort_by do |provider| + case provider + when 'google_oauth2' + 0 + when 'github' + 1 + else + 2 + end + end end def button_based_providers_enabled? diff --git a/app/models/user.rb b/app/models/user.rb index be9f528e1bd..e86c0a1826d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -394,6 +394,11 @@ class User < ApplicationRecord Gitlab::CurrentSettings.minimum_password_length..Devise.password_length.max end + # Generate a random password that conforms to the current password length settings + def random_password + Devise.friendly_token(password_length.max) + end + # Devise method overridden to allow sign in with email or username def find_for_database_authentication(warden_conditions) conditions = warden_conditions.dup diff --git a/app/services/metrics/dashboard/base_service.rb b/app/services/metrics/dashboard/base_service.rb index c51c88d776a..40c015dff9c 100644 --- a/app/services/metrics/dashboard/base_service.rb +++ b/app/services/metrics/dashboard/base_service.rb @@ -38,13 +38,9 @@ module Metrics # Determines whether users should be able to view # dashboards at all. def allowed? - if params[:environment] - Ability.allowed?(current_user, :read_environment, project) - elsif params[:cluster] - true # Authorization handled at controller level - else - false - end + return false unless params[:environment] + + Ability.allowed?(current_user, :read_environment, project) end # Returns a new dashboard Hash, supplemented with DB info diff --git a/app/services/users/build_service.rb b/app/services/users/build_service.rb index d18f20bc1db..56631bf2785 100644 --- a/app/services/users/build_service.rb +++ b/app/services/users/build_service.rb @@ -23,7 +23,7 @@ module Users @reset_token = user.generate_reset_token if params[:reset_password] if user_params[:force_random_password] - random_password = Devise.friendly_token.first(User.password_length.min) + random_password = User.random_password user.password = user.password_confirmation = random_password end end diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml index 4832861445b..7de7dec61b0 100644 --- a/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml +++ b/app/views/devise/shared/_experimental_separate_sign_up_flow_box.html.haml @@ -41,3 +41,5 @@ = recaptcha_tags .submit-container.mt-3 = f.submit _("Register"), class: "btn-register btn btn-block btn-success mb-0 p-2", data: { qa_selector: 'new_user_register_button' } + - if omniauth_enabled? && button_based_providers_enabled? + = render 'devise/shared/experimental_separate_sign_up_flow_omniauth_box' diff --git a/app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml b/app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml new file mode 100644 index 00000000000..d9143d90430 --- /dev/null +++ b/app/views/devise/shared/_experimental_separate_sign_up_flow_omniauth_box.haml @@ -0,0 +1,13 @@ +.omniauth-divider.d-flex.align-items-center.text-center + = _("or") +%label.label-bold.d-block + = _("Create an account using:") +- providers = enabled_button_based_providers +.d-flex.justify-content-between.flex-wrap + - providers.each do |provider| + - has_icon = provider_has_icon?(provider) + = link_to omniauth_authorize_path(:user, provider), method: :post, class: "btn d-flex align-items-center omniauth-btn text-left oauth-login mb-2 p-2 #{qa_class_for_provider(provider)}", id: "oauth-login-#{provider}" do + - if has_icon + = provider_image_tag(provider) + %span.ml-2 + = label_for_provider(provider) diff --git a/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml index 2f05717fc0e..3a5c5399355 100644 --- a/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml +++ b/app/views/layouts/devise_experimental_separate_sign_up_flow.html.haml @@ -9,10 +9,10 @@ = render "layouts/broadcast" .content = render "layouts/flash" - .row.mb-3 + .row.mb-6 .col-sm-8.offset-sm-2.col-md-6.offset-md-3.new-session-forms-container = render_if_exists 'layouts/devise_help_text' - .text-center.signup-heading.mt-3.mb-3 + .text-center.signup-heading.mb-3 = image_tag(image_url('logo.svg'), class: 'gitlab-logo', alt: 'GitLab Logo') - if content_for?(:page_title) %h2= yield :page_title diff --git a/changelogs/unreleased/197925-setting-minimum-password-length-breaks-sign-up-with-saml.yml b/changelogs/unreleased/197925-setting-minimum-password-length-breaks-sign-up-with-saml.yml new file mode 100644 index 00000000000..0530fd88749 --- /dev/null +++ b/changelogs/unreleased/197925-setting-minimum-password-length-breaks-sign-up-with-saml.yml @@ -0,0 +1,5 @@ +--- +title: Fixes random passwords generated not conforming to minimum_password_length setting +merge_request: 23387 +author: +type: fixed diff --git a/changelogs/unreleased/reorder-signup-omniauth-options.yml b/changelogs/unreleased/reorder-signup-omniauth-options.yml new file mode 100644 index 00000000000..46f9a2dcdb6 --- /dev/null +++ b/changelogs/unreleased/reorder-signup-omniauth-options.yml @@ -0,0 +1,5 @@ +--- +title: Reorder signup omniauth options +merge_request: 23082 +author: +type: changed diff --git a/lib/gitlab/auth/o_auth/auth_hash.rb b/lib/gitlab/auth/o_auth/auth_hash.rb index 76f2827af1a..b37a9225dd7 100644 --- a/lib/gitlab/auth/o_auth/auth_hash.rb +++ b/lib/gitlab/auth/o_auth/auth_hash.rb @@ -34,7 +34,7 @@ module Gitlab end def password - @password ||= Gitlab::Utils.force_utf8(Devise.friendly_token[0, 8].downcase) + @password ||= Gitlab::Utils.force_utf8(::User.random_password.downcase) end def location diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 1d3a7e2a958..aad7e54b9db 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -5361,6 +5361,9 @@ msgstr "" msgid "Create a personal access token on your account to pull or push via %{protocol}." msgstr "" +msgid "Create an account using:" +msgstr "" + msgid "Create an issue" msgstr "" @@ -22721,6 +22724,9 @@ msgstr "" msgid "opened %{timeAgo}" msgstr "" +msgid "or" +msgstr "" + msgid "out of %d total test" msgid_plural "out of %d total tests" msgstr[0] "" diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js index 007429a3d02..195abae3783 100644 --- a/spec/frontend/monitoring/components/dashboard_spec.js +++ b/spec/frontend/monitoring/components/dashboard_spec.js @@ -28,6 +28,15 @@ describe('Dashboard', () => { let wrapper; let mock; + const findEnvironmentsDropdown = () => wrapper.find({ ref: 'monitorEnvironmentsDropdown' }); + const findAllEnvironmentsDropdownItems = () => findEnvironmentsDropdown().findAll(GlDropdownItem); + const setSearchTerm = searchTerm => { + wrapper.vm.$store.commit( + `monitoringDashboard/${types.SET_ENVIRONMENTS_SEARCH_TERM}`, + searchTerm, + ); + }; + const createShallowWrapper = (props = {}, options = {}) => { wrapper = shallowMount(Dashboard, { localVue, @@ -52,9 +61,6 @@ describe('Dashboard', () => { }); }; - const findEnvironmentsDropdown = () => wrapper.find({ ref: 'monitorEnvironmentsDropdown' }); - const findAllEnvironmentsDropdownItems = () => findEnvironmentsDropdown().findAll(GlDropdownItem); - beforeEach(() => { store = createStore(); mock = new MockAdapter(axios); @@ -155,12 +161,9 @@ describe('Dashboard', () => { wrapper.vm .$nextTick() .then(() => { - const environmentDropdownItems = findAllEnvironmentsDropdownItems(); + expect(findAllEnvironmentsDropdownItems().length).toEqual(environmentData.length); - expect(wrapper.vm.environments.length).toEqual(environmentData.length); - expect(environmentDropdownItems.length).toEqual(wrapper.vm.environments.length); - - environmentDropdownItems.wrappers.forEach((itemWrapper, index) => { + findAllEnvironmentsDropdownItems().wrappers.forEach((itemWrapper, index) => { const anchorEl = itemWrapper.find('a'); if (anchorEl.exists() && environmentData[index].metrics_path) { const href = anchorEl.attributes('href'); @@ -248,6 +251,70 @@ describe('Dashboard', () => { }); }); + describe('searchable environments dropdown', () => { + beforeEach(() => { + createMountedWrapper( + { hasMetrics: true }, + { + attachToDocument: true, + stubs: ['graph-group', 'panel-type'], + provide: { + glFeatures: { searchableEnvironmentsDropdown: true }, + }, + }, + ); + + setupComponentStore(wrapper); + + return wrapper.vm.$nextTick(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders a search input', () => { + expect(wrapper.find({ ref: 'monitorEnvironmentsDropdownSearch' }).exists()).toBe(true); + }); + + it('renders dropdown items', () => { + findAllEnvironmentsDropdownItems().wrappers.forEach((itemWrapper, index) => { + const anchorEl = itemWrapper.find('a'); + if (anchorEl.exists()) { + expect(anchorEl.text()).toBe(environmentData[index].name); + } + }); + }); + + it('filters rendered dropdown items', () => { + const searchTerm = 'production'; + const resultEnvs = environmentData.filter(({ name }) => name.indexOf(searchTerm) !== -1); + setSearchTerm(searchTerm); + + return wrapper.vm.$nextTick(() => { + expect(findAllEnvironmentsDropdownItems().length).toEqual(resultEnvs.length); + }); + }); + + it('does not filter dropdown items if search term is empty string', () => { + const searchTerm = ''; + setSearchTerm(searchTerm); + + return wrapper.vm.$nextTick(() => { + expect(findAllEnvironmentsDropdownItems().length).toEqual(environmentData.length); + }); + }); + + it("shows error message if search term doesn't match", () => { + const searchTerm = 'does-not-exist'; + setSearchTerm(searchTerm); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.find({ ref: 'monitorEnvironmentsDropdownMsg' }).isVisible()).toBe(true); + }); + }); + }); + describe('drag and drop function', () => { const findDraggables = () => wrapper.findAll(VueDraggable); const findEnabledDraggables = () => findDraggables().filter(f => !f.attributes('disabled')); diff --git a/spec/frontend/monitoring/mock_data.js b/spec/frontend/monitoring/mock_data.js index 094554f525c..ada3e44f0a4 100644 --- a/spec/frontend/monitoring/mock_data.js +++ b/spec/frontend/monitoring/mock_data.js @@ -331,6 +331,14 @@ export const mockedQueryResultPayloadCoresTotal = { ], }; +const extraEnvironmentData = new Array(15).fill(null).map((_, idx) => ({ + id: 136 + idx, + name: `no-deployment/noop-branch-${idx}`, + state: 'available', + created_at: '2018-07-04T18:39:41.702Z', + updated_at: '2018-07-04T18:44:54.010Z', +})); + export const environmentData = [ { id: 34, @@ -368,14 +376,7 @@ export const environmentData = [ id: 128, }, }, - { - id: 36, - name: 'no-deployment/noop-branch', - state: 'available', - created_at: '2018-07-04T18:39:41.702Z', - updated_at: '2018-07-04T18:44:54.010Z', - }, -]; +].concat(extraEnvironmentData); export const metricsDashboardResponse = { dashboard: { diff --git a/spec/frontend/monitoring/store/getters_spec.js b/spec/frontend/monitoring/store/getters_spec.js index 097a5ca7f7c..263050b462f 100644 --- a/spec/frontend/monitoring/store/getters_spec.js +++ b/spec/frontend/monitoring/store/getters_spec.js @@ -3,6 +3,7 @@ import mutations from '~/monitoring/stores/mutations'; import * as types from '~/monitoring/stores/mutation_types'; import { metricStates } from '~/monitoring/constants'; import { + environmentData, metricsDashboardPayload, mockedEmptyResult, mockedQueryResultPayload, @@ -214,4 +215,58 @@ describe('Monitoring store Getters', () => { }); }); }); + + describe('filteredEnvironments', () => { + let state; + const setupState = (initState = {}) => { + state = { + ...state, + ...initState, + }; + }; + + beforeAll(() => { + setupState({ + environments: environmentData, + }); + }); + + afterAll(() => { + state = null; + }); + + [ + { + input: '', + output: 17, + }, + { + input: ' ', + output: 17, + }, + { + input: null, + output: 17, + }, + { + input: 'does-not-exist', + output: 0, + }, + { + input: 'noop-branch-', + output: 15, + }, + { + input: 'noop-branch-9', + output: 1, + }, + ].forEach(({ input, output }) => { + it(`filteredEnvironments returns ${output} items for ${input}`, () => { + setupState({ + environmentsSearchTerm: input, + }); + expect(getters.filteredEnvironments(state).length).toBe(output); + }); + }); + }); }); diff --git a/spec/helpers/auth_helper_spec.rb b/spec/helpers/auth_helper_spec.rb index cb7c670198d..9179019cd6a 100644 --- a/spec/helpers/auth_helper_spec.rb +++ b/spec/helpers/auth_helper_spec.rb @@ -73,12 +73,17 @@ describe AuthHelper do describe 'enabled_button_based_providers' do before do - allow(helper).to receive(:auth_providers) { [:twitter, :github] } + allow(helper).to receive(:auth_providers) { [:twitter, :github, :google_oauth2] } end context 'all providers are enabled to sign in' do it 'returns all the enabled providers from settings' do - expect(helper.enabled_button_based_providers).to include('twitter', 'github') + expect(helper.enabled_button_based_providers).to include('twitter', 'github', 'google_oauth2') + end + + it 'puts google and github in the beginning' do + expect(helper.enabled_button_based_providers.first).to eq('google_oauth2') + expect(helper.enabled_button_based_providers.second).to eq('github') end end diff --git a/spec/lib/gitlab/auth/ldap/user_spec.rb b/spec/lib/gitlab/auth/ldap/user_spec.rb index bc09de7b525..071d687b2bf 100644 --- a/spec/lib/gitlab/auth/ldap/user_spec.rb +++ b/spec/lib/gitlab/auth/ldap/user_spec.rb @@ -139,6 +139,18 @@ describe Gitlab::Auth::LDAP::User do expect(gl_user).to be_confirmed end end + + context 'when the current minimum password length is different from the default minimum password length' do + before do + stub_application_setting minimum_password_length: 21 + end + + it 'creates the user' do + ldap_user.save + + expect(gl_user).to be_persisted + end + end end describe 'updating email' do diff --git a/spec/lib/gitlab/auth/o_auth/user_spec.rb b/spec/lib/gitlab/auth/o_auth/user_spec.rb index c621c0aa935..022a544395e 100644 --- a/spec/lib/gitlab/auth/o_auth/user_spec.rb +++ b/spec/lib/gitlab/auth/o_auth/user_spec.rb @@ -86,6 +86,20 @@ describe Gitlab::Auth::OAuth::User do end end + context 'when the current minimum password length is different from the default minimum password length' do + before do + stub_application_setting minimum_password_length: 21 + end + + it 'creates the user' do + stub_omniauth_config(allow_single_sign_on: [provider]) + + oauth_user.save + + expect(gl_user).to be_persisted + end + end + it 'marks user as having password_automatically_set' do stub_omniauth_config(allow_single_sign_on: [provider], external_providers: [provider]) diff --git a/spec/lib/gitlab/auth/saml/user_spec.rb b/spec/lib/gitlab/auth/saml/user_spec.rb index 5546438b7ee..4c400636ddf 100644 --- a/spec/lib/gitlab/auth/saml/user_spec.rb +++ b/spec/lib/gitlab/auth/saml/user_spec.rb @@ -325,6 +325,18 @@ describe Gitlab::Auth::Saml::User do expect(gl_user).to be_confirmed end end + + context 'when the current minimum password length is different from the default minimum password length' do + before do + stub_application_setting minimum_password_length: 21 + end + + it 'creates the user' do + saml_user.save + + expect(gl_user).to be_persisted + end + end end describe 'blocking' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 5620f211d9c..6f393d169a2 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -508,6 +508,20 @@ describe User, :do_not_mock_admin_mode do end end + describe '.random_password' do + let(:random_password) { described_class.random_password } + + before do + expect(User).to receive(:password_length).and_return(88..128) + end + + context 'length' do + it 'conforms to the current password length settings' do + expect(random_password.length).to eq(128) + end + end + end + describe '.password_length' do let(:password_length) { described_class.password_length } |