Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-11-08 00:24:56 +00:00
parent b40ff326b9
commit c7c4e203a0
36 changed files with 325 additions and 87 deletions

View File

@ -260,7 +260,7 @@ gem 'rouge', '~> 4.4.0', feature_category: :shared
gem 'truncato', '~> 0.7.12', feature_category: :team_planning
gem 'nokogiri', '~> 1.16', feature_category: :shared
gem 'gitlab-glfm-markdown', '~> 0.0.21', feature_category: :markdown
gem 'tanuki_emoji', '~> 0.9', feature_category: :markdown
gem 'tanuki_emoji', '~> 0.13', feature_category: :markdown
gem 'unicode-emoji', '~> 3.6', feature_category: :markdown
# Calendar rendering
@ -380,7 +380,6 @@ gem 'addressable', '~> 2.8' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'gon', '~> 6.4.0' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'request_store', '~> 1.5.1' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'base32', '~> 0.3.0' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'gitlab-license', '~> 2.5', feature_category: :shared
# Protect against bruteforcing

View File

@ -704,7 +704,7 @@
{"name":"sys-filesystem","version":"1.4.3","platform":"ruby","checksum":"390919de89822ad6d3ba3daf694d720be9d83ed95cdf7adf54d4573c98b17421"},
{"name":"sysexits","version":"1.2.0","platform":"ruby","checksum":"598241c4ae57baa403c125182dfdcc0d1ac4c0fb606dd47fbed57e4aaf795662"},
{"name":"table_print","version":"1.5.7","platform":"ruby","checksum":"436664281f93387b882335795e16cfeeb839ad0c785ff7f9110fc0f17c68b5cb"},
{"name":"tanuki_emoji","version":"0.9.0","platform":"ruby","checksum":"009f0b283f61b7aed5f57d7d1f050225f2a5df8eec121550a67bdd7b95c74056"},
{"name":"tanuki_emoji","version":"0.13.0","platform":"ruby","checksum":"dee2182a5cad6f88ed91cd4e39088bd2a8f313e24f83ff5d4b5b0fecf29f6d93"},
{"name":"telesign","version":"2.2.4","platform":"ruby","checksum":"dcc6e96ea7bcb4da1e2ae786bfe7a4d670a4b5f94ae95dfcdde77d547c544c42"},
{"name":"telesignenterprise","version":"2.2.2","platform":"ruby","checksum":"f147a03263a8c2fe0a0db1a7a9454a6ee37d9e8abd58eaca305bdd8081f9f1b3"},
{"name":"temple","version":"0.8.2","platform":"ruby","checksum":"c12071214346c606dbd219b4117276d04a9f2c20d65e66a66b2c4ec18efc1f18"},

View File

@ -1801,7 +1801,8 @@ GEM
ffi (~> 1.1)
sysexits (1.2.0)
table_print (1.5.7)
tanuki_emoji (0.9.0)
tanuki_emoji (0.13.0)
i18n (~> 1.14)
telesign (2.2.4)
net-http-persistent (>= 3.0.0, < 5.0)
telesignenterprise (2.2.2)
@ -2296,7 +2297,7 @@ DEPENDENCIES
stackprof (~> 0.2.26)
state_machines-activerecord (~> 0.8.0)
sys-filesystem (~> 1.4.3)
tanuki_emoji (~> 0.9)
tanuki_emoji (~> 0.13)
telesignenterprise (~> 2.2)
terser (= 1.0.2)
test-prof (~> 1.4.0)

View File

@ -719,7 +719,7 @@
{"name":"sys-filesystem","version":"1.4.3","platform":"ruby","checksum":"390919de89822ad6d3ba3daf694d720be9d83ed95cdf7adf54d4573c98b17421"},
{"name":"sysexits","version":"1.2.0","platform":"ruby","checksum":"598241c4ae57baa403c125182dfdcc0d1ac4c0fb606dd47fbed57e4aaf795662"},
{"name":"table_print","version":"1.5.7","platform":"ruby","checksum":"436664281f93387b882335795e16cfeeb839ad0c785ff7f9110fc0f17c68b5cb"},
{"name":"tanuki_emoji","version":"0.9.0","platform":"ruby","checksum":"009f0b283f61b7aed5f57d7d1f050225f2a5df8eec121550a67bdd7b95c74056"},
{"name":"tanuki_emoji","version":"0.13.0","platform":"ruby","checksum":"dee2182a5cad6f88ed91cd4e39088bd2a8f313e24f83ff5d4b5b0fecf29f6d93"},
{"name":"telesign","version":"2.2.4","platform":"ruby","checksum":"dcc6e96ea7bcb4da1e2ae786bfe7a4d670a4b5f94ae95dfcdde77d547c544c42"},
{"name":"telesignenterprise","version":"2.2.2","platform":"ruby","checksum":"f147a03263a8c2fe0a0db1a7a9454a6ee37d9e8abd58eaca305bdd8081f9f1b3"},
{"name":"temple","version":"0.8.2","platform":"ruby","checksum":"c12071214346c606dbd219b4117276d04a9f2c20d65e66a66b2c4ec18efc1f18"},

