diff --git a/.gitpod.yml b/.gitpod.yml index 0cb0e55c373..7642cfce294 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -63,8 +63,10 @@ tasks: ) ports: - - port: 3000 # rails-web + - port: 2222 # sshd onOpen: ignore + - port: 3000 # rails-web + onOpen: notify - port: 3010 # gitlab-pages onOpen: ignore - port: 3808 # webpack diff --git a/app/assets/javascripts/reports/codequality_report/store/actions.js b/app/assets/javascripts/reports/codequality_report/store/actions.js index e3238207af2..33005ec0e9e 100644 --- a/app/assets/javascripts/reports/codequality_report/store/actions.js +++ b/app/assets/javascripts/reports/codequality_report/store/actions.js @@ -1,4 +1,4 @@ -import axios from '~/lib/utils/axios_utils'; +import pollUntilComplete from '~/lib/utils/poll_until_complete'; import * as types from './mutation_types'; import { parseCodeclimateMetrics } from './utils/codequality_parser'; @@ -10,8 +10,7 @@ export const fetchReports = ({ state, dispatch, commit }) => { if (!state.basePath) { return dispatch('receiveReportsError'); } - return axios - .get(state.reportsPath) + return pollUntilComplete(state.reportsPath) .then(({ data }) => { return dispatch('receiveReportsSuccess', { newIssues: parseCodeclimateMetrics(data.new_errors, state.headBlobPath), diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index 0328fa5c282..cb68d31c06f 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -77,12 +77,10 @@ .row.user-time-preferences.js-search-settings-section .col-lg-4.profile-settings-sidebar %h4.gl-mt-0= s_("Profiles|Time settings") - %p= s_("Profiles|You can set your current timezone here") + %p= s_("Profiles|Set your local time zone") .col-lg-8 - -# TODO: might need an entry in user/profile.md to describe some of these settings - -# https://gitlab.com/gitlab-org/gitlab-foss/issues/60070 %h5= _("Time zone") - = dropdown_tag(_("Select a timezone"), options: { toggle_class: 'gl-button btn js-timezone-dropdown input-lg', title: _("Select a timezone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } ) + = dropdown_tag(_("Select a time zone"), options: { toggle_class: 'gl-button btn js-timezone-dropdown input-lg', title: _("Select a time zone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } ) %input.hidden{ :type => 'hidden', :id => 'user_timezone', :name => 'user[timezone]', value: @user.timezone } .col-lg-12 %hr diff --git a/doc/.vale/gitlab/SubstitutionWarning.yml b/doc/.vale/gitlab/SubstitutionWarning.yml index 50ac97bc227..3bedc5837cf 100644 --- a/doc/.vale/gitlab/SubstitutionWarning.yml +++ b/doc/.vale/gitlab/SubstitutionWarning.yml @@ -18,6 +18,7 @@ swap: filesystem: file system info: information repo: repository + timezone: time zone utilize: use administrator access: the Administrator role administrator permission: the Administrator role diff --git a/doc/administration/img/time_zone_settings.png b/doc/administration/img/time_zone_settings.png deleted file mode 100644 index e735a8bc5ec..00000000000 Binary files a/doc/administration/img/time_zone_settings.png and /dev/null differ diff --git a/doc/administration/timezone.md b/doc/administration/timezone.md index 0006a442ec9..b6076c8ed26 100644 --- a/doc/administration/timezone.md +++ b/doc/administration/timezone.md @@ -48,13 +48,8 @@ gitlab-ctl restart > - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/29669) in GitLab 13.9. > - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/29669) in GitLab 14.1. -This setting controls the local time displayed on a user's profile. -See [&280](https://gitlab.com/groups/gitlab-org/-/epics/280) for other planned features. +A user can set their time zone in their profile. If a user has not set their time zone, it defaults +to the time zone [configured at the instance level](#changing-your-time-zone). On GitLab.com, the +default time zone is UTC. -NOTE: -If a user has not set their time zone, it defaults to the time zone [configured at the instance level](#changing-your-time-zone). On GitLab.com, the default time zone is UTC. - -1. Navigate to [your user settings](../user/profile/index.md#access-your-user-settings). -1. Select your time zone from the dropdown. - -![User Time Zone Settings](img/time_zone_settings.png) +For more information, see [Set your time zone](../user/profile/index.md#set-your-time-zone). diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md index 28061d3a676..29b81e14e00 100644 --- a/doc/user/profile/index.md +++ b/doc/user/profile/index.md @@ -192,6 +192,14 @@ To set the busy status indicator, either: | --- | --- | | ![Busy status - notes](img/busy_indicator_notes_v13_9.png) | ![Busy status - note header](img/busy_indicator_note_header_v13_9.png) | +## Set your time zone + +To set your time zone: + +1. In the top-right corner, select your avatar. +1. Select **Edit profile**. +1. In the **Time settings** section, select your time zone from the dropdown list. + ## Change the email displayed on your commits A commit email is an email address displayed in every Git-related action carried out through the GitLab interface. diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 22e6e93d553..34861588c4a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -25410,6 +25410,9 @@ msgstr "" msgid "Profiles|Set new profile picture" msgstr "" +msgid "Profiles|Set your local time zone" +msgstr "" + msgid "Profiles|Social sign-in" msgstr "" @@ -25491,9 +25494,6 @@ msgstr "" msgid "Profiles|You can change your avatar here or remove the current avatar to revert to %{gravatar_link}" msgstr "" -msgid "Profiles|You can set your current timezone here" -msgstr "" - msgid "Profiles|You can upload your avatar here" msgstr "" @@ -29742,6 +29742,9 @@ msgstr "" msgid "Select a template type" msgstr "" +msgid "Select a time zone" +msgstr "" + msgid "Select a timezone" msgstr "" diff --git a/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb b/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb index 7c080504c31..19b6b597a84 100644 --- a/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb +++ b/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb @@ -40,7 +40,7 @@ RSpec.describe Projects::ErrorTracking::StackTracesController do context 'service result is successful' do let(:service_response) { { status: :success, latest_event: error_event } } - let(:error_event) { build(:error_tracking_error_event) } + let(:error_event) { build(:error_tracking_sentry_error_event) } it 'responds with success' do expect(response).to have_gitlab_http_status(:ok) diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb index 5ea885e4fd6..822778779eb 100644 --- a/spec/controllers/projects/error_tracking_controller_spec.rb +++ b/spec/controllers/projects/error_tracking_controller_spec.rb @@ -95,7 +95,7 @@ RSpec.describe Projects::ErrorTrackingController do get :index, params: params end - let(:error) { build(:error_tracking_error) } + let(:error) { build(:error_tracking_sentry_error) } it 'returns a list of errors' do expect(response).to have_gitlab_http_status(:ok) @@ -126,7 +126,7 @@ RSpec.describe Projects::ErrorTrackingController do .and_return(external_url) end - let(:error) { build(:error_tracking_error) } + let(:error) { build(:error_tracking_sentry_error) } it 'returns a list of errors' do get :index, params: project_params(format: :json) @@ -221,7 +221,7 @@ RSpec.describe Projects::ErrorTrackingController do get :details, params: issue_params(issue_id: issue_id, format: :json) end - let(:error) { build(:detailed_error_tracking_error) } + let(:error) { build(:error_tracking_sentry_detailed_error) } it 'returns an error' do expected_error = error.as_json.except('first_release_version').merge( diff --git a/spec/factories/error_tracking/detailed_error.rb b/spec/factories/error_tracking/detailed_error.rb index 83004ffae38..c2e5741b150 100644 --- a/spec/factories/error_tracking/detailed_error.rb +++ b/spec/factories/error_tracking/detailed_error.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true FactoryBot.define do - factory :detailed_error_tracking_error, parent: :error_tracking_error, class: 'Gitlab::ErrorTracking::DetailedError' do + factory :error_tracking_sentry_detailed_error, parent: :error_tracking_sentry_error, class: 'Gitlab::ErrorTracking::DetailedError' do gitlab_issue { 'http://gitlab.example.com/issues/1' } external_base_url { 'http://example.com' } first_release_last_commit { '68c914da9' } diff --git a/spec/factories/error_tracking/error.rb b/spec/factories/error_tracking/error.rb index e5f2e2ca9a7..cd2df351abe 100644 --- a/spec/factories/error_tracking/error.rb +++ b/spec/factories/error_tracking/error.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true FactoryBot.define do - factory :error_tracking_error, class: 'Gitlab::ErrorTracking::Error' do + # There is an issue to rename this class https://gitlab.com/gitlab-org/gitlab/-/issues/323342. + factory :error_tracking_sentry_error, class: 'Gitlab::ErrorTracking::Error' do id { '1' } title { 'title' } type { 'error' } @@ -25,4 +26,14 @@ FactoryBot.define do skip_create end + + factory :error_tracking_error, class: 'ErrorTracking::Error' do + project + name { 'ActionView::MissingTemplate' } + description { 'Missing template posts/edit' } + actor { 'PostsController#edit' } + platform { 'ruby' } + first_seen_at { Time.now.iso8601 } + last_seen_at { Time.now.iso8601 } + end end diff --git a/spec/factories/error_tracking/error_event.rb b/spec/factories/error_tracking/error_event.rb index 880fdf17fae..9620e3999d6 100644 --- a/spec/factories/error_tracking/error_event.rb +++ b/spec/factories/error_tracking/error_event.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true FactoryBot.define do - factory :error_tracking_error_event, class: 'Gitlab::ErrorTracking::ErrorEvent' do + # There is an issue to rename this class https://gitlab.com/gitlab-org/gitlab/-/issues/323342. + factory :error_tracking_sentry_error_event, class: 'Gitlab::ErrorTracking::ErrorEvent' do issue_id { 'id' } date_received { Time.now.iso8601 } stack_trace_entries do @@ -53,4 +54,14 @@ FactoryBot.define do skip_create end + + factory :error_tracking_error_event, class: 'ErrorTracking::ErrorEvent' do + error factory: :error_tracking_error + + description { 'ActionView::MissingTemplate' } + environment { 'development' } + level { 'error' } + occurred_at { Time.now.iso8601 } + payload { Gitlab::Json.parse(File.read(Rails.root.join('spec/fixtures/', 'error_tracking/parsed_event.json'))) } + end end diff --git a/spec/frontend/reports/codequality_report/store/actions_spec.js b/spec/frontend/reports/codequality_report/store/actions_spec.js index 9dda024bffd..2255b676074 100644 --- a/spec/frontend/reports/codequality_report/store/actions_spec.js +++ b/spec/frontend/reports/codequality_report/store/actions_spec.js @@ -7,6 +7,11 @@ import * as actions from '~/reports/codequality_report/store/actions'; import * as types from '~/reports/codequality_report/store/mutation_types'; import { reportIssues, parsedReportIssues } from '../mock_data'; +const pollInterval = 123; +const pollIntervalHeader = { + 'Poll-Interval': pollInterval, +}; + describe('Codequality Reports actions', () => { let localState; let localStore; @@ -39,10 +44,11 @@ describe('Codequality Reports actions', () => { }); describe('fetchReports', () => { + const endpoint = `${TEST_HOST}/codequality_reports.json`; let mock; beforeEach(() => { - localState.reportsPath = `${TEST_HOST}/codequality_reports.json`; + localState.reportsPath = endpoint; localState.basePath = '/base/path'; mock = new MockAdapter(axios); }); @@ -53,7 +59,7 @@ describe('Codequality Reports actions', () => { describe('on success', () => { it('commits REQUEST_REPORTS and dispatches receiveReportsSuccess', (done) => { - mock.onGet(`${TEST_HOST}/codequality_reports.json`).reply(200, reportIssues); + mock.onGet(endpoint).reply(200, reportIssues); testAction( actions.fetchReports, @@ -73,7 +79,7 @@ describe('Codequality Reports actions', () => { describe('on error', () => { it('commits REQUEST_REPORTS and dispatches receiveReportsError', (done) => { - mock.onGet(`${TEST_HOST}/codequality_reports.json`).reply(500); + mock.onGet(endpoint).reply(500); testAction( actions.fetchReports, @@ -100,6 +106,63 @@ describe('Codequality Reports actions', () => { ); }); }); + + describe('while waiting for report results', () => { + it('continues polling until it receives data', (done) => { + mock + .onGet(endpoint) + .replyOnce(204, undefined, pollIntervalHeader) + .onGet(endpoint) + .reply(200, reportIssues); + + Promise.all([ + testAction( + actions.fetchReports, + null, + localState, + [{ type: types.REQUEST_REPORTS }], + [ + { + payload: parsedReportIssues, + type: 'receiveReportsSuccess', + }, + ], + done, + ), + axios + // wait for initial NO_CONTENT response to be fulfilled + .waitForAll() + .then(() => { + jest.advanceTimersByTime(pollInterval); + }), + ]).catch(done.fail); + }); + + it('continues polling until it receives an error', (done) => { + mock + .onGet(endpoint) + .replyOnce(204, undefined, pollIntervalHeader) + .onGet(endpoint) + .reply(500); + + Promise.all([ + testAction( + actions.fetchReports, + null, + localState, + [{ type: types.REQUEST_REPORTS }], + [{ type: 'receiveReportsError', payload: expect.any(Error) }], + done, + ), + axios + // wait for initial NO_CONTENT response to be fulfilled + .waitForAll() + .then(() => { + jest.advanceTimersByTime(pollInterval); + }), + ]).catch(done.fail); + }); + }); }); describe('receiveReportsSuccess', () => { diff --git a/spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb b/spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb index bf8d2139c82..2aef483ac95 100644 --- a/spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb +++ b/spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb @@ -42,7 +42,7 @@ RSpec.describe Resolvers::ErrorTracking::SentryDetailedErrorResolver do end context 'error matched' do - let(:detailed_error) { build(:detailed_error_tracking_error) } + let(:detailed_error) { build(:error_tracking_sentry_detailed_error) } before do allow(issue_details_service).to receive(:execute) diff --git a/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb b/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb index 5c496d653b2..577d59798da 100644 --- a/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb +++ b/spec/lib/gitlab/error_tracking/stack_trace_highlight_decorator_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Gitlab::ErrorTracking::StackTraceHighlightDecorator do - let(:error_event) { build(:error_tracking_error_event) } + let(:error_event) { build(:error_tracking_sentry_error_event) } describe '.decorate' do subject(:decorate) { described_class.decorate(error_event) } diff --git a/spec/models/error_tracking/project_error_tracking_setting_spec.rb b/spec/models/error_tracking/project_error_tracking_setting_spec.rb index 3ae0666f7d0..bafa62c9543 100644 --- a/spec/models/error_tracking/project_error_tracking_setting_spec.rb +++ b/spec/models/error_tracking/project_error_tracking_setting_spec.rb @@ -241,7 +241,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end describe '#issue_details' do - let(:issue) { build(:detailed_error_tracking_error) } + let(:issue) { build(:error_tracking_sentry_detailed_error) } let(:sentry_client) { double('sentry_client', issue_details: issue) } let(:commit_id) { issue.first_release_version } diff --git a/spec/presenters/sentry_error_presenter_spec.rb b/spec/presenters/sentry_error_presenter_spec.rb index 86e43be1fa7..ce1b31d2371 100644 --- a/spec/presenters/sentry_error_presenter_spec.rb +++ b/spec/presenters/sentry_error_presenter_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe SentryErrorPresenter do - let(:error) { build(:detailed_error_tracking_error) } + let(:error) { build(:error_tracking_sentry_detailed_error) } let(:presenter) { described_class.new(error) } describe '#frequency' do diff --git a/spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb b/spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb index 14fabaaf032..40a3281d3b7 100644 --- a/spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb +++ b/spec/requests/api/graphql/project/error_tracking/sentry_detailed_error_request_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'getting a detailed sentry error' do let_it_be(:project) { create(:project, :repository) } let_it_be(:project_setting) { create(:project_error_tracking_setting, project: project) } let_it_be(:current_user) { project.owner } - let_it_be(:sentry_detailed_error) { build(:detailed_error_tracking_error) } + let_it_be(:sentry_detailed_error) { build(:error_tracking_sentry_detailed_error) } let(:sentry_gid) { sentry_detailed_error.to_global_id.to_s } let(:fields) do diff --git a/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb b/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb index e71e5a48ddc..80376f56ee8 100644 --- a/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb +++ b/spec/requests/api/graphql/project/error_tracking/sentry_errors_request_spec.rb @@ -16,7 +16,7 @@ RSpec.describe 'sentry errors requests' do end describe 'getting a detailed sentry error' do - let_it_be(:sentry_detailed_error) { build(:detailed_error_tracking_error) } + let_it_be(:sentry_detailed_error) { build(:error_tracking_sentry_detailed_error) } let(:sentry_gid) { sentry_detailed_error.to_global_id.to_s } @@ -97,7 +97,7 @@ RSpec.describe 'sentry errors requests' do end describe 'getting an errors list' do - let_it_be(:sentry_error) { build(:error_tracking_error) } + let_it_be(:sentry_error) { build(:error_tracking_sentry_error) } let_it_be(:pagination) do { 'next' => { 'cursor' => '2222' }, @@ -193,7 +193,7 @@ RSpec.describe 'sentry errors requests' do end describe 'getting a stack trace' do - let_it_be(:sentry_stack_trace) { build(:error_tracking_error_event) } + let_it_be(:sentry_stack_trace) { build(:error_tracking_sentry_error_event) } let(:sentry_gid) { global_id_of(Gitlab::ErrorTracking::DetailedError.new(id: 1)) } diff --git a/spec/services/error_tracking/issue_details_service_spec.rb b/spec/services/error_tracking/issue_details_service_spec.rb index 1954640a512..2880697e2ae 100644 --- a/spec/services/error_tracking/issue_details_service_spec.rb +++ b/spec/services/error_tracking/issue_details_service_spec.rb @@ -10,7 +10,7 @@ RSpec.describe ErrorTracking::IssueDetailsService do describe '#execute' do context 'with authorized user' do context 'when issue_details returns a detailed error' do - let(:detailed_error) { build(:detailed_error_tracking_error) } + let(:detailed_error) { build(:error_tracking_sentry_detailed_error) } let(:params) { { issue_id: detailed_error.id } } before do diff --git a/spec/services/error_tracking/issue_latest_event_service_spec.rb b/spec/services/error_tracking/issue_latest_event_service_spec.rb index b7560762ae4..82579418c10 100644 --- a/spec/services/error_tracking/issue_latest_event_service_spec.rb +++ b/spec/services/error_tracking/issue_latest_event_service_spec.rb @@ -10,7 +10,7 @@ RSpec.describe ErrorTracking::IssueLatestEventService do describe '#execute' do context 'with authorized user' do context 'when issue_latest_event returns an error event' do - let(:error_event) { build(:error_tracking_error_event) } + let(:error_event) { build(:error_tracking_sentry_error_event) } before do expect(error_tracking_setting)