diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index ecd32dcd0ce08ae45c93404e1833aab8b976b2fa..4aba633e18242499994805b6251e6ee46438536f 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -196,6 +196,11 @@ ul.content-list { display: flex; align-items: center; white-space: nowrap; + + // Override style that allows the flex-row text to wrap. + &.allow-wrap { + white-space: normal; + } } .row-main-content { diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 3ae804ff23141e8610799af9d6de2c84b2096f0f..8389272fd355c6294a16cf24a475f4de80c60e26 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -94,6 +94,25 @@ module ApplicationHelper sanitize(str, tags: %w(a span)) end + def body_data + { + page: body_data_page, + page_type_id: controller.params[:id], + find_file: find_file_path, + group: "#{@group&.path}" + }.merge(project_data) + end + + def project_data + return {} unless @project + + { + project_id: @project.id, + project: @project.path, + namespace_id: @project.namespace&.id + } + end + def body_data_page [*controller.controller_path.split('/'), controller.action_name].compact.join(':') end diff --git a/app/views/clusters/clusters/_namespace.html.haml b/app/views/clusters/clusters/_namespace.html.haml index 0c64819ad62d71dbb8e5dca3ff86c51b1198f860..8a86fd909631cc382d2a8988958939ff1c97621d 100644 --- a/app/views/clusters/clusters/_namespace.html.haml +++ b/app/views/clusters/clusters/_namespace.html.haml @@ -1,4 +1,4 @@ -- managed_namespace_help_text = s_('ClusterIntegration|Choose a prefix to be used for your namespaces. Defaults to your project path.') +- managed_namespace_help_text = s_('ClusterIntegration|Set a prefix for your namespaces. If not set, defaults to your project path. If modified, existing environments will use their current namespaces until the cluster cache is cleared.') - non_managed_namespace_help_text = s_('ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, pod logs, and Web terminals.') - managed_namespace_help_link = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank' diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index c38f96f302a5a5e98978d195b4d83229f5dc75db..f4ab491a38ef60904e06776d46b12ed51555f883 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -1,7 +1,7 @@ !!! 5 %html{ lang: I18n.locale, class: page_class } = render "layouts/head" - %body{ class: "#{user_application_theme} #{@body_class} #{client_class_list}", data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}", find_file: find_file_path } } + %body{ class: "#{user_application_theme} #{@body_class} #{client_class_list}", data: body_data } = render "layouts/init_auto_complete" if @gfm_form = render "layouts/init_client_detection_flags" = render 'peek/bar' diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml index b04d484c8a75a97a5ae082d0b69515fe79d3bf0e..75805192a616aa8a98ba91ff605028e7a8be8be2 100644 --- a/app/views/projects/tags/_tag.html.haml +++ b/app/views/projects/tags/_tag.html.haml @@ -1,7 +1,7 @@ - commit = @repository.commit(tag.dereferenced_target) - release = @releases.find { |release| release.tag == tag.name } -%li.flex-row - .row-main-content.str-truncated +%li.flex-row.allow-wrap + .row-main-content = icon('tag') = link_to tag.name, project_tag_path(@project, tag.name), class: 'item-title ref-name prepend-left-4' @@ -26,7 +26,7 @@ = _("Release") = link_to release.name, project_releases_path(@project, anchor: release.tag), class: 'tag-release-link' - if release.description.present? - .description.md.prepend-top-default + .md.prepend-top-default = markdown_field(release, :description) .row-fixed-content.controls.flex-row diff --git a/changelogs/unreleased/33482-allow-text-wrapping-on-repository-tags-page.yml b/changelogs/unreleased/33482-allow-text-wrapping-on-repository-tags-page.yml new file mode 100644 index 0000000000000000000000000000000000000000..567e1b7cfda5ae721786993e2043a223f4922210 --- /dev/null +++ b/changelogs/unreleased/33482-allow-text-wrapping-on-repository-tags-page.yml @@ -0,0 +1,5 @@ +--- +title: Allow patch notes on repo tags page to word wrap +merge_request: 20135 +author: +type: fixed diff --git a/changelogs/unreleased/add_body_data_elements_for_page_type_id_project_id_and_namespace_id.yml b/changelogs/unreleased/add_body_data_elements_for_page_type_id_project_id_and_namespace_id.yml new file mode 100644 index 0000000000000000000000000000000000000000..587741a8ea584449b181b5b72d997fd06b94a7b7 --- /dev/null +++ b/changelogs/unreleased/add_body_data_elements_for_page_type_id_project_id_and_namespace_id.yml @@ -0,0 +1,5 @@ +--- +title: Add body data elements for pageview context +merge_request: 18450 +author: +type: added diff --git a/changelogs/unreleased/update-managed-namespace-prefix-copy.yml b/changelogs/unreleased/update-managed-namespace-prefix-copy.yml new file mode 100644 index 0000000000000000000000000000000000000000..e19e8078f64c162349f46137ed46162c53fd4541 --- /dev/null +++ b/changelogs/unreleased/update-managed-namespace-prefix-copy.yml @@ -0,0 +1,5 @@ +--- +title: Update copy on managed namespace prefixes +merge_request: 20935 +author: +type: fixed diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md index a6474b8b141061b06c7455b7c09e921b1999fe9d..64a59796ebce56905001a353370dcb2f77579e6f 100644 --- a/doc/development/documentation/index.md +++ b/doc/development/documentation/index.md @@ -30,6 +30,23 @@ The source of the documentation exists within the codebase of each GitLab applic Documentation issues and merge requests are part of their respective repositories and all have the label `Documentation`. +### Branch naming + +The [CI pipeline for the main GitLab project](../pipelines.md) is configured to automatically +run only the jobs that match the type of contribution. If your contribution contains +**only** documentation changes, then only documentation-related jobs will be run, and +the pipeline will complete much faster than a code contribution. + +If you are submitting documentation-only changes to Runner, Omnibus, or Charts, +the fast pipeline is not determined automatically. Instead, create branches for +docs-only merge requests using the following guide: + +| Branch name | Valid example | +|:----------------------|:-----------------------------| +| Starting with `docs/` | `docs/update-api-issues` | +| Starting with `docs-` | `docs-update-api-issues` | +| Ending in `-docs` | `123-update-api-issues-docs` | + ## Contributing to docs [Contributions to GitLab docs](workflow.md) are welcome from the entire GitLab community. diff --git a/doc/development/testing_guide/end_to_end/best_practices.md b/doc/development/testing_guide/end_to_end/best_practices.md index e2a0d267ba1a7d159afe9409e59e875b2391feda..fc00fcea67e51daf9b8ca97b114d8fc2d792f74c 100644 --- a/doc/development/testing_guide/end_to_end/best_practices.md +++ b/doc/development/testing_guide/end_to_end/best_practices.md @@ -54,9 +54,9 @@ In summary: - **Do**: Split tests across separate files, unless the tests share expensive setup. - **Don't**: Put new tests in an existing file without considering the impact on parallelization. -## Limit the use of `before(:all)` hook +## Limit the use of `before(:all)` and `after` hooks -Limit the use of `before(:all)` to perform setup tasks with only API calls, non UI operations +Limit the use of `before(:all)` hook to perform setup tasks with only API calls, non UI operations or basic UI operations such as login. We use [`capybara-screenshot`](https://github.com/mattheworiordan/capybara-screenshot) library to automatically save screenshots on failures. @@ -66,6 +66,10 @@ This library [saves the screenshots in the RSpec's `after` hook](https://github. Given this fact, we should limit the use of `before(:all)` to only those operations where a screenshot is not necessary in case of failure and QA logs would be enough for debugging. +Similarly, the `after` hook should only be used for non-UI operations. Any UI operations in `after` hook in a test file +would execute before the `after` hook that takes the screenshot. This would result in moving the UI status away from the +point of failure and so the screenshot would not be captured at the right moment. + ## Ensure tests do not leave the browser logged in All QA tests expect to be able to log in at the start of the test. @@ -74,7 +78,7 @@ That's not possible if a test leaves the browser logged in when it finishes. Nor For an example see: <https://gitlab.com/gitlab-org/gitlab/issues/34736> -Ideally, any actions peformed in an `after(:context)` (or [`before(:context)`](#limit-the-use-of-beforeall-hook)) block would be performed via the API. But if it's necessary to do so via the UI (e.g., if API functionality doesn't exist), make sure to log out at the end of the block. +Ideally, any actions peformed in an `after(:context)` (or [`before(:context)`](#limit-the-use-of-beforeall-and-after-hooks)) block would be performed via the API. But if it's necessary to do so via the UI (e.g., if API functionality doesn't exist), make sure to log out at the end of the block. ```ruby after(:all) do diff --git a/doc/user/admin_area/settings/visibility_and_access_controls.md b/doc/user/admin_area/settings/visibility_and_access_controls.md index 73406fd503755861f9c4ca184d2445ee5a0576e7..30f9d4e53a34cfa7c09dfbe32ac697330a20e530 100644 --- a/doc/user/admin_area/settings/visibility_and_access_controls.md +++ b/doc/user/admin_area/settings/visibility_and_access_controls.md @@ -14,8 +14,11 @@ To access the visibility and access control options: ## Default branch protection -Branch protection specifies which roles can push to branches and which roles can delete -branches. +This global option defines the branch protection that applies to every repository's default branch. [Branch protection](../../project/protected_branches.md) specifies which roles can push to branches and which roles can delete +branches. In this case _Default_ refers to a repository's default branch, which in most cases is _master_. +branches. "Default" in this case refers to a repository's default branch, which in most cases would be "master". + +This setting applies only to each repositories' default branch. To protect other branches, you must configure branch protection in repository. For details, see [Protected Branches](../../project/protected_branches.md). To change the default branch protection: diff --git a/doc/user/project/integrations/github.md b/doc/user/project/integrations/github.md index 9d16748085cf4a76a367be2313f15820fcd2948e..b8b073af2a4c69fad0c5d73fa9310b1940770668 100644 --- a/doc/user/project/integrations/github.md +++ b/doc/user/project/integrations/github.md @@ -33,6 +33,9 @@ with `repo:status` access granted: 1. Optionally uncheck **Static status check names** checkbox to disable static status check names. 1. Save or optionally click "Test Settings". +Once the integration is configured, see [Pipelines for external pull requests](../../../ci/ci_cd_for_external_repos/#pipelines-for-external-pull-requests) +to configure pipelines to run for open pull requests. + #### Static / dynamic status check names > - Introduced in GitLab 11.5: using static status check names as opt-in option. diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 95a04eb18b09a0976f88f11b1b6a8eaf09c95649..6b6143eba96f8868b29e818420e581bc904305b3 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -3595,9 +3595,6 @@ msgstr "" msgid "ClusterIntegration|Certificate Authority bundle (PEM format)" msgstr "" -msgid "ClusterIntegration|Choose a prefix to be used for your namespaces. Defaults to your project path." -msgstr "" - msgid "ClusterIntegration|Choose the %{startLink}security group %{externalLinkIcon} %{endLink} to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets." msgstr "" @@ -4132,6 +4129,9 @@ msgstr "" msgid "ClusterIntegration|Service token is required." msgstr "" +msgid "ClusterIntegration|Set a prefix for your namespaces. If not set, defaults to your project path. If modified, existing environments will use their current namespaces until the cluster cache is cleared." +msgstr "" + msgid "ClusterIntegration|Show" msgstr "" diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb index 66c56c86fc8238c9678ef15a98b514384adaa952..7143cc574b85514eae1171bdec21add20a58369d 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/group/create_group_with_mattermost_team_spec.rb @@ -4,8 +4,7 @@ module QA context 'Configure', :orchestrated, :mattermost do describe 'Mattermost support' do it 'user creates a group with a mattermost team' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Page::Main::Menu.perform(&:go_to_groups) Page::Dashboard::Groups.perform do |groups| diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb index c9acd7df7762b963c394b4ba249e5b2daca67418..6f75940e1f0a6a3b7ccb9dcc31c2bb101d6362ac 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage' do describe 'Project transfer between groups' do it 'user transfers a project between groups' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in source_group = Resource::Group.fabricate_via_api! do |group| group.path = 'source-group' diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb index d8233fc5586417d48d03706d92176c4ff365dcca..1050005a231fb30d70f405c2fa99a4140fca43c6 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage', :smoke do describe 'basic user login' do it 'user logs in using basic credentials and logs out' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Page::Main::Menu.perform do |menu| expect(menu).to have_personal_area diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb index 10cd8470a8fbb6951dc40bd4abb2cd2b97af4c34..46a0f1a4c8be546798e89b635364e04ef10e5207 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_gitlab_via_ldap_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage', :orchestrated, :ldap_no_tls, :ldap_tls do describe 'LDAP login' do it 'user logs into GitLab using LDAP credentials' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Page::Main::Menu.perform do |menu| expect(menu).to have_personal_area diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb index e66c12c1301c26abf936288cbb31710a231cbedc..a680cfa96bd36ba6a8bb9d5fd7361c3e45e4d06a 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_into_mattermost_via_gitlab_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage', :orchestrated, :mattermost do describe 'Mattermost login' do it 'user logs into Mattermost using GitLab OAuth' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Support::Retrier.retry_on_exception do Runtime::Browser.visit(:mattermost, Page::Mattermost::Login) diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb index abb46463ed24685b7b29c358564443cb42edd56a..9a273e9cd1c38a53e3c9f3b340e2db8fe8527b33 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage' do describe 'Add project member' do it 'user adds project member' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in user = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb index fbe857dc2a528646025a7366e9819e6bd60250b2..9ca933a957f2ef75e7b039892563f9809ba3044f 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/create_project_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage', :smoke do describe 'Project creation' do it 'user creates a new project' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in created_project = Resource::Project.fabricate_via_browser_ui! do |project| project.name = 'awesome-project' diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb index 4f68500974e31c00a4a72151a0edede1b86b1204..7a47194c3a4e6f2d35ac263a3b65210c5b832635 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb @@ -23,8 +23,7 @@ module QA end it 'user imports a GitHub repo' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in imported_project # import the project diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb index fe92fbd3ffeac3c64743c13f8dea954125194bd0..5f3b492ea8190d86e8998d3ef03cab141221f976 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb @@ -4,8 +4,7 @@ module QA context 'Manage' do describe 'Project activity' do it 'user creates an event in the activity page upon Git push' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project_push = Resource::Repository::ProjectPush.fabricate! do |push| push.file_name = 'README.md' diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb index 6bdec232bb0b3e3b79bb834e4a55305a03b0793f..f48fe78c530b51c101867e88fc457fbd798a6c75 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Create a new merge request' do before do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in @project = Resource::Project.fabricate_via_api! do |project| project.name = 'project' diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb index 6ca7af8a3afa0d4d7055baf9eca03755bea7e7bb..370bf30f3a4c4bffcd03eae41478396a3570c619 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Merge request creation from fork' do it 'user forks a project, submits a merge request and maintainer merges it' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in merge_request = Resource::MergeRequestFromFork.fabricate! do |merge_request| merge_request.fork_branch = 'feature-branch' diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb index c7b5e40d0beb5c9fc14ae2959361d83440fc0717..c41cb24f4c2b66e3be1fffc99ee035763911d5fd 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb @@ -5,8 +5,7 @@ module QA context 'Create', :quarantine do describe 'Merge request rebasing' do it 'user rebases source branch of merge request' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project = Resource::Project.fabricate! do |project| project.name = "only-fast-forward" diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb index a93f2695ec2dcaacb0f35b0d7794ccb36adad55e..f1ba726ddec6e40593dacb59116d90a3c345ed02 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/squash_merge_request_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Merge request squashing' do it 'user squashes commits while merging' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project = Resource::Project.fabricate! do |project| project.name = "squash-before-merge" diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb index 3306c5f5c50c5a6055872ae1cdd5de03424ce603..7b1c2a71158d3f733a56f8bc0eba97082585d4d3 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb @@ -16,8 +16,7 @@ module QA commit_message_of_third_branch = "Add #{file_third_branch}" before do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project = Resource::Project.fabricate! do |proj| proj.name = 'project-qa-test' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb index 56a7a04e84018ec4a8c48e14ddce4d0c3a3ed240..474a7904fea423ee13dc8f7962f5edbe7f021bb0 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_ssh_key_spec.rb @@ -6,8 +6,7 @@ module QA let(:key_title) { "key for ssh tests #{Time.now.to_f}" } it 'user adds and then removes an SSH key', :smoke do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in key = Resource::SSHKey.fabricate! do |resource| resource.title = key_title diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb index ec3c4c1ae946e657e6372ef06a58c8fb8dbab8cc..3771be1a8d156abe46308e5088c9f5eeb516a806 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb @@ -6,8 +6,7 @@ module QA context 'Create', :quarantine do describe 'Push over HTTP using Git protocol version 2', :requires_git_protocol_v2 do it 'user pushes to the repository' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in # Create a project to push to project = Resource::Project.fabricate! do |project| diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb index 58f402a19cefd8ea00be86c365de7df3f5b99873..e2b2ee801c3aff5180a6877b5a94e1210888b05a 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb @@ -17,20 +17,15 @@ module QA end end - def login - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) - end - around do |example| # Create an SSH key to be used with Git - login + Flow::Login.sign_in ssh_key example.run # Remove the SSH key - login + Flow::Login.sign_in Page::Main::Menu.perform(&:click_settings_link) Page::Profile::Menu.perform(&:click_ssh_keys) Page::Profile::SSHKeys.perform do |ssh_keys| diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb index 1f4fb08accc3b885da01a02164b717b36db9478f..c713f11af7df486d5cb2a5d2af23044b4ec46819 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Git push over HTTP', :ldap_no_tls do it 'user using a personal access token pushes code to the repository' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in access_token = Resource::PersonalAccessToken.fabricate!.access_token diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb index 58e6c160a3ac5a90ee7c1f86fe274ae37e8545a7..2bd54d763a69860571e6b9d6ee1c068f784f69ad 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Git push over HTTP', :ldap_no_tls do it 'user pushes code to the repository' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in project_push = Resource::Repository::ProjectPush.fabricate! do |push| push.file_name = 'README.md' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb index a0251e1c385820902448ff2c45b5b9537c455e79..1837a110d799f7674f3ae179a396590f8b40a4fd 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/use_ssh_key_spec.rb @@ -9,8 +9,7 @@ module QA let(:key_title) { "key for ssh tests #{Time.now.to_f}" } it 'user adds an ssh key and pushes code to the repository' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in key = Resource::SSHKey.fabricate! do |resource| resource.title = key_title diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb index cbc9f63f772bfa788210defebeb547db032d8966..277e7364adae9d768c92e1c040f99d3ee7de999c 100644 --- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_snippet_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create', :smoke do describe 'Snippet creation' do it 'User creates a snippet' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in Page::Main::Menu.perform(&:go_to_snippets) diff --git a/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb b/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb index 770d66141eb07594018224fbc43717b212591572..42aa527da85781e78c46f30bd78ed05569530d96 100644 --- a/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/wiki/create_edit_clone_push_wiki_spec.rb @@ -4,8 +4,7 @@ module QA context 'Create' do describe 'Wiki management' do it 'user creates, edits, clones, and pushes to the wiki' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in wiki = Resource::Wiki.fabricate! do |resource| resource.title = 'Home' diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb index 6f39a755392d3272edc2b544ba627252f06bcd94..9c964c726f1d43657126344a6f881c63ada5822d 100644 --- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb @@ -4,8 +4,7 @@ module QA context 'Release' do describe 'Deploy key creation' do it 'user adds a deploy key' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in key = Runtime::Key::RSA.new deploy_key_title = 'deploy key title' diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb index 9dc4bcc8a0388546d421990729996967c467b3a8..3badaa983cbef86eb4621bb1b016323c5caea262 100644 --- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb @@ -10,8 +10,7 @@ module QA @job_log_json_flag_enabled = Runtime::Feature.enabled?('job_log_json') Runtime::Feature.disable('job_log_json') if @job_log_json_flag_enabled - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in @runner_name = "qa-runner-#{Time.now.to_i}" diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb index ec0c45652fd9722f736ce58f9601d826468b0fa5..9cb9f9ba529ce023dc6ace7de9acff96349350c5 100644 --- a/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb @@ -4,8 +4,7 @@ module QA context 'Release' do describe 'Deploy token creation' do it 'user adds a deploy token' do - Runtime::Browser.visit(:gitlab, Page::Main::Login) - Page::Main::Login.perform(&:sign_in_using_credentials) + Flow::Login.sign_in deploy_token_name = 'deploy token name' one_week_from_now = Date.today + 7 diff --git a/spec/javascripts/lib/utils/accessor_spec.js b/spec/frontend/lib/utils/accessor_spec.js similarity index 91% rename from spec/javascripts/lib/utils/accessor_spec.js rename to spec/frontend/lib/utils/accessor_spec.js index 0045330e4705cb49c4860f08cb6845065e4660d2..752a88296e6ba111e7dda491c018c18abd3238d2 100644 --- a/spec/javascripts/lib/utils/accessor_spec.js +++ b/spec/frontend/lib/utils/accessor_spec.js @@ -1,14 +1,18 @@ +import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import AccessorUtilities from '~/lib/utils/accessor'; describe('AccessorUtilities', () => { + useLocalStorageSpy(); + const testError = new Error('test error'); describe('isPropertyAccessSafe', () => { let base; it('should return `true` if access is safe', () => { - base = { testProp: 'testProp' }; - + base = { + testProp: 'testProp', + }; expect(AccessorUtilities.isPropertyAccessSafe(base, 'testProp')).toBe(true); }); @@ -54,17 +58,12 @@ describe('AccessorUtilities', () => { }); describe('isLocalStorageAccessSafe', () => { - beforeEach(() => { - spyOn(window.localStorage, 'setItem'); - spyOn(window.localStorage, 'removeItem'); - }); - it('should return `true` if access is safe', () => { expect(AccessorUtilities.isLocalStorageAccessSafe()).toBe(true); }); it('should return `false` if access to .setItem isnt safe', () => { - window.localStorage.setItem.and.callFake(() => { + window.localStorage.setItem.mockImplementation(() => { throw testError; }); diff --git a/spec/javascripts/lib/utils/dom_utils_spec.js b/spec/frontend/lib/utils/dom_utils_spec.js similarity index 75% rename from spec/javascripts/lib/utils/dom_utils_spec.js rename to spec/frontend/lib/utils/dom_utils_spec.js index 2bcf37f35c7ac812cf155d29ba26a5e773dc1a49..10b4a10a8ffcae667270702b94fac25ee9492dae 100644 --- a/spec/javascripts/lib/utils/dom_utils_spec.js +++ b/spec/frontend/lib/utils/dom_utils_spec.js @@ -25,7 +25,7 @@ describe('DOM Utils', () => { addClassIfElementExists(childElement, className); - expect(childElement.classList).toContain(className); + expect(childElement.classList).toContainEqual(className); }); it('does not throw if element does not exist', () => { @@ -40,22 +40,44 @@ describe('DOM Utils', () => { describe('canScrollUp', () => { [1, 100].forEach(scrollTop => { it(`is true if scrollTop is > 0 (${scrollTop})`, () => { - expect(canScrollUp({ scrollTop })).toBe(true); + expect( + canScrollUp({ + scrollTop, + }), + ).toBe(true); }); }); [0, -10].forEach(scrollTop => { it(`is false if scrollTop is <= 0 (${scrollTop})`, () => { - expect(canScrollUp({ scrollTop })).toBe(false); + expect( + canScrollUp({ + scrollTop, + }), + ).toBe(false); }); }); it('is true if scrollTop is > margin', () => { - expect(canScrollUp({ scrollTop: TEST_MARGIN + 1 }, TEST_MARGIN)).toBe(true); + expect( + canScrollUp( + { + scrollTop: TEST_MARGIN + 1, + }, + TEST_MARGIN, + ), + ).toBe(true); }); it('is false if scrollTop is <= margin', () => { - expect(canScrollUp({ scrollTop: TEST_MARGIN }, TEST_MARGIN)).toBe(false); + expect( + canScrollUp( + { + scrollTop: TEST_MARGIN, + }, + TEST_MARGIN, + ), + ).toBe(false); }); }); @@ -63,7 +85,11 @@ describe('DOM Utils', () => { let element; beforeEach(() => { - element = { scrollTop: 7, offsetHeight: 22, scrollHeight: 30 }; + element = { + scrollTop: 7, + offsetHeight: 22, + scrollHeight: 30, + }; }); it('is true if element can be scrolled down', () => { diff --git a/spec/javascripts/lib/utils/file_upload_spec.js b/spec/frontend/lib/utils/file_upload_spec.js similarity index 91% rename from spec/javascripts/lib/utils/file_upload_spec.js rename to spec/frontend/lib/utils/file_upload_spec.js index 8f7092f63deb1b2ef732a12e5484925ee1ead740..1255d6fc14f89ab50d3ced1c6692328397cd8c4a 100644 --- a/spec/javascripts/lib/utils/file_upload_spec.js +++ b/spec/frontend/lib/utils/file_upload_spec.js @@ -20,7 +20,7 @@ describe('File upload', () => { const btn = document.querySelector('.js-button'); const input = document.querySelector('.js-input'); - spyOn(input, 'click'); + jest.spyOn(input, 'click').mockReturnValue(); btn.click(); @@ -43,7 +43,7 @@ describe('File upload', () => { const btn = document.querySelector('.js-button'); fileUpload('.js-not-button', '.js-input'); - spyOn(input, 'click'); + jest.spyOn(input, 'click').mockReturnValue(); btn.click(); @@ -55,7 +55,7 @@ describe('File upload', () => { const btn = document.querySelector('.js-button'); fileUpload('.js-button', '.js-not-input'); - spyOn(input, 'click'); + jest.spyOn(input, 'click').mockReturnValue(); btn.click(); diff --git a/spec/javascripts/lib/utils/higlight_spec.js b/spec/frontend/lib/utils/highlight_spec.js similarity index 100% rename from spec/javascripts/lib/utils/higlight_spec.js rename to spec/frontend/lib/utils/highlight_spec.js diff --git a/spec/javascripts/lib/utils/icon_utils_spec.js b/spec/frontend/lib/utils/icon_utils_spec.js similarity index 59% rename from spec/javascripts/lib/utils/icon_utils_spec.js rename to spec/frontend/lib/utils/icon_utils_spec.js index 3fd3940efe8677dae6832157b1f68a7877b3ad31..816d634ad1564bd163e5f8771016d8bbadee630d 100644 --- a/spec/javascripts/lib/utils/icon_utils_spec.js +++ b/spec/frontend/lib/utils/icon_utils_spec.js @@ -17,51 +17,44 @@ describe('Icon utils', () => { let axiosMock; let mockEndpoint; - let getIcon; const mockName = 'mockIconName'; const mockPath = 'mockPath'; + const getIcon = () => iconUtils.getSvgIconPathContent(mockName); beforeEach(() => { axiosMock = new MockAdapter(axios); mockEndpoint = axiosMock.onGet(gon.sprite_icons); - getIcon = iconUtils.getSvgIconPathContent(mockName); }); afterEach(() => { axiosMock.restore(); }); - it('extracts svg icon path content from sprite icons', done => { + it('extracts svg icon path content from sprite icons', () => { mockEndpoint.replyOnce( 200, `<svg><symbol id="${mockName}"><path d="${mockPath}"/></symbol></svg>`, ); - getIcon - .then(path => { - expect(path).toBe(mockPath); - done(); - }) - .catch(done.fail); + + return getIcon().then(path => { + expect(path).toBe(mockPath); + }); }); - it('returns null if icon path content does not exist', done => { + it('returns null if icon path content does not exist', () => { mockEndpoint.replyOnce(200, ``); - getIcon - .then(path => { - expect(path).toBe(null); - done(); - }) - .catch(done.fail); + + return getIcon().then(path => { + expect(path).toBe(null); + }); }); - it('returns null if an http error occurs', done => { + it('returns null if an http error occurs', () => { mockEndpoint.replyOnce(500); - getIcon - .then(path => { - expect(path).toBe(null); - done(); - }) - .catch(done.fail); + + return getIcon().then(path => { + expect(path).toBe(null); + }); }); }); }); diff --git a/spec/javascripts/lib/utils/text_markdown_spec.js b/spec/frontend/lib/utils/text_markdown_spec.js similarity index 97% rename from spec/javascripts/lib/utils/text_markdown_spec.js rename to spec/frontend/lib/utils/text_markdown_spec.js index df4029555bbc534823d773a0de99dca091c269a7..ba3e4020e66ee8c12211fec0d02bd2288d2ed979 100644 --- a/spec/javascripts/lib/utils/text_markdown_spec.js +++ b/spec/frontend/lib/utils/text_markdown_spec.js @@ -243,7 +243,7 @@ describe('init markdown', () => { }); it('uses ace editor insert text when editor is passed in', () => { - spyOn(editor, 'insert'); + jest.spyOn(editor, 'insert').mockReturnValue(); insertMarkdownText({ text: editor.getValue, @@ -258,7 +258,7 @@ describe('init markdown', () => { }); it('adds block tags on line above and below selection', () => { - spyOn(editor, 'insert'); + jest.spyOn(editor, 'insert').mockReturnValue(); const selected = 'this text \n is multiple \n lines'; const text = `before \n ${selected} \n after`; @@ -276,7 +276,7 @@ describe('init markdown', () => { }); it('uses ace editor to navigate back tag length when nothing is selected', () => { - spyOn(editor, 'navigateLeft'); + jest.spyOn(editor, 'navigateLeft').mockReturnValue(); insertMarkdownText({ text: editor.getValue, @@ -291,7 +291,7 @@ describe('init markdown', () => { }); it('ace editor does not navigate back when there is selected text', () => { - spyOn(editor, 'navigateLeft'); + jest.spyOn(editor, 'navigateLeft').mockReturnValue(); insertMarkdownText({ text: editor.getValue, diff --git a/spec/javascripts/lib/utils/users_cache_spec.js b/spec/frontend/lib/utils/users_cache_spec.js similarity index 85% rename from spec/javascripts/lib/utils/users_cache_spec.js rename to spec/frontend/lib/utils/users_cache_spec.js index acb5e024acd7dcbe9c3a20f3f87e9181066e16b3..7ed8712348253724c1e55edd84230245c9fc7b1a 100644 --- a/spec/javascripts/lib/utils/users_cache_spec.js +++ b/spec/frontend/lib/utils/users_cache_spec.js @@ -4,7 +4,10 @@ import UsersCache from '~/lib/utils/users_cache'; describe('UsersCache', () => { const dummyUsername = 'win'; const dummyUserId = 123; - const dummyUser = { name: 'has a farm', username: 'farmer' }; + const dummyUser = { + name: 'has a farm', + username: 'farmer', + }; const dummyUserStatus = 'my status'; beforeEach(() => { @@ -68,7 +71,6 @@ describe('UsersCache', () => { it('does nothing if cache contains no matching data', () => { UsersCache.internalStorage['no body'] = 'no data'; - UsersCache.remove(dummyUsername); expect(UsersCache.internalStorage['no body']).toBe('no data'); @@ -76,7 +78,6 @@ describe('UsersCache', () => { it('removes matching data', () => { UsersCache.internalStorage[dummyUsername] = dummyUser; - UsersCache.remove(dummyUsername); expect(UsersCache.internalStorage).toEqual({}); @@ -87,13 +88,16 @@ describe('UsersCache', () => { let apiSpy; beforeEach(() => { - spyOn(Api, 'users').and.callFake((query, options) => apiSpy(query, options)); + jest.spyOn(Api, 'users').mockImplementation((query, options) => apiSpy(query, options)); }); it('stores and returns data from API call if cache is empty', done => { apiSpy = (query, options) => { expect(query).toBe(''); - expect(options).toEqual({ username: dummyUsername }); + expect(options).toEqual({ + username: dummyUsername, + }); + return Promise.resolve({ data: [dummyUser], }); @@ -110,14 +114,18 @@ describe('UsersCache', () => { it('returns undefined if Ajax call fails and cache is empty', done => { const dummyError = new Error('server exploded'); + apiSpy = (query, options) => { expect(query).toBe(''); - expect(options).toEqual({ username: dummyUsername }); + expect(options).toEqual({ + username: dummyUsername, + }); + return Promise.reject(dummyError); }; UsersCache.retrieve(dummyUsername) - .then(user => fail(`Received unexpected user: ${JSON.stringify(user)}`)) + .then(user => done.fail(`Received unexpected user: ${JSON.stringify(user)}`)) .catch(error => { expect(error).toBe(dummyError); }) @@ -127,7 +135,8 @@ describe('UsersCache', () => { it('makes no Ajax call if matching data exists', done => { UsersCache.internalStorage[dummyUsername] = dummyUser; - apiSpy = () => fail(new Error('expected no Ajax call!')); + + apiSpy = () => done.fail(new Error('expected no Ajax call!')); UsersCache.retrieve(dummyUsername) .then(user => { @@ -142,12 +151,13 @@ describe('UsersCache', () => { let apiSpy; beforeEach(() => { - spyOn(Api, 'user').and.callFake(id => apiSpy(id)); + jest.spyOn(Api, 'user').mockImplementation(id => apiSpy(id)); }); it('stores and returns data from API call if cache is empty', done => { apiSpy = id => { expect(id).toBe(dummyUserId); + return Promise.resolve({ data: dummyUser, }); @@ -164,13 +174,15 @@ describe('UsersCache', () => { it('returns undefined if Ajax call fails and cache is empty', done => { const dummyError = new Error('server exploded'); + apiSpy = id => { expect(id).toBe(dummyUserId); + return Promise.reject(dummyError); }; UsersCache.retrieveById(dummyUserId) - .then(user => fail(`Received unexpected user: ${JSON.stringify(user)}`)) + .then(user => done.fail(`Received unexpected user: ${JSON.stringify(user)}`)) .catch(error => { expect(error).toBe(dummyError); }) @@ -180,7 +192,8 @@ describe('UsersCache', () => { it('makes no Ajax call if matching data exists', done => { UsersCache.internalStorage[dummyUserId] = dummyUser; - apiSpy = () => fail(new Error('expected no Ajax call!')); + + apiSpy = () => done.fail(new Error('expected no Ajax call!')); UsersCache.retrieveById(dummyUserId) .then(user => { @@ -195,12 +208,13 @@ describe('UsersCache', () => { let apiSpy; beforeEach(() => { - spyOn(Api, 'userStatus').and.callFake(id => apiSpy(id)); + jest.spyOn(Api, 'userStatus').mockImplementation(id => apiSpy(id)); }); it('stores and returns data from API call if cache is empty', done => { apiSpy = id => { expect(id).toBe(dummyUserId); + return Promise.resolve({ data: dummyUserStatus, }); @@ -217,13 +231,15 @@ describe('UsersCache', () => { it('returns undefined if Ajax call fails and cache is empty', done => { const dummyError = new Error('server exploded'); + apiSpy = id => { expect(id).toBe(dummyUserId); + return Promise.reject(dummyError); }; UsersCache.retrieveStatusById(dummyUserId) - .then(userStatus => fail(`Received unexpected user: ${JSON.stringify(userStatus)}`)) + .then(userStatus => done.fail(`Received unexpected user: ${JSON.stringify(userStatus)}`)) .catch(error => { expect(error).toBe(dummyError); }) @@ -232,8 +248,11 @@ describe('UsersCache', () => { }); it('makes no Ajax call if matching data exists', done => { - UsersCache.internalStorage[dummyUserId] = { status: dummyUserStatus }; - apiSpy = () => fail(new Error('expected no Ajax call!')); + UsersCache.internalStorage[dummyUserId] = { + status: dummyUserStatus, + }; + + apiSpy = () => done.fail(new Error('expected no Ajax call!')); UsersCache.retrieveStatusById(dummyUserId) .then(userStatus => { diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index d3d25d3cb74e0d1cd218fe22a27bd230d6e93bfd..a0c85863150fa755f5d8e81cd2039e7d97da49c2 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -235,4 +235,88 @@ describe ApplicationHelper do end end end + + describe '#body_data' do + context 'when @project is not set' do + it 'does not include project data in the body data elements' do + expect(helper.body_data).to eq( + { + page: 'application', + page_type_id: nil, + find_file: nil, + group: '' + } + ) + end + + context 'when @group is set' do + it 'sets group in the body data elements' do + group = create(:group) + + assign(:group, group) + + expect(helper.body_data).to eq( + { + page: 'application', + page_type_id: nil, + find_file: nil, + group: group.path + } + ) + end + end + end + + context 'when @project is set' do + it 'includes all possible body data elements and associates the project elements with project' do + project = create(:project) + + assign(:project, project) + + expect(helper.body_data).to eq( + { + page: 'application', + page_type_id: nil, + find_file: nil, + group: '', + project_id: project.id, + project: project.name, + namespace_id: project.namespace.id + } + ) + end + + context 'when controller is issues' do + before do + stub_controller_method(:controller_path, 'projects:issues') + end + + context 'when params[:id] is present and the issue exsits and action_name is show' do + it 'sets all project and id elements correctly related to the issue' do + issue = create(:issue) + stub_controller_method(:action_name, 'show') + stub_controller_method(:params, { id: issue.id }) + + assign(:project, issue.project) + + expect(helper.body_data).to eq( + { + page: 'projects:issues:show', + page_type_id: issue.id, + find_file: nil, + group: '', + project_id: issue.project.id, + project: issue.project.name, + namespace_id: issue.project.namespace.id + } + ) + end + end + end + end + + def stub_controller_method(method_name, value) + allow(helper.controller).to receive(method_name).and_return(value) + end + end end diff --git a/spec/views/layouts/application.html.haml_spec.rb b/spec/views/layouts/application.html.haml_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..bdd4a97a1f5e80ed1a600aa20488d321dc8684a0 --- /dev/null +++ b/spec/views/layouts/application.html.haml_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'layouts/application' do + let(:user) { create(:user) } + + before do + allow(view).to receive(:current_application_settings).and_return(Gitlab::CurrentSettings.current_application_settings) + allow(view).to receive(:experiment_enabled?).and_return(false) + allow(view).to receive(:session).and_return({}) + allow(view).to receive(:user_signed_in?).and_return(true) + allow(view).to receive(:current_user).and_return(user) + end + + context 'body data elements for pageview context' do + let(:body_data) do + { + body_data_page: 'projects:issues:show', + body_data_page_type_id: '1', + body_data_project_id: '2', + body_data_namespace_id: '3' + } + end + + before do + allow(view).to receive(:body_data).and_return(body_data) + render + end + + it 'includes the body element page' do + expect(rendered).to include('data-page="projects:issues:show"') + end + + it 'includes the body element page_type_id' do + expect(rendered).to include('data-page-type-id="1"') + end + + it 'includes the body element project_id' do + expect(rendered).to include('data-project-id="2"') + end + + it 'includes the body element namespace_id' do + expect(rendered).to include('data-namespace-id="3"') + end + end +end