View File

@ -1828,7 +1828,8 @@ GEM
ffi (~> 1.1)
sysexits (1.2.0)
table_print (1.5.7)
tanuki_emoji (0.9.0)
tanuki_emoji (0.13.0)
i18n (~> 1.14)
telesign (2.2.4)
net-http-persistent (>= 3.0.0, < 5.0)
telesignenterprise (2.2.2)
@ -2323,7 +2324,7 @@ DEPENDENCIES
stackprof (~> 0.2.26)
state_machines-activerecord (~> 0.8.0)
sys-filesystem (~> 1.4.3)
tanuki_emoji (~> 0.9)
tanuki_emoji (~> 0.13)
telesignenterprise (~> 2.2)
terser (= 1.0.2)
test-prof (~> 1.4.0)

View File

@ -1,8 +1,9 @@
---
migration_job_name: BackfillDesignManagementVersionsNamespaceId
description: Backfills sharding key `design_management_versions.namespace_id` from `issues`.
description: Backfills sharding key `design_management_versions.namespace_id` from
`issues`.
feature_category: design_management
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154281
milestone: '17.1'
queued_migration_version: 20240530121656
finalized_by: # version of the migration that finalized this BBM
finalized_by: '20241105232559'

View File

@ -0,0 +1,12 @@
---
table_name: subscription_user_add_on_assignment_versions
description: Stores user add-on assignment versioning data
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/169180
milestone: '17.6'
feature_categories:
- subscription_management
classes:
- GitlabSubscriptions::UserAddOnAssignmentVersion
gitlab_schema: gitlab_main_cell
sharding_key:
organization_id: organizations

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
class CreateUserAddOnAssignmentVersions < Gitlab::Database::Migration[2.2]
milestone '17.6'
def change
create_table :subscription_user_add_on_assignment_versions do |t| # rubocop:disable Migration/EnsureFactoryForTable -- No factory needed
t.references :organization,
foreign_key: true,
null: false,
index: { name: 'idx_user_add_on_assignment_versions_on_organization_id' }
t.bigint :item_id
t.bigint :purchase_id
t.bigint :user_id
t.datetime_with_timezone :created_at
t.text :item_type, null: false, limit: 255
t.text :event, null: false, limit: 255
t.text :namespace_path, limit: 255
t.text :add_on_name, limit: 255
t.text :whodunnit, limit: 255
t.jsonb :object
t.index :item_id, name: 'idx_user_add_on_assignment_versions_on_item_id'
end
end
end

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
class FinalizeBackfillDesignManagementVersionsNamespaceId < Gitlab::Database::Migration[2.2]
milestone '17.6'
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
def up
ensure_batched_background_migration_is_finished(
job_class_name: 'BackfillDesignManagementVersionsNamespaceId',
table_name: :design_management_versions,
column_name: :id,
job_arguments: [:namespace_id, :issues, :namespace_id, :issue_id],
finalize: true
)
end
def down; end
end

View File

@ -0,0 +1 @@
b798beb93f31b748dfb0bcc50528e45054288339ab713f2b8cebb9845b3eafcf

View File

@ -0,0 +1 @@
2de004a9d362510d745076d491485c5304683f09bb5e74075093a24bdeb36b71

View File

