Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-03-29 18:08:06 +00:00
parent 9c28b22cfc
commit 2194dac753
24 changed files with 37 additions and 505 deletions

View File

@ -1,47 +0,0 @@
<script>
import Identicon from '../identicon.vue';
import ProjectAvatarImage from './image.vue';
export default {
name: 'DeprecatedProjectAvatar',
components: {
Identicon,
ProjectAvatarImage,
},
props: {
project: {
type: Object,
required: true,
},
size: {
type: Number,
default: 40,
required: false,
},
},
computed: {
sizeClass() {
return `s${this.size}`;
},
},
};
</script>
<template>
<span :class="sizeClass" class="avatar-container rect-avatar project-avatar">
<project-avatar-image
v-if="project.avatar_url"
:link-href="project.path"
:img-src="project.avatar_url"
:img-alt="project.name"
:img-size="size"
/>
<identicon
v-else
:entity-id="project.id"
:entity-name="project.name"
:size-class="sizeClass"
class="rect-avatar"
/>
</span>
</template>

View File

@ -1,81 +0,0 @@
<script>
/* This is a re-usable vue component for rendering a project avatar that
does not need to link to the project's profile. The image and an optional
tooltip can be configured by props passed to this component.
Sample configuration:
<project-avatar-image
:lazy="true"
:img-src="projectAvatarSrc"
:img-alt="tooltipText"
:tooltip-text="tooltipText"
tooltip-placement="top"
/>
*/
import defaultAvatarUrl from 'images/no_avatar.png';
import { __ } from '~/locale';
import { placeholderImage } from '../../../lazy_loader';
export default {
name: 'ProjectAvatarImage',
props: {
lazy: {
type: Boolean,
required: false,
default: false,
},
imgSrc: {
type: String,
required: false,
default: defaultAvatarUrl,
},
cssClasses: {
type: String,
required: false,
default: '',
},
imgAlt: {
type: String,
required: false,
default: __('project avatar'),
},
size: {
type: Number,
required: false,
default: 20,
},
},
computed: {
// API response sends null when gravatar is disabled and
// we provide an empty string when we use it inside project avatar link.
// In both cases we should render the defaultAvatarUrl
sanitizedSource() {
return this.imgSrc === '' || this.imgSrc === null ? defaultAvatarUrl : this.imgSrc;
},
resultantSrcAttribute() {
return this.lazy ? placeholderImage : this.sanitizedSource;
},
avatarSizeClass() {
return `s${this.size}`;
},
},
};
</script>
<template>
<img
:class="{
lazy: lazy,
[avatarSizeClass]: true,
[cssClasses]: true,
}"
:src="resultantSrcAttribute"
:width="size"
:height="size"
:alt="imgAlt"
:data-src="sanitizedSource"
class="avatar"
/>
</template>

View File

@ -1,35 +0,0 @@
<script>
import { getIdenticonBackgroundClass, getIdenticonTitle } from '~/helpers/avatar_helper';
export default {
props: {
entityId: {
type: [Number, String],
required: true,
},
entityName: {
type: String,
required: true,
},
sizeClass: {
type: String,
required: false,
default: 's40',
},
},
computed: {
identiconBackgroundClass() {
return getIdenticonBackgroundClass(this.entityId);
},
identiconTitle() {
return getIdenticonTitle(this.entityName);
},
},
};
</script>
<template>
<div ref="identicon" :class="[sizeClass, identiconBackgroundClass]" class="avatar identicon">
{{ identiconTitle }}
</div>
</template>

View File