@ -19798,6 +19798,35 @@ CREATE SEQUENCE subscription_seat_assignments_id_seq
ALTER SEQUENCE subscription_seat_assignments_id_seq OWNED BY subscription_seat_assignments.id;
CREATE TABLE subscription_user_add_on_assignment_versions (
id bigint NOT NULL,
organization_id bigint NOT NULL,
item_id bigint,
purchase_id bigint,
user_id bigint,
created_at timestamp with time zone,
item_type text NOT NULL,
event text NOT NULL,
namespace_path text,
add_on_name text,
whodunnit text,
object jsonb,
CONSTRAINT check_211bad6d65 CHECK ((char_length(item_type) <= 255)),
CONSTRAINT check_34ca72be24 CHECK ((char_length(event) <= 255)),
CONSTRAINT check_839913a25d CHECK ((char_length(namespace_path) <= 255)),
CONSTRAINT check_9ceaa5668c CHECK ((char_length(add_on_name) <= 255)),
CONSTRAINT check_e185bf0c82 CHECK ((char_length(whodunnit) <= 255))
);
CREATE SEQUENCE subscription_user_add_on_assignment_versions_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE subscription_user_add_on_assignment_versions_id_seq OWNED BY subscription_user_add_on_assignment_versions.id;
CREATE TABLE subscription_user_add_on_assignments (
id bigint NOT NULL,
add_on_purchase_id bigint NOT NULL,
@ -23606,6 +23635,8 @@ ALTER TABLE ONLY subscription_add_ons ALTER COLUMN id SET DEFAULT nextval('subsc
ALTER TABLE ONLY subscription_seat_assignments ALTER COLUMN id SET DEFAULT nextval('subscription_seat_assignments_id_seq'::regclass);
ALTER TABLE ONLY subscription_user_add_on_assignment_versions ALTER COLUMN id SET DEFAULT nextval('subscription_user_add_on_assignment_versions_id_seq'::regclass);
ALTER TABLE ONLY subscription_user_add_on_assignments ALTER COLUMN id SET DEFAULT nextval('subscription_user_add_on_assignments_id_seq'::regclass);
ALTER TABLE ONLY subscriptions ALTER COLUMN id SET DEFAULT nextval('subscriptions_id_seq'::regclass);
@ -26348,6 +26379,9 @@ ALTER TABLE ONLY subscription_add_ons
ALTER TABLE ONLY subscription_seat_assignments
ADD CONSTRAINT subscription_seat_assignments_pkey PRIMARY KEY (id);
ALTER TABLE ONLY subscription_user_add_on_assignment_versions
ADD CONSTRAINT subscription_user_add_on_assignment_versions_pkey PRIMARY KEY (id);
ALTER TABLE ONLY subscription_user_add_on_assignments
ADD CONSTRAINT subscription_user_add_on_assignments_pkey PRIMARY KEY (id);
@ -28309,6 +28343,10 @@ CREATE UNIQUE INDEX idx_uniq_analytics_dashboards_pointers_on_project_id ON anal
CREATE UNIQUE INDEX idx_usages_on_cmpt_used_by_project_cmpt_and_last_used_date ON catalog_resource_component_last_usages USING btree (component_id, used_by_project_id, last_used_date);
CREATE INDEX idx_user_add_on_assignment_versions_on_item_id ON subscription_user_add_on_assignment_versions USING btree (item_id);
CREATE INDEX idx_user_add_on_assignment_versions_on_organization_id ON subscription_user_add_on_assignment_versions USING btree (organization_id);
CREATE INDEX idx_user_add_on_assignments_on_add_on_purchase_id_and_id ON subscription_user_add_on_assignments USING btree (add_on_purchase_id, id);
CREATE INDEX idx_user_audit_events_on_author_id_created_at_id ON ONLY user_audit_events USING btree (author_id, created_at, id);
@ -36686,6 +36724,9 @@ ALTER TABLE ONLY issue_assignment_events
ALTER TABLE ONLY security_policies
ADD CONSTRAINT fk_rails_08722e8ac7 FOREIGN KEY (security_policy_management_project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY subscription_user_add_on_assignment_versions
ADD CONSTRAINT fk_rails_091e013a61 FOREIGN KEY (organization_id) REFERENCES organizations(id);
ALTER TABLE ONLY trending_projects
ADD CONSTRAINT fk_rails_09feecd872 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;

View File

@ -218,9 +218,10 @@ Same as when column is dropped, after the rename is completed, we need to [remov
## Changing column constraints
Adding or removing a `NOT NULL` clause (or another constraint) can typically be
done without requiring downtime. However, this does require that any application
changes are deployed _first_. Thus, changing the constraints of a column should
happen in a post-deployment migration.
done without requiring downtime. Adding a `NOT NULL` contraint requires that any application
changes are deployed _first_, so it should happen in a post-deployment migration.
In contrary removing a `NOT NULL` contraint should be done in a regular migration.
This way any code which insers `NULL` values can safely run for the column.
Avoid using `change_column` as it produces an inefficient query because it re-defines
the whole column type.

View File

@ -179,7 +179,17 @@ Executor.
If you would like to start Duo Workflow with the VS Code extension instead,
follow [these steps](../../user/duo_workflow/index.md#prerequisites).
If you are debugging or making changes to the VSCode extension and need to run the extension in development mode, you can do that following [these instructions](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main/CONTRIBUTING.md#configuring-development-environment).
If you would like to start Duo Workflow with a locally running VS Code extension and GitLab Language Server (for debugging or making changes to the extension)
1. Clone [language server](https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp).
1. Clone [VSCode extension](https://gitlab.com/gitlab-org/gitlab-vscode-extension).
1. Change directory (`cd`) into language server.
1. Run `npm install`.
1. Run `npm run watch -- --editor=vscode --packages webview-duo-workflow workflow-api --vscode-path path-to-vscode-extension-from-step-2`.
1. Open VSCode extension project in VSCode.
1. Click **Run and Debug**, choose **Run Extension** in the dropdown and select **Play**.
1. If prompted with **All installed extensions are temporarily disabled**, do not click **Reload and Enable extensions** because that will use native extensions.
1. In the command palette, run `GitLab: Show Duo Workflow`.
## Troubleshooting

View File

@ -14,17 +14,22 @@ NOTE:
## How to update Emojis
1. Update the [`tanuki_emoji`](https://gitlab.com/gitlab-org/ruby/gems/tanuki_emoji) gem.
1. Update `fixtures/emojis/index.json` from [Gemojione](https://github.com/bonusly/gemojione/blob/master/config/index.json).
In the future, we could grab the file directly from the gem.
We should probably make a PR on the Gemojione project to get access to
all emojis after being parsed or just a raw path to the `json` file itself.
1. Ensure [`emoji-unicode-version`](https://www.npmjs.com/package/emoji-unicode-version)
is up to date with the latest version.
1. Use the [`tanuki_emoji`](https://gitlab.com/gitlab-org/ruby/gems/tanuki_emoji) gem's [Rake tasks](../rake_tasks.md) to update aliases, digests, and sprites:
1. Run `bundle exec rake tanuki_emoji:aliases`
1. Run `bundle exec rake tanuki_emoji:digests`
1. Run `bundle exec rake tanuki_emoji:sprite`
1. Ensure new sprite sheets generated for 1x and 2x
1. Update `EMOJI_VERSION` in `lib/gitlab/emoji.rb`
1. Update `EMOJI_VERSION` in `app/assets/javascripts/emoji/index.js`
1. Use the [`tanuki_emoji`](https://gitlab.com/gitlab-org/ruby/gems/tanuki_emoji) gem's [Rake tasks](../rake_tasks.md) to update aliases, fallback images, digests, and sprites. Run in the following order:
1. `bundle exec rake tanuki_emoji:aliases` - updates `fixtures/emojis/aliases.json`
1. `bundle exec rake tanuki_emoji:import` - imports all the images into `public/-/emojis` directory
1. `bundle exec rake tanuki_emoji:digests` - updates `public/-/emojis/VERSION/emojis.json` and `fixtures/emojis/digests.json`
1. `bundle exec rake tanuki_emoji:sprite` - creates new sprite sheets
If new emoji are added, the sprite sheet may change size. To compensate for
such changes, first generate the `app/assets/images/emoji.png` sprite sheet with the above Rake
task, then check the dimensions of the new sprite sheet and update the
`SPRITESHEET_WIDTH` and `SPRITESHEET_HEIGHT` constants in `lib/tasks/tanuki_emoji.rake` accordingly.
Then re-run the task.
- Use [ImageOptim](https://imageoptim.com) or similar program to optimize the images for size
1. Ensure new sprite sheets were generated for 1x and 2x
- `app/assets/images/emoji.png`
- `app/assets/images/emoji@2x.png`
1. Update `fixtures/emojis/intents.json` with any new emoji that we would like to highlight as having positive or negative intent.
@ -38,3 +43,10 @@ NOTE:
that do not support a certain emoji and we need to fallback to an image.
See `app/assets/javascripts/emoji/support/is_emoji_unicode_supported.js`
and `app/assets/javascripts/emoji/support/unicode_support_map.js`
- if a new version of Unicode emojis is being added, update the list in `app/assets/javascripts/emoji/support/unicode_support_map.js`
1. Ensure you use the version of [emoji-regex](https://github.com/mathiasbynens/emoji-regex) that corresponds
to the version of Unicode that is being supported. This should be updated in `package.json`. Used for
filtering emojis in `app/assets/javascripts/emoji/index.js`.
1. Have there been any changes to the category names? If so then `app/assets/javascripts/emoji/constants.js`
will need to be updated
1. See an [example MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166790)

View File

@ -88,7 +88,7 @@ module Gitlab
module Emoji
def emoji_unicode_version(name)
@emoji_unicode_versions_by_name ||=
JSON.parse(File.read(Rails.root.join('fixtures', 'emojis', 'emoji-unicode-version-map.json')))
JSON.parse(File.read(Rails.root.join('fixtures', 'emojis', 'digests.json')))
@emoji_unicode_versions_by_name[name]
end
end
@ -113,7 +113,7 @@ module Gitlab
def emoji_unicode_versions_by_name
@emoji_unicode_versions_by_name ||=
JSON.parse(File.read(Rails.root.join('fixtures', 'emojis', 'emoji-unicode-version-map.json')))
JSON.parse(File.read(Rails.root.join('fixtures', 'emojis', 'digests.json')))
end
end
end

View File

@ -378,26 +378,26 @@ following:
bundle exec rake tanuki_emoji:aliases
```
To update the Emoji digests file (used for Emoji autocomplete), run the
following:
To import the fallback Emoji images, run the following:
```shell
bundle exec rake tanuki_emoji:import
```
To update the Emoji digests file (used for Emoji autocomplete) based on the currently
available Emoji, run the following:
```shell
bundle exec rake tanuki_emoji:digests
```
This updates the file `fixtures/emojis/digests.json` based on the currently
available Emoji.
To generate a sprite file containing all the Emoji, run:
```shell
bundle exec rake tanuki_emoji:sprite
```
If new emoji are added, the sprite sheet may change size. To compensate for
such changes, first generate the `emoji.png` sprite sheet with the above Rake
task, then check the dimensions of the new sprite sheet and update the
`SPRITESHEET_WIDTH` and `SPRITESHEET_HEIGHT` constants accordingly.
See [How to update Emojis](fe_guide/emojis.md) for detailed instructions.
## Update project templates

View File

@ -11,6 +11,7 @@ module Banzai
prepend Concerns::PipelineTimingCheck
IGNORED_ANCESTOR_TAGS = %w[pre code tt].to_set
IGNORE_UNICODE_EMOJIS = %w[™ © ®].freeze
def call
@emoji_count = 0
@ -42,12 +43,7 @@ module Banzai
.gsub_with_limit(text, emoji_pattern, limit: Banzai::Filter::FILTER_ITEM_LIMIT) do |match_data|
emoji = TanukiEmoji.find_by_alpha_code(match_data[0])
if emoji
@emoji_count += 1
Gitlab::Emoji.gl_emoji_tag(emoji)
else
match_data[0]
end
process_emoji_tag(emoji, match_data[0])
end
end
@ -59,17 +55,27 @@ module Banzai
def emoji_unicode_element_unicode_filter(text)
Gitlab::Utils::Gsub
.gsub_with_limit(text, emoji_unicode_pattern, limit: Banzai::Filter::FILTER_ITEM_LIMIT) do |match_data|
emoji = TanukiEmoji.find_by_codepoints(match_data[0])
if emoji
@emoji_count += 1
Gitlab::Emoji.gl_emoji_tag(emoji)
else
if ignore_emoji?(match_data[0])
match_data[0]
else
emoji = TanukiEmoji.find_by_codepoints(match_data[0])
process_emoji_tag(emoji, match_data[0])
end
end
end
def process_emoji_tag(emoji, fallback)
return fallback unless emoji
@emoji_count += 1
Gitlab::Emoji.gl_emoji_tag(emoji)
end
def ignore_emoji?(text)
IGNORE_UNICODE_EMOJIS.include?(text)
end
# Build a regexp that matches all valid :emoji: names.
def self.emoji_pattern
@emoji_pattern ||= TanukiEmoji.index.alpha_code_pattern

View File

@ -6,7 +6,7 @@ module Gitlab
# When updating emoji assets increase the version below
# and update the version number in `app/assets/javascripts/emoji/index.js`
EMOJI_VERSION = 3
EMOJI_VERSION = 4
# Return a Pathname to emoji's current versioned folder
#

View File

@ -117,10 +117,10 @@ namespace :tanuki_emoji do
SIZE = 20
RETINA = SIZE * 2
# Update these values to the width and height of the spritesheet when
# Update these values to the width and height of the sprite sheet when
# new emoji are added.
SPRITESHEET_WIDTH = 860
SPRITESHEET_HEIGHT = 840
SPRITESHEET_WIDTH = 1240
SPRITESHEET_HEIGHT = 1220
emoji_dir = Gitlab::Emoji.emoji_public_absolute_path
@ -235,7 +235,7 @@ namespace :tanuki_emoji do
To enable this task, *temporarily* add the following lines to Gemfile and
re-bundle:
gem 'rmagick', '~> 3.2'
gem 'rmagick', '~> 6.0'
It depends on ImageMagick 6, which can be installed via HomeBrew with:

View File

@ -243,7 +243,8 @@ RSpec.describe 'Database schema',
namespace_settings: %w[early_access_program_joined_by_id], # isn't used inside product itself. Only through Snowflake
workspaces_agent_config_versions: %w[item_id], # polymorphic associations
work_item_types: %w[correct_id], # temporary column that is not a foreign key
instance_integrations: %w[project_id group_id inherit_from_id] # these columns are not used in instance integrations
instance_integrations: %w[project_id group_id inherit_from_id], # these columns are not used in instance integrations
subscription_user_add_on_assignment_versions: %w[item_id user_id purchase_id] # Managed by paper_trail gem, no need for FK on the historical data
}.with_indifferent_access.freeze
end
@ -418,7 +419,8 @@ RSpec.describe 'Database schema',
"Releases::Evidence" => %w[summary],
"Vulnerabilities::Finding::Evidence" => %w[data], # Validation work in progress
"Ai::DuoWorkflows::Checkpoint" => %w[checkpoint metadata], # https://gitlab.com/gitlab-org/gitlab/-/issues/468632
"RemoteDevelopment::WorkspacesAgentConfigVersion" => %w[object object_changes] # Managed by paper_trail gem
"RemoteDevelopment::WorkspacesAgentConfigVersion" => %w[object object_changes], # Managed by paper_trail gem
"GitlabSubscriptions::UserAddOnAssignmentVersion" => %w[object] # Managed by paper_trail gem
}.freeze
end

View File

@ -42,7 +42,7 @@ RSpec.describe 'Dropdown emoji', :js, feature_category: :team_planning do
it 'loads all the emojis when opened' do
select_tokens 'My-Reaction', '='
# Expect None, Any, star, thumbs_up, thumbs_down
# Expect None, Any, star, thumbsup, thumbsdown
expect_suggestion_count 5
end

View File

@ -18,7 +18,7 @@ RSpec.describe 'User interacts with awards', feature_category: :team_planning do
visit(project_issue_path(project, issue))
end
it 'toggles the thumbs_up award emoji', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27959' do
it 'toggles the thumbsup award emoji', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27959' do
page.within('.awards') do
thumbsup = page.first('.award-control')
thumbsup.click
@ -281,14 +281,14 @@ RSpec.describe 'User interacts with awards', feature_category: :team_planning do
wait_for_requests
end
context 'click the thumbs_down emoji' do
it 'increments the thumbs_down emoji', :js do
context 'click the thumbsdown emoji' do
it 'increments the thumbsdown emoji', :js do
find(%([data-name="#{AwardEmoji::THUMBS_DOWN}"])).click
wait_for_requests
expect(thumbsdown_emoji).to have_text("1")
end
it 'decrements the thumbs_up emoji', :js do
it 'decrements the thumbsup emoji', :js do
expect(thumbsup_emoji).to have_text("0")
end
end

View File

@ -29,14 +29,14 @@ RSpec.describe 'Merge request > User creates custom emoji', :js, feature_categor
wait_for_requests
find_by_testid("custom-emoji-name-input").set 'parrot'
find_by_testid("custom-emoji-name-input").set 'flying_parrot'
find_by_testid("custom-emoji-url-input").set 'https://example.com'
click_button 'Save'
wait_for_requests
expect(page).to have_content(':parrot:')
expect(page).to have_content(':flying_parrot:')
end
end

View File

@ -62,7 +62,7 @@ exports[`releases/util.js convertAllReleasesGraphQLResponse matches snapshot 1`]
<gl-emoji
data-name="shrug"
data-unicode-version="9.0"
title="shrug"
title="person shrugging"
>
🤷
</gl-emoji>

View File

@ -81,7 +81,7 @@ RSpec.describe IssuesHelper, feature_category: :team_planning do
end
describe 'awards_sort' do
it 'sorts a hash so thumbs_up and thumbs_down are always on top' do
it 'sorts a hash so thumbsup and thumbsdown are always on top' do
data = { AwardEmoji::THUMBS_DOWN => 'some value', 'lifter' => 'some value', AwardEmoji::THUMBS_UP => 'some value' }
expect(awards_sort(data).keys).to eq(%W[#{AwardEmoji::THUMBS_UP} #{AwardEmoji::THUMBS_DOWN} lifter])
end

View File

@ -11,12 +11,12 @@ RSpec.describe Banzai::Filter::EmojiFilter, feature_category: :markdown do
it 'replaces supported name emoji' do
doc = filter('<p>:heart:</p>')
expect(doc.css('gl-emoji').first.text).to eq '❤'
expect(doc.css('gl-emoji').first.text).to eq '❤'
end
it 'replaces supported unicode emoji' do
doc = filter('<p>❤️</p>')
expect(doc.css('gl-emoji').first.text).to eq '❤'
expect(doc.css('gl-emoji').first.text).to eq '❤'
end
it 'ignores unicode versions of trademark, copyright, and registered trademark' do
@ -159,7 +159,7 @@ RSpec.describe Banzai::Filter::EmojiFilter, feature_category: :markdown do
context 'when using TanukiEmoji' do
# the regex doesn't find emoji components, and they are not really meant to be used
# by themselves, so ignore them.
let(:exclude_components) { "🏻🏼🏽🏾🏿" }
let(:exclude_components) { "🏻🏼🏽🏾🏿🦰🦱🦳🦲" }
it 'finds all unicode emoji codepoints with regex' do
TanukiEmoji.index.all.each do |emoji| # rubocop:disable Rails/FindEach -- not a Rails model

View File

@ -68,7 +68,7 @@ RSpec.describe Banzai::Pipeline::IncidentManagement::TimelineEventPipeline do
it 'renders emojis wrapped in <gl-emoji> tag' do
# rubocop:disable Layout/LineLength
is_expected.to eq(
%(<p><gl-emoji title="thumbs up sign" data-name="#{AwardEmoji::THUMBS_UP}" data-unicode-version="6.0">👍</gl-emoji><gl-emoji title="thumbs up sign" data-name="#{AwardEmoji::THUMBS_UP}" data-unicode-version="6.0">👍</gl-emoji></p>)
%(<p><gl-emoji title="thumbs up" data-name="#{AwardEmoji::THUMBS_UP}" data-unicode-version="6.0">👍</gl-emoji><gl-emoji title="thumbs up" data-name="#{AwardEmoji::THUMBS_UP}" data-unicode-version="6.0">👍</gl-emoji></p>)
)
# rubocop:enable Layout/LineLength
end

View File

@ -8,7 +8,7 @@ RSpec.describe Gitlab::Emoji do
emoji = TanukiEmoji.find_by_alpha_code('small_airplane')
gl_tag = described_class.gl_emoji_tag(emoji)
expect(gl_tag).to eq('<gl-emoji title="small airplane" data-name="airplane_small" data-unicode-version="7.0">🛩</gl-emoji>')
expect(gl_tag).to eq('<gl-emoji title="small airplane" data-name="airplane_small" data-unicode-version="7.0">🛩</gl-emoji>')
end
it 'returns nil if emoji is not found' do

View File

@ -14,10 +14,10 @@ RSpec.describe CustomEmoji do
end
describe 'exclusion of duplicated emoji' do
let(:emoji_name) { TanukiEmoji.index.all.sample.name }
let(:group) { create(:group, :private) }
it 'disallows emoji names of built-in emoji' do
emoji_name = TanukiEmoji.index.all.sample.name until emoji_name && emoji_name.size < 36
new_emoji = build(:custom_emoji, name: emoji_name, group: group)
expect(new_emoji).not_to be_valid
@ -70,13 +70,13 @@ RSpec.describe CustomEmoji do
describe '#for_namespaces' do
let_it_be(:group) { create(:group) }
let_it_be(:custom_emoji) { create(:custom_emoji, namespace: group, name: 'parrot') }
let_it_be(:custom_emoji) { create(:custom_emoji, namespace: group, name: 'flying_parrot') }
it { expect(described_class.for_namespaces([group.id])).to eq([custom_emoji]) }
context 'with subgroup' do
let_it_be(:subgroup) { create(:group, parent: group) }
let_it_be(:subgroup_emoji) { create(:custom_emoji, namespace: subgroup, name: 'parrot') }
let_it_be(:subgroup_emoji) { create(:custom_emoji, namespace: subgroup, name: 'flying_parrot') }
it { expect(described_class.for_namespaces([subgroup.id, group.id])).to eq([subgroup_emoji]) }
end

View File

@ -72,7 +72,7 @@ RSpec.describe IncidentManagement::TimelineEvent do
# rubocop:disable Layout/LineLength
let(:expected_emoji_html) do
%(<gl-emoji title="thumbs up sign" data-name="#{AwardEmoji::THUMBS_UP}" data-unicode-version="6.0">👍</gl-emoji><gl-emoji title="thumbs up sign" data-name="#{AwardEmoji::THUMBS_UP}" data-unicode-version="6.0">👍</gl-emoji>)
%(<gl-emoji title="thumbs up" data-name="#{AwardEmoji::THUMBS_UP}" data-unicode-version="6.0">👍</gl-emoji><gl-emoji title="thumbs up" data-name="#{AwardEmoji::THUMBS_UP}" data-unicode-version="6.0">👍</gl-emoji>)
end
let(:expected_note_html) do

View File

@ -251,7 +251,7 @@ RSpec.describe API::AwardEmoji, feature_category: :shared do
expect(response).to have_gitlab_http_status(:bad_request)
end
it "normalizes +1 as thumbs_up award" do
it "normalizes +1 as thumbsup award" do
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), params: { name: '+1' }
expect(issue.award_emoji.last.name).to eq(AwardEmoji::THUMBS_UP)
@ -306,7 +306,7 @@ RSpec.describe API::AwardEmoji, feature_category: :shared do
expect(todo.reload).to be_done
end
it "normalizes +1 as thumbs_up award" do
it "normalizes +1 as thumbsup award" do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), params: { name: '+1' }
expect(note.award_emoji.last.name).to eq(AwardEmoji::THUMBS_UP)

View File

@ -126,7 +126,7 @@ RSpec.describe GroupChildEntity do
let(:description) { ':smile:' }
it 'has the correct markdown_description' do
expect(json[:markdown_description]).to eq('<p dir="auto"><gl-emoji title="smiling face with open mouth and smiling eyes" data-name="smile" data-unicode-version="6.0">😄</gl-emoji></p>')
expect(json[:markdown_description]).to eq('<p dir="auto"><gl-emoji title="grinning face with smiling eyes" data-name="smile" data-unicode-version="6.0">😄</gl-emoji></p>')
end
end

View File

@ -481,7 +481,7 @@ RSpec.shared_examples 'work items award emoji' do
within(award_section_selector) do
expect(page).to have_selector(selected_award_button_selector)
# As the user2 has already awarded the `:thumbs_up:` emoji, the emoji count will be 2
# As the user2 has already awarded the `:thumbsup:` emoji, the emoji count will be 2
expect(first(award_button_selector)).to have_content '2'
end
expect(page.find(tooltip_selector)).to have_content("John and you reacted with :#{AwardEmoji::THUMBS_UP}:")
@ -491,7 +491,7 @@ RSpec.shared_examples 'work items award emoji' do
select_emoji
page.within(award_section_selector) do
# As the user2 has already awarded the `:thumbs_up:` emoji, the emoji count will be 2
# As the user2 has already awarded the `:thumbsup:` emoji, the emoji count will be 2
expect(first(award_button_selector)).to have_content '2'
end

View File

@ -744,51 +744,51 @@ RSpec.shared_examples 'issues or work items finder' do |factory, execute_context
end
end
context 'user searches by "thumbs_up" reaction' do
context 'user searches by "thumbsup" reaction' do
let(:params) { { my_reaction_emoji: AwardEmoji::THUMBS_UP } }
it 'returns items that the user thumbs_up to' do
it 'returns items that the user thumbsup to' do
expect(items).to contain_exactly(item1)
end
context 'using NOT' do
let(:params) { { not: { my_reaction_emoji: AwardEmoji::THUMBS_UP } } }
it 'returns items that the user did not thumbs_up to' do
it 'returns items that the user did not thumbsup to' do
expect(items).to contain_exactly(item2, item3, item4, item5)
end
end
end
context 'user2 searches by "thumbs_up" reaction' do
context 'user2 searches by "thumbsup" reaction' do
let(:search_user) { user2 }
let(:params) { { my_reaction_emoji: AwardEmoji::THUMBS_UP } }
it 'returns items that the user2 thumbs_up to' do
it 'returns items that the user2 thumbsup to' do
expect(items).to contain_exactly(item2)
end
context 'using NOT' do
let(:params) { { not: { my_reaction_emoji: AwardEmoji::THUMBS_UP } } }
it 'returns items that the user2 thumbs_up to' do
it 'returns items that the user2 thumbsup to' do
expect(items).to contain_exactly(item3)
end
end
end
context 'user searches by "thumbs_down" reaction' do
context 'user searches by "thumbsdown" reaction' do
let(:params) { { my_reaction_emoji: AwardEmoji::THUMBS_DOWN } }
it 'returns items that the user thumbs_down to' do
it 'returns items that the user thumbsdown to' do
expect(items).to contain_exactly(item3)
end
context 'using NOT' do
let(:params) { { not: { my_reaction_emoji: AwardEmoji::THUMBS_DOWN } } }
it 'returns items that the user thumbs_down to' do
it 'returns items that the user thumbsdown to' do
expect(items).to contain_exactly(item1, item2, item4, item5)
end
end

View File

@ -0,0 +1,102 @@
# frozen_string_literal: true
RSpec.shared_examples 'a model with paper trail configured' do
describe 'paper_trail' do
subject(:object) { create(factory) } # rubocop:disable Rails/SaveBang -- False positive, this is a factory bot method.
# making duplication of object, and it does not reload when object updated
let(:new_object_before_change) { object }
shared_examples 'saving additional properties' do
it 'saves additional properties' do
version = object.versions.last
additional_properties.each do |attr, value|
expect(version[attr]).to eq(value)
end
end
end
context 'on creation' do
it 'contains version with 1' do
expect(object.versions.length).to be 1
end
it 'create version has nil object' do
expect(object.versions[0].reify).to be_nil
end
it_behaves_like 'saving additional properties'
end
context 'on update' do
before do
object.update!(attributes_to_update)
end
it 'contains version with 2' do
expect(object.versions.length).to be 2
end
it 'contains version before update' do
reified_object = object.versions.last.reify
expect(reified_object).to eql(object)
end
it_behaves_like 'saving additional properties'
end
context 'on destroy' do
before do
object.destroy!
end
it 'contains version with 2' do
expect(object.versions.length).to be 2
end
it 'contains version before destroy' do
reified_object = object.versions.last.reify
expect(reified_object).to eql(object)
end
it_behaves_like 'saving additional properties'
end
context 'on delete' do
before do
object.delete
end
it 'contains version with 1' do
expect(object.versions.length).to be 1
end
it 'does not contain version before delete' do
reified_object = object.versions.last.reify
expect(reified_object).to be_nil
end
end
context 'on touch' do
before do
object.touch
end
it 'contains version with 2' do
expect(object.versions.length).to be 2
end
it 'contains version before touch' do
reified_object = object.versions.last.reify
expect(reified_object).to eql(new_object_before_change)
end
it_behaves_like 'saving additional properties'
end
end
end