@ -3,7 +3,7 @@ import { GlButton, GlIcon, GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
import { isString } from 'lodash'; import { isString } from 'lodash';
import highlight from '~/lib/utils/highlight'; import highlight from '~/lib/utils/highlight';
import { truncateNamespace } from '~/lib/utils/text_utility'; import { truncateNamespace } from '~/lib/utils/text_utility';
import ProjectAvatar from '~/vue_shared/components/deprecated_project_avatar/default.vue'; import ProjectAvatar from '~/vue_shared/components/project_avatar.vue';
export default { export default {
name: 'ProjectListItem', name: 'ProjectListItem',
@ -22,6 +22,9 @@ export default {
matcher: { type: String, required: false, default: '' }, matcher: { type: String, required: false, default: '' },
}, },
computed: { computed: {
projectAvatarUrl() {
return this.project.avatar_url || this.project.avatarUrl;
},
projectNameWithNamespace() { projectNameWithNamespace() {
return this.project.nameWithNamespace || this.project.name_with_namespace; return this.project.nameWithNamespace || this.project.name_with_namespace;
}, },
@ -49,7 +52,11 @@ export default {
class="gl-display-flex gl-align-items-center gl-flex-wrap project-namespace-name-container" class="gl-display-flex gl-align-items-center gl-flex-wrap project-namespace-name-container"
> >
<gl-icon v-if="selected" class="js-selected-icon" name="mobile-issue-close" /> <gl-icon v-if="selected" class="js-selected-icon" name="mobile-issue-close" />
<project-avatar class="gl-flex-shrink-0 js-project-avatar" :project="project" :size="32" /> <project-avatar
:project-avatar-url="projectAvatarUrl"
:project-name="projectNameWithNamespace"
class="gl-mr-3"
/>
<div <div
v-if="truncatedNamespace" v-if="truncatedNamespace"
:title="projectNameWithNamespace" :title="projectNameWithNamespace"

View File

@ -3,6 +3,7 @@
class Projects::StaticSiteEditorController < Projects::ApplicationController class Projects::StaticSiteEditorController < Projects::ApplicationController
include ExtractsPath include ExtractsPath
include CreatesCommit include CreatesCommit
include BlobHelper
layout 'fullscreen' layout 'fullscreen'
@ -24,28 +25,7 @@ class Projects::StaticSiteEditorController < Projects::ApplicationController
end end
def show def show
service_response = ::StaticSiteEditor::ConfigService.new( redirect_to ide_edit_path(project, @ref, @path)
container: project,
current_user: current_user,
params: {
ref: @ref,
path: @path,
return_url: params[:return_url]
}
).execute
if service_response.success?
Gitlab::UsageDataCounters::StaticSiteEditorCounter.increment_views_count
@data = serialize_necessary_payload_values_to_json(service_response.payload)
else
# TODO: For now, if the service returns any error, the user is redirected
# to the root project page with the error message displayed as an alert.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/213285#note_414808004
# for discussion of plans to handle this via a page owned by the Static Site Editor.
flash[:alert] = service_response.message
redirect_to project_path(project)
end
end end
private private

View File

@ -576,7 +576,6 @@ severities
sharded sharded
sharding sharding
shfmt shfmt
Shibboleth
Shimo Shimo
Shopify Shopify
Sidekiq Sidekiq

View File

@ -31,7 +31,6 @@ providers:
- [Salesforce](../../integration/salesforce.md) - [Salesforce](../../integration/salesforce.md)
- [SAML](../../integration/saml.md) - [SAML](../../integration/saml.md)
- [SAML for GitLab.com groups](../../user/group/saml_sso/index.md) **(PREMIUM SAAS)** - [SAML for GitLab.com groups](../../user/group/saml_sso/index.md) **(PREMIUM SAAS)**
- [Shibboleth](../../integration/saml.md)
- [Smartcard](smartcard.md) **(PREMIUM SELF)** - [Smartcard](smartcard.md) **(PREMIUM SELF)**
- [Twitter](../../integration/twitter.md) - [Twitter](../../integration/twitter.md)

View File

@ -300,7 +300,7 @@ disable enforcement. For more information, see the documentation on configuring
```toml ```toml
listen_addr = '0.0.0.0:8075' listen_addr = '0.0.0.0:8075'
runtime_dir = '/var/opt/gitlab/gitaly' internal_socket_dir = '/var/opt/gitlab/gitaly'
[logging] [logging]
format = 'json' format = 'json'
@ -308,9 +308,6 @@ disable enforcement. For more information, see the documentation on configuring
dir = '/var/log/gitaly' dir = '/var/log/gitaly'
``` ```
For GitLab 14.9 and earlier, set `internal_socket_dir = '/var/opt/gitlab/gitaly'` instead
of `runtime_dir`.
1. Append the following to `/home/git/gitaly/config.toml` for each respective Gitaly server: 1. Append the following to `/home/git/gitaly/config.toml` for each respective Gitaly server:
On `gitaly1.internal`: On `gitaly1.internal`:

View File

@ -332,7 +332,7 @@ PUT --form "paused=true" /runners/:runner_id
# --or-- # --or--
# Deprecated: removal planned in 15.0 # Deprecated: removal planned in 16.0
PUT --form "active=false" /runners/:runner_id PUT --form "active=false" /runners/:runner_id
``` ```
@ -346,7 +346,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" \
# --or-- # --or--
# Deprecated: removal planned in 15.0 # Deprecated: removal planned in 16.0
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" \ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" \
--form "active=false" "https://gitlab.example.com/api/v4/runners/6" --form "active=false" "https://gitlab.example.com/api/v4/runners/6"
``` ```

View File

@ -1121,7 +1121,7 @@ host localhost # Give your setup a name (here: override localhost)
hostname 127.0.0.1; # Your server name or IP hostname 127.0.0.1; # Your server name or IP
``` ```
You also need to change the corresponding options (for example, `ssh_user`, `ssh_host`, `admin_uri`) in the `config\gitlab.yml` file. You also need to change the corresponding options (for example, `ssh_user`, `ssh_host`, `admin_uri`) in the `config/gitlab.yml` file.
### Additional Markup Styles ### Additional Markup Styles

View File

@ -24,8 +24,8 @@ GitLab can be configured to authenticate access requests with the following auth
- Integrate with [Kerberos](kerberos.md). - Integrate with [Kerberos](kerberos.md).
- Enable sign in via [LDAP](../administration/auth/ldap/index.md). - Enable sign in via [LDAP](../administration/auth/ldap/index.md).
- Enable [OAuth2 provider](oauth_provider.md) application creation. - Enable [OAuth2 provider](oauth_provider.md) application creation.
- Use [OmniAuth](omniauth.md) to enable sign in via Twitter, GitHub, GitLab.com, Google, - Use [OmniAuth](omniauth.md) to enable sign in through Twitter, GitHub, GitLab.com, Google,
Bitbucket, Facebook, Shibboleth, SAML, Crowd, Azure, or Authentiq ID. Bitbucket, Facebook, SAML, Crowd, Azure, or Authentiq ID.
- Use GitLab as an [OpenID Connect](openid_connect_provider.md) identity provider. - Use GitLab as an [OpenID Connect](openid_connect_provider.md) identity provider.
- Authenticate to [Vault](vault.md) through GitLab OpenID Connect. - Authenticate to [Vault](vault.md) through GitLab OpenID Connect.
- Configure GitLab as a [SAML](saml.md) 2.0 Service Provider. - Configure GitLab as a [SAML](saml.md) 2.0 Service Provider.

View File

@ -41,7 +41,6 @@ GitLab supports the following OmniAuth providers.
| [OpenID Connect](../administration/auth/oidc.md) | `openid_connect` | | [OpenID Connect](../administration/auth/oidc.md) | `openid_connect` |
| [Salesforce](salesforce.md) | `salesforce` | | [Salesforce](salesforce.md) | `salesforce` |
| [SAML](saml.md) | `saml` | | [SAML](saml.md) | `saml` |
| [Shibboleth](saml.md) | `shibboleth` |
| [Twitter](twitter.md) | `twitter` | | [Twitter](twitter.md) | `twitter` |
## Configure initial settings ## Configure initial settings
@ -53,7 +52,7 @@ Setting | Description | Default value
---------------------------|-------------|-------------- ---------------------------|-------------|--------------
`allow_single_sign_on` | Enables you to list the providers that automatically create a GitLab account. The provider names are available in the **OmniAuth provider name** column in the [supported providers table](#supported-providers). | The default is `false`. If `false`, users must be created manually, or they can't sign in using OmniAuth. `allow_single_sign_on` | Enables you to list the providers that automatically create a GitLab account. The provider names are available in the **OmniAuth provider name** column in the [supported providers table](#supported-providers). | The default is `false`. If `false`, users must be created manually, or they can't sign in using OmniAuth.
`auto_link_ldap_user` | If enabled, creates an LDAP identity in GitLab for users that are created through an OmniAuth provider. You can enable this setting if you have the [LDAP (ActiveDirectory)](../administration/auth/ldap/index.md) integration enabled. Requires the `uid` of the user to be the same in both LDAP and the OmniAuth provider. | The default is `false`. `auto_link_ldap_user` | If enabled, creates an LDAP identity in GitLab for users that are created through an OmniAuth provider. You can enable this setting if you have the [LDAP (ActiveDirectory)](../administration/auth/ldap/index.md) integration enabled. Requires the `uid` of the user to be the same in both LDAP and the OmniAuth provider. | The default is `false`.
`block_auto_created_users` | If enabled, blocks users that are automatically created from signing in until they are approved by an administrator. | The default is `true`. If you set the value to `false`, make sure you only define providers for `allow_single_sign_on` that you can control, like SAML, Shibboleth, Crowd, or Google. Otherwise, any user on the internet can sign in to GitLab without an administrator's approval. `block_auto_created_users` | If enabled, blocks users that are automatically created from signing in until they are approved by an administrator. | The default is `true`. If you set the value to `false`, make sure you only define providers for `allow_single_sign_on` that you can control, like SAML, Crowd, or Google. Otherwise, any user on the internet can sign in to GitLab without an administrator's approval.
To change these settings: To change these settings:

View File

@ -91,7 +91,8 @@ To view a list of merge requests that need your attention:
1. On the top bar, select **Merge requests** (**{merge-request}**). 1. On the top bar, select **Merge requests** (**{merge-request}**).
1. Select **Attention requests**. 1. Select **Attention requests**.
To request attention from another user: To request attention from another user, use the `/attention @user`
[quick action](../quick_actions.md) or:
1. Go to the merge request. 1. Go to the merge request.
1. On the right sidebar, identify the user you want to request attention from. 1. On the right sidebar, identify the user you want to request attention from.

View File

@ -55,6 +55,7 @@ threads. Some quick actions might not be available to all subscription tiers.
| `/assign me` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Assign yourself. | | `/assign me` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Assign yourself. |
| `/assign_reviewer @user1 @user2` or `/reviewer @user1 @user2` or `/request_review @user1 @user2` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Assign one or more users as reviewers. | | `/assign_reviewer @user1 @user2` or `/reviewer @user1 @user2` or `/request_review @user1 @user2` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Assign one or more users as reviewers. |
| `/assign_reviewer me` or `/reviewer me` or `/request_review me` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Assign yourself as a reviewer. | | `/assign_reviewer me` or `/reviewer me` or `/request_review me` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Assign yourself as a reviewer. |
| `/attention @user1` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | [Request attention](merge_requests/index.md#request-attention-to-a-merge-request) to a merge request from a user. |
| `/award :emoji:` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Toggle emoji award. | | `/award :emoji:` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Toggle emoji award. |
| `/child_epic <epic>` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Add child epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7330) in GitLab 12.0). | | `/child_epic <epic>` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Add child epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7330) in GitLab 12.0). |
| `/clear_health_status` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Clear [health status](issues/managing_issues.md#health-status) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213814) in GitLab 14.7). | | `/clear_health_status` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Clear [health status](issues/managing_issues.md#health-status) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213814) in GitLab 14.7). |

View File

@ -124,9 +124,9 @@ module Gitlab
config[:storage] = storages config[:storage] = storages
runtime_dir = options[:runtime_dir] || File.join(gitaly_dir, 'run') internal_socket_dir = options[:internal_socket_dir] || File.join(gitaly_dir, 'internal_sockets')
FileUtils.mkdir(runtime_dir) unless File.exist?(runtime_dir) FileUtils.mkdir(internal_socket_dir) unless File.exist?(internal_socket_dir)
config[:runtime_dir] = runtime_dir config[:internal_socket_dir] = internal_socket_dir
config[:'gitaly-ruby'] = { dir: File.join(gitaly_dir, 'ruby') } if gitaly_ruby config[:'gitaly-ruby'] = { dir: File.join(gitaly_dir, 'ruby') } if gitaly_ruby
config[:'gitlab-shell'] = { dir: Gitlab.config.gitlab_shell.path } config[:'gitlab-shell'] = { dir: Gitlab.config.gitlab_shell.path }

View File

@ -45052,9 +45052,6 @@ msgstr ""
msgid "project access tokens" msgid "project access tokens"
msgstr "" msgstr ""
msgid "project avatar"
msgstr ""
msgid "project bots cannot be added to other groups / projects" msgid "project bots cannot be added to other groups / projects"
msgstr "" msgstr ""

View File

@ -81,6 +81,7 @@ module QA
return puts "\nNothing to download!" if files_list.empty? return puts "\nNothing to download!" if files_list.empty?
FileUtils.mkdir_p('tmp/')
files_list.each do |file_name| files_list.each do |file_name|
local_path = "tmp/#{file_name.split('/').last}" local_path = "tmp/#{file_name.split('/').last}"
Runtime::Logger.info("Downloading #{file_name} to #{local_path}") Runtime::Logger.info("Downloading #{file_name} to #{local_path}")

View File

@ -76,12 +76,11 @@ RSpec.describe Projects::StaticSiteEditorController do
get :show, params: default_params get :show, params: default_params
end end
it 'increases the views counter' do it 'redirects to the Web IDE' do
expect(Gitlab::UsageDataCounters::StaticSiteEditorCounter).to have_received(:increment_views_count) get :show, params: default_params
end
it 'renders the edit page' do expected_path_regex = %r[-/ide/project/#{project.full_path}/edit/master/-/README.md]
expect(response).to render_template(:show) expect(response).to redirect_to(expected_path_regex)
end end
it 'assigns ref and path variables' do it 'assigns ref and path variables' do
@ -96,62 +95,6 @@ RSpec.describe Projects::StaticSiteEditorController do
expect(response).to have_gitlab_http_status(:not_found) expect(response).to have_gitlab_http_status(:not_found)
end end
end end
context 'when invalid config file' do
let(:service_response) { ServiceResponse.error(message: 'invalid') }
it 'redirects to project page and flashes error message' do
expect(response).to redirect_to(project_path(project))
expect(controller).to set_flash[:alert].to('invalid')
end
end
context 'with a service response payload containing multiple data types' do
let(:data) do
{
a_string: 'string',
an_array: [
{
foo: 'bar'
}
],
an_integer: 123,
a_hash: {
a_deeper_hash: {
foo: 'bar'
}
},
a_boolean: true,
a_nil: nil
}
end
let(:assigns_data) { assigns(:data) }
it 'leaves data values which are strings as strings' do
expect(assigns_data[:a_string]).to eq('string')
end
it 'leaves data values which are integers as integers' do
expect(assigns_data[:an_integer]).to eq(123)
end
it 'serializes data values which are booleans to JSON' do
expect(assigns_data[:a_boolean]).to eq('true')
end
it 'serializes data values which are arrays to JSON' do
expect(assigns_data[:an_array]).to eq('[{"foo":"bar"}]')
end
it 'serializes data values which are hashes to JSON' do
expect(assigns_data[:a_hash]).to eq('{"a_deeper_hash":{"foo":"bar"}}')
end
it 'serializes data values which are nil to an empty string' do
expect(assigns_data[:a_nil]).to eq('')
end
end
end end
end end
end end

View File

@ -1,113 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Static Site Editor' do
include ContentSecurityPolicyHelpers
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
let(:sse_path) { project_show_sse_path(project, 'master/README.md') }
before_all do
project.add_developer(user)
end
before do
sign_in(user)
end
context "when no config file is present" do
before do
visit sse_path
end
it 'renders SSE page with all generated config values and default config file values' do
node = page.find('#static-site-editor')
# assert generated config values are present
expect(node['data-base-url']).to eq("/#{project.full_path}/-/sse/master%2FREADME.md")
expect(node['data-branch']).to eq('master')
expect(node['data-commit-id']).to match(/\A[0-9a-f]{40}\z/)
expect(node['data-is-supported-content']).to eq('true')
expect(node['data-merge-requests-illustration-path'])
.to match(%r{/assets/illustrations/merge_requests-.*\.svg})
expect(node['data-namespace']).to eq(project.namespace.full_path)
expect(node['data-project']).to eq(project.path)
expect(node['data-project-id']).to eq(project.id.to_s)
# assert default config file values are present
expect(node['data-image-upload-path']).to eq('source/images')
expect(node['data-mounts']).to eq('[{"source":"source","target":""}]')
expect(node['data-static-site-generator']).to eq('middleman')
end
end
context "when a config file is present" do
let(:config_file_yml) do
<<~YAML
image_upload_path: custom-image-upload-path
mounts:
- source: source1
target: ""
- source: source2
target: target2
static_site_generator: middleman
YAML
end
before do
allow_next_instance_of(Repository) do |repository|
allow(repository).to receive(:blob_data_at).and_return(config_file_yml)
end
visit sse_path
end
it 'renders Static Site Editor page values read from config file' do
node = page.find('#static-site-editor')
# assert user-specified config file values are present
expected_mounts = '[{"source":"source1","target":""},{"source":"source2","target":"target2"}]'
expect(node['data-image-upload-path']).to eq('custom-image-upload-path')
expect(node['data-mounts']).to eq(expected_mounts)
expect(node['data-static-site-generator']).to eq('middleman')
end
end
describe 'Static Site Editor Content Security Policy' do
subject { response_headers['Content-Security-Policy'] }
context 'when no global CSP config exists' do
before do
setup_csp_for_controller(Projects::StaticSiteEditorController)
end
it 'does not add CSP directives' do
visit sse_path
is_expected.to be_blank
end
end
context 'when a global CSP config exists' do
let_it_be(:cdn_url) { 'https://some-cdn.test' }
let_it_be(:youtube_url) { 'https://www.youtube.com' }
before do
csp = ActionDispatch::ContentSecurityPolicy.new do |p|
p.frame_src :self, cdn_url
end
setup_existing_csp_for_controller(Projects::StaticSiteEditorController, csp)
end
it 'appends youtube to the CSP frame-src policy' do
visit sse_path
is_expected.to eql("frame-src 'self' #{cdn_url} #{youtube_url}")
end
end
end
end

View File

@ -1,21 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Identicon entity id is a GraphQL id matches snapshot 1`] = `
<div
class="avatar identicon s40 bg2"
>
E
</div>
`;
exports[`Identicon entity id is a number matches snapshot 1`] = `
<div
class="avatar identicon s40 bg2"
>
E
</div>
`;

View File

@ -1,50 +0,0 @@
import { shallowMount } from '@vue/test-utils';
import IdenticonComponent from '~/vue_shared/components/identicon.vue';
describe('Identicon', () => {
let wrapper;
const defaultProps = {
entityId: 1,
entityName: 'entity-name',
sizeClass: 's40',
};
const createComponent = (props = {}) => {
wrapper = shallowMount(IdenticonComponent, {
propsData: {
...defaultProps,
...props,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('entity id is a number', () => {
beforeEach(() => createComponent());
it('matches snapshot', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('adds a correct class to identicon', () => {
expect(wrapper.find({ ref: 'identicon' }).classes()).toContain('bg2');
});
});
describe('entity id is a GraphQL id', () => {
beforeEach(() => createComponent({ entityId: 'gid://gitlab/Project/8' }));
it('matches snapshot', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('adds a correct class to identicon', () => {
expect(wrapper.find({ ref: 'identicon' }).classes()).toContain('bg2');
});
});
});

View File

@ -1,50 +0,0 @@
import Vue, { nextTick } from 'vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import { projectData } from 'jest/ide/mock_data';
import { TEST_HOST } from 'spec/test_constants';
import { getFirstCharacterCapitalized } from '~/lib/utils/text_utility';
import ProjectAvatarDefault from '~/vue_shared/components/deprecated_project_avatar/default.vue';
describe('ProjectAvatarDefault component', () => {
const Component = Vue.extend(ProjectAvatarDefault);
let vm;
beforeEach(() => {
vm = mountComponent(Component, {
project: projectData,
});
});
afterEach(() => {
vm.$destroy();
});
it('renders identicon if project has no avatar_url', async () => {
const expectedText = getFirstCharacterCapitalized(projectData.name);
vm.project = {
...vm.project,
avatar_url: null,
};
await nextTick();
const identiconEl = vm.$el.querySelector('.identicon');
expect(identiconEl).not.toBe(null);
expect(identiconEl.textContent.trim()).toEqual(expectedText);
});
it('renders avatar image if project has avatar_url', async () => {
const avatarUrl = `${TEST_HOST}/images/home/nasa.svg`;
vm.project = {
...vm.project,
avatar_url: avatarUrl,
};
await nextTick();
expect(vm.$el.querySelector('.avatar')).not.toBeNull();
expect(vm.$el.querySelector('.identicon')).toBeNull();
expect(vm.$el.querySelector('img')).toHaveAttr('src', avatarUrl);
});
});

View File

@ -2,7 +2,7 @@ import { shallowMount } from '@vue/test-utils';
import Vue from 'vue'; import Vue from 'vue';
import mockProjects from 'test_fixtures_static/projects.json'; import mockProjects from 'test_fixtures_static/projects.json';
import { trimText } from 'helpers/text_helper'; import { trimText } from 'helpers/text_helper';
import ProjectAvatar from '~/vue_shared/components/deprecated_project_avatar/default.vue'; import ProjectAvatar from '~/vue_shared/components/project_avatar.vue';
import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue'; import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue';
describe('ProjectListItem component', () => { describe('ProjectListItem component', () => {
@ -52,8 +52,13 @@ describe('ProjectListItem component', () => {
it(`renders the project avatar`, () => { it(`renders the project avatar`, () => {
wrapper = shallowMount(Component, options); wrapper = shallowMount(Component, options);
const avatar = wrapper.findComponent(ProjectAvatar);
expect(wrapper.findComponent(ProjectAvatar).exists()).toBe(true); expect(avatar.exists()).toBe(true);
expect(avatar.props()).toMatchObject({
projectAvatarUrl: '',
projectName: project.name_with_namespace,
});
}); });
it(`renders a simple namespace name with a trailing slash`, () => { it(`renders a simple namespace name with a trailing slash`, () => {

View File

@ -267,7 +267,7 @@ module GitalySetup
{ 'default' => repos_path }, { 'default' => repos_path },
force: true, force: true,
options: { options: {
runtime_dir: File.join(gitaly_dir, "run2"), internal_socket_dir: File.join(gitaly_dir, "internal_gitaly2"),
gitaly_socket: "gitaly2.socket", gitaly_socket: "gitaly2.socket",
config_filename: "gitaly2.config.toml" config_filename: "gitaly2.config.toml"
} }