mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-07-25 16:03:48 +00:00
Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
@ -24,11 +24,10 @@ module Mutations
|
||||
discussion_id = nil
|
||||
|
||||
if gid = args[:discussion_id]
|
||||
discussion = GitlabSchema.find_by_gid(gid)
|
||||
discussion_id = ::GitlabSchema.parse_gid(gid, expected_type: ::Discussion).model_id
|
||||
discussion = noteable.notes.find_discussion(discussion_id)
|
||||
|
||||
authorize_discussion!(discussion)
|
||||
|
||||
discussion_id = discussion.id
|
||||
end
|
||||
|
||||
super.merge({
|
||||
|
@ -17,6 +17,7 @@ module WorkItems
|
||||
@target_noteable = target_noteable
|
||||
@source_parent = source_noteable.resource_parent
|
||||
@target_parent = target_noteable.resource_parent
|
||||
@new_discussion_ids = {}
|
||||
end
|
||||
|
||||
def execute
|
||||
@ -40,7 +41,8 @@ module WorkItems
|
||||
|
||||
private
|
||||
|
||||
attr_reader :current_user, :source_noteable, :target_noteable, :source_parent, :target_parent
|
||||
attr_reader :current_user, :source_noteable, :target_noteable, :source_parent, :target_parent,
|
||||
:new_discussion_ids
|
||||
|
||||
def copy_notes_emoji(notes_ids_map)
|
||||
notes_emoji = ::AwardEmoji.by_awardable('Note', notes_ids_map.keys)
|
||||
@ -79,19 +81,26 @@ module WorkItems
|
||||
ids.zip(allocated_ids).to_h
|
||||
end
|
||||
|
||||
# rubocop: disable Metrics/AbcSize -- Despite being long, this method is straightforward.
|
||||
def new_notes(notes_batch, notes_ids_map)
|
||||
notes_batch.map do |note|
|
||||
new_discussion_ids[note.discussion_id] ||= Note.new(
|
||||
noteable_id: target_noteable.id,
|
||||
noteable_type: target_noteable.class.base_class
|
||||
).discussion_id
|
||||
|
||||
note.attributes.tap do |attrs|
|
||||
attrs['id'] = notes_ids_map[note.id]
|
||||
attrs['noteable_id'] = target_noteable.id
|
||||
# we want this if we want to use this also to copy notes when promoting issue to epic
|
||||
attrs['noteable_type'] = target_noteable.class.base_class
|
||||
attrs['discussion_id'] = new_discussion_ids[note.discussion_id]
|
||||
# need to use `try` to be able to handle Issue model and legacy Epic model instances
|
||||
attrs['project_id'] = target_noteable.try(:project_id)
|
||||
attrs['namespace_id'] = target_noteable.try(:namespace_id) || target_noteable.try(:group_id)
|
||||
attrs['imported_from'] = 'none' # maintaining current copy notes implementation
|
||||
|
||||
# this data is not changed, but it is being serialized and we need it deserialized for bulk inserts
|
||||
# this data is not changed, but it is being serialized, and we need it deserialized for bulk inserts
|
||||
attrs['position'] = note.attributes_before_type_cast['position']
|
||||
attrs['original_position'] = note.attributes_before_type_cast['original_position']
|
||||
attrs['change_position'] = note.attributes_before_type_cast['change_position']
|
||||
@ -104,6 +113,7 @@ module WorkItems
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop: enable Metrics/AbcSize
|
||||
|
||||
def new_notes_emoji(notes_emoji, notes_ids_map)
|
||||
notes_emoji.map do |note_emoji|
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: api_request_access_with_scope
|
||||
description: A susbset of API requests authenticated by a token with an audited scope
|
||||
description: A subset of API requests authenticated by a token with an audited scope
|
||||
introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/499461
|
||||
introduced_by_mr: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/172548
|
||||
feature_category: duo_workflow
|
||||
|
@ -10097,6 +10097,25 @@ Input type: `PromoteToEpicInput`
|
||||
| <a id="mutationpromotetoepicerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during the mutation. |
|
||||
| <a id="mutationpromotetoepicissue"></a>`issue` | [`Issue`](#issue) | Issue after mutation. |
|
||||
|
||||
### `Mutation.refreshFindingTokenStatus`
|
||||
|
||||
Input type: `RefreshFindingTokenStatusInput`
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationrefreshfindingtokenstatusclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationrefreshfindingtokenstatusvulnerabilityid"></a>`vulnerabilityId` | [`VulnerabilityID!`](#vulnerabilityid) | Global ID of the Vulnerability whose token status should be refreshed. |
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationrefreshfindingtokenstatusclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationrefreshfindingtokenstatuserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during the mutation. |
|
||||
| <a id="mutationrefreshfindingtokenstatusfindingtokenstatus"></a>`findingTokenStatus` | [`VulnerabilityFindingTokenStatus`](#vulnerabilityfindingtokenstatus) | Updated token status record for the given finding. |
|
||||
|
||||
### `Mutation.refreshStandardsAdherenceChecks`
|
||||
|
||||
Input type: `RefreshStandardsAdherenceChecksInput`
|
||||
|
@ -294,11 +294,11 @@ Audit event types belong to the following product categories.
|
||||
|:----------|:---------------------|:------------------|:--------------|:------|
|
||||
| [`project_feature_metrics_dashboard_access_level_updated`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106919) | A project's metrics dashboard access level setting is updated | {{< icon name="check-circle" >}} Yes | GitLab [15.7](https://gitlab.com/gitlab-org/gitlab/-/issues/369289) | Project |
|
||||
|
||||
### GitLab Duo Workflow
|
||||
### GitLab Duo Agent Platform
|
||||
|
||||
| Type name | Event triggered when | Saved to database | Introduced in | Scope |
|
||||
|:----------|:---------------------|:------------------|:--------------|:------|
|
||||
| [`api_request_access_with_scope`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/172548) | A susbset of API requests authenticated by a token with an audited scope | {{< icon name="check-circle" >}} Yes | GitLab [17.7](https://gitlab.com/gitlab-org/gitlab/-/issues/499461) | User |
|
||||
| [`api_request_access_with_scope`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/172548) | A subset of API requests authenticated by a token with an audited scope | {{< icon name="check-circle" >}} Yes | GitLab [17.7](https://gitlab.com/gitlab-org/gitlab/-/issues/499461) | User |
|
||||
|
||||
### Dynamic application security testing
|
||||
|
||||
|
@ -99,12 +99,20 @@ the immediate parent group.
|
||||
|
||||
## View groups
|
||||
|
||||
To explore all public groups you are a member of:
|
||||
To explore all public or internal groups:
|
||||
|
||||
1. On the left sidebar, select **Search or go to**.
|
||||
1. Select **View all my groups**.
|
||||
1. In the upper right, select **Explore groups**.
|
||||
|
||||
## View groups you are a member of
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- **Member** tab [introduced](https://gitlab.com/groups/gitlab-org/-/epics/13781) in GitLab 18.2 [with a flag](../../administration/feature_flags/_index.md) named `your_work_groups_vue`. Disabled by default.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
To view groups where you have direct or indirect membership:
|
||||
|
||||
1. On the left sidebar, select **Search or go to**.
|
||||
@ -115,6 +123,8 @@ This page shows groups that you are a member of through:
|
||||
- Membership of a subgroup's parent group.
|
||||
- Direct or inherited membership of a project in the group or subgroup.
|
||||
|
||||
If the `your_work_groups_vue` feature flag is enabled, groups that you are a member of appear in the **Member** tab.
|
||||
|
||||
## View a group
|
||||
|
||||
{{< history >}}
|
||||
@ -270,6 +280,12 @@ the deletion job will instead restore and unarchive the group, so the group will
|
||||
|
||||
### View groups pending deletion
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- **Inactive** tab [introduced](https://gitlab.com/groups/gitlab-org/-/epics/13781) in GitLab 18.2 [with a flag](../../administration/feature_flags/_index.md) named `your_work_groups_vue`. Disabled by default.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
To view a list of the subgroups that are pending deletion in a group:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
@ -277,6 +293,8 @@ To view a list of the subgroups that are pending deletion in a group:
|
||||
|
||||
Groups that are marked for deletion are labeled **Pending deletion**.
|
||||
|
||||
If the `your_work_groups_vue` feature flag is enabled, groups marked for deletion appear in the **Inactive** tab.
|
||||
|
||||
## Delete a group immediately
|
||||
|
||||
{{< history >}}
|
||||
|
@ -33,7 +33,13 @@ You can use Docker commands to build and push container images to your container
|
||||
docker push registry.example.com/group/project/image
|
||||
```
|
||||
|
||||
## Configure your `.gitlab-ci.yml` file
|
||||
## Use GitLab CI/CD
|
||||
|
||||
You can use [GitLab CI/CD](../../../ci/_index.md) to build and push container images to the
|
||||
Container Registry. You can use CI/CD to test, build, and deploy your project from the container
|
||||
image you created.
|
||||
|
||||
### Configure your `.gitlab-ci.yml` file
|
||||
|
||||
You can configure your `.gitlab-ci.yml` file to build and push container images to the container registry.
|
||||
|
||||
@ -50,19 +56,26 @@ You can configure your `.gitlab-ci.yml` file to build and push container images
|
||||
- Don't build directly to the `latest` tag because multiple jobs may be
|
||||
happening simultaneously.
|
||||
|
||||
## Use GitLab CI/CD
|
||||
### Use a Docker-in-Docker container image
|
||||
|
||||
You can use [GitLab CI/CD](../../../ci/_index.md) to build and push container images to the
|
||||
Container Registry. You can use CI/CD to test, build, and deploy your project from the container
|
||||
image you created.
|
||||
You can use your own Docker-in-Docker (DinD)
|
||||
container images with the container registry or Dependency Proxy.
|
||||
|
||||
### Use a Docker-in-Docker container image from your container registry
|
||||
Use DinD to build, test, and deploy containerized
|
||||
applications from your CI/CD pipeline.
|
||||
|
||||
You can use your own container images for Docker-in-Docker.
|
||||
Prerequisites:
|
||||
|
||||
1. Set up [Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker).
|
||||
1. Update the `image` and `service` to point to your registry.
|
||||
1. Add a service [alias](../../../ci/services/_index.md#available-settings-for-services).
|
||||
- Set up [Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker).
|
||||
|
||||
{{< tabs >}}
|
||||
|
||||
{{< tab title="From the container registry" >}}
|
||||
|
||||
In your `.gitlab-ci.yml` file:
|
||||
|
||||
- Update `image` and `services` to point to your registry.
|
||||
- Add a service [alias](../../../ci/services/_index.md#available-settings-for-services).
|
||||
|
||||
Your `.gitlab-ci.yml` should look similar to this:
|
||||
|
||||
@ -78,20 +91,14 @@ build:
|
||||
- docker run my-docker-image /script/to/run/tests
|
||||
```
|
||||
|
||||
If you forget to set the service alias, the container image can't find the `dind` service,
|
||||
and an error like the following is shown:
|
||||
{{< /tab >}}
|
||||
|
||||
```plaintext
|
||||
error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on 192.168.0.1:53: no such host
|
||||
```
|
||||
{{< tab title="With the Dependency Proxy" >}}
|
||||
|
||||
### Use a Docker-in-Docker container image with Dependency Proxy
|
||||
In your `.gitlab-ci.yml` file:
|
||||
|
||||
You can use your own container images with Dependency Proxy.
|
||||
|
||||
1. Set up [Docker-in-Docker](../../../ci/docker/using_docker_build.md#use-docker-in-docker).
|
||||
1. Update the `image` and `service` to point to your registry.
|
||||
1. Add a service [alias](../../../ci/services/_index.md#available-settings-for-services).
|
||||
- Update `image` and `services` to point to your dependency proxy.
|
||||
- Add a service [alias](../../../ci/services/_index.md#available-settings-for-services).
|
||||
|
||||
Your `.gitlab-ci.yml` should look similar to this:
|
||||
|
||||
@ -107,6 +114,10 @@ build:
|
||||
- docker run my-docker-image /script/to/run/tests
|
||||
```
|
||||
|
||||
{{< /tab >}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
If you forget to set the service alias, the container image can't find the `dind` service,
|
||||
and an error like the following is shown:
|
||||
|
||||
@ -116,7 +127,7 @@ error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker
|
||||
|
||||
## Container registry examples with GitLab CI/CD
|
||||
|
||||
If you're using Docker-in-Docker on your runners, your `.gitlab-ci.yml` file should look similar to this:
|
||||
If you're using DinD on your runners, your `.gitlab-ci.yml` file should look similar to this:
|
||||
|
||||
```yaml
|
||||
build:
|
||||
|
@ -86,7 +86,6 @@ spec/frontend/jira_import/components/jira_import_form_spec.js
|
||||
spec/frontend/lib/utils/breadcrumbs_spec.js
|
||||
spec/frontend/lib/utils/confirm_via_gl_modal/confirm_action_spec.js
|
||||
spec/frontend/members/components/app_spec.js
|
||||
spec/frontend/members/components/modals/leave_modal_spec.js
|
||||
spec/frontend/members/components/table/max_role_spec.js
|
||||
spec/frontend/members/components/table/members_table_spec.js
|
||||
spec/frontend/ml/model_registry/components/model_edit_spec.js
|
||||
@ -110,7 +109,6 @@ spec/frontend/super_sidebar/components/user_menu_spec.js
|
||||
spec/frontend/tooltips/index_spec.js
|
||||
spec/frontend/vue_alerts_spec.js
|
||||
spec/frontend/vue_popovers_spec.js
|
||||
spec/frontend/vue_shared/components/design_management/design_note_pin_spec.js
|
||||
spec/frontend/vue_shared/components/file_tree_spec.js
|
||||
spec/frontend/vue_shared/components/filtered_search_bar/tokens/date_token_spec.js
|
||||
spec/frontend/vue_shared/components/metric_images/metric_image_details_modal_spec.js
|
||||
|
@ -180,7 +180,7 @@ describe('LeaveModal', () => {
|
||||
|
||||
const submitSpy = jest.spyOn(findForm().element, 'submit');
|
||||
|
||||
findModal().findByText('Leave').trigger('click');
|
||||
findModal().vm.$emit('primary');
|
||||
|
||||
expect(submitSpy).toHaveBeenCalled();
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { assertProps } from 'helpers/assert_props';
|
||||
import DesignNotePin from '~/vue_shared/components/design_management/design_note_pin.vue';
|
||||
|
||||
describe('Design note pin component', () => {
|
||||
@ -61,12 +62,9 @@ describe('Design note pin component', () => {
|
||||
});
|
||||
|
||||
it('throws when passed any other value except `sm` or `md`', () => {
|
||||
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
createComponent({ size: 'lg' });
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
expect(console.error).toHaveBeenCalled();
|
||||
expect(() => {
|
||||
assertProps(DesignNotePin, { size: 'lg' });
|
||||
}).toThrow('Invalid prop: custom validator check failed');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -61,11 +61,24 @@ RSpec.describe 'Adding a Note', feature_category: :team_planning do
|
||||
context 'when the user has permission to create notes on the discussion' do
|
||||
let(:discussion) { create(:discussion_note, project: project).to_discussion }
|
||||
|
||||
context 'when discussion is not on the noteable' do
|
||||
it 'checks noteable and discussion noteable' do
|
||||
expect(noteable.id).not_to eq(discussion.noteable_id)
|
||||
end
|
||||
|
||||
it_behaves_like 'a mutation that returns top-level errors',
|
||||
errors: ["The discussion does not exist or you don't have permission to perform this action"]
|
||||
end
|
||||
|
||||
context 'when the discussion is on the noteable' do
|
||||
let(:noteable) { discussion.noteable }
|
||||
|
||||
it 'creates a Note in a discussion' do
|
||||
post_graphql_mutation(mutation, current_user: current_user)
|
||||
|
||||
expect(mutation_response['note']['discussion']).to match a_graphql_entity_for(discussion)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the discussion_id is not for a Discussion' do
|
||||
let(:discussion) { create(:issue) }
|
||||
|
@ -63,7 +63,7 @@ RSpec.describe WorkItems::DataSync::Handlers::Notes::CopyService, feature_catego
|
||||
|
||||
# 4 notes are copied to the target work item: 2 system notes and 2 user notes
|
||||
# 2 system notes had also description version metadata
|
||||
# 2 user notes notes had also description version metadata
|
||||
# 2 user notes had also description version metadata
|
||||
expect { execute_service }.to change { ::Note.count }.by(5).and(
|
||||
change { ::SystemNoteMetadata.count }.by(2)).and(
|
||||
change { ::DescriptionVersion.count }.by(1)).and(
|
||||
@ -71,7 +71,10 @@ RSpec.describe WorkItems::DataSync::Handlers::Notes::CopyService, feature_catego
|
||||
change { ::IssueUserMention.count }.by(2))
|
||||
|
||||
notes_details = target_work_item.reload.notes.pluck(:note, :discussion_id)
|
||||
expect(notes_details).to match_array(expected_notes_details)
|
||||
# same number of discussions in target and source work items
|
||||
expect(notes_details.size).to eq(expected_notes_details.size)
|
||||
# but with different discussion ids
|
||||
expect(notes_details).not_to match_array(expected_notes_details)
|
||||
end
|
||||
|
||||
it 'sets correct attributes from target', :aggregate_failures do
|
||||
@ -82,5 +85,100 @@ RSpec.describe WorkItems::DataSync::Handlers::Notes::CopyService, feature_catego
|
||||
expect(expected_description_version.namespace_id).to eq(target_work_item.namespace_id)
|
||||
expect(expected_description_version.issue_id).to eq(target_work_item.id)
|
||||
end
|
||||
|
||||
describe 'discussion_id generation' do
|
||||
it 'generates new discussion_ids for copied notes' do
|
||||
original_discussion_ids = work_item.notes.pluck(:discussion_id).uniq
|
||||
|
||||
execute_service
|
||||
|
||||
copied_discussion_ids = target_work_item.reload.notes.pluck(:discussion_id).uniq
|
||||
|
||||
# All copied notes should have different discussion_ids from originals
|
||||
expect(copied_discussion_ids).not_to include(*original_discussion_ids)
|
||||
# Each copied discussion_id should be a valid 40-character hex string
|
||||
copied_discussion_ids.all? { |discussion_id| expect(discussion_id).to match(/\A\h{40}\z/) }
|
||||
end
|
||||
|
||||
it 'reuses the same new discussion_id for notes in the same discussion' do
|
||||
# Create notes that are part of the same discussion
|
||||
discussion_note = create(:note, project: work_item.project, noteable: work_item)
|
||||
reply_note = create(:note,
|
||||
project: work_item.project,
|
||||
noteable: work_item,
|
||||
discussion_id: discussion_note.discussion_id,
|
||||
in_reply_to: discussion_note
|
||||
)
|
||||
|
||||
execute_service
|
||||
|
||||
copied_notes = target_work_item.reload.notes.where(note: [discussion_note.note, reply_note.note])
|
||||
copied_discussion_ids = copied_notes.pluck(:discussion_id).uniq
|
||||
|
||||
# Both copied notes should have the same new discussion_id
|
||||
expect(copied_discussion_ids.size).to eq(1)
|
||||
# But it should be different from the original
|
||||
expect(copied_discussion_ids.first).not_to eq(discussion_note.discussion_id)
|
||||
end
|
||||
|
||||
it 'generates different discussion_ids for different original discussions' do
|
||||
# Create two separate discussions
|
||||
discussion1_note = create(:note, project: work_item.project, noteable: work_item)
|
||||
discussion2_note = create(:note, project: work_item.project, noteable: work_item)
|
||||
|
||||
execute_service
|
||||
|
||||
copied_notes = target_work_item.reload.notes.where(note: [discussion1_note.note, discussion2_note.note])
|
||||
copied_discussion_ids = copied_notes.pluck(:discussion_id)
|
||||
|
||||
# Each copied note should have a different discussion_id
|
||||
expect(copied_discussion_ids.uniq.size).to eq(2)
|
||||
expect(copied_discussion_ids).not_to include(discussion1_note.discussion_id, discussion2_note.discussion_id)
|
||||
end
|
||||
|
||||
it 'calls Discussion.discussion_id to generate new discussion_ids' do
|
||||
expect(::Discussion).to receive(:discussion_id).at_least(:once).and_call_original
|
||||
|
||||
execute_service
|
||||
end
|
||||
|
||||
it 'maintains discussion structure when copying notes with replies' do
|
||||
# Create a discussion with multiple replies
|
||||
parent_note = create(:note, project: work_item.project, noteable: work_item, note: 'Parent note')
|
||||
create(:note,
|
||||
project: work_item.project,
|
||||
noteable: work_item,
|
||||
note: 'Reply 1',
|
||||
discussion_id: parent_note.discussion_id,
|
||||
in_reply_to: parent_note
|
||||
)
|
||||
create(:note,
|
||||
project: work_item.project,
|
||||
noteable: work_item,
|
||||
note: 'Reply 2',
|
||||
discussion_id: parent_note.discussion_id,
|
||||
in_reply_to: parent_note
|
||||
)
|
||||
|
||||
execute_service
|
||||
|
||||
# Find the copied notes
|
||||
copied_parent = target_work_item.reload.notes.find_by(note: 'Parent note')
|
||||
copied_reply1 = target_work_item.notes.find_by(note: 'Reply 1')
|
||||
copied_reply2 = target_work_item.notes.find_by(note: 'Reply 2')
|
||||
|
||||
# All copied notes should have the same new discussion_id
|
||||
expect(copied_parent.discussion_id).to eq(copied_reply1.discussion_id)
|
||||
expect(copied_parent.discussion_id).to eq(copied_reply2.discussion_id)
|
||||
|
||||
# But different from the original
|
||||
expect(copied_parent.discussion_id).not_to eq(parent_note.discussion_id)
|
||||
|
||||
# Verify the discussion structure is maintained
|
||||
discussion = target_work_item.notes.find_discussion(copied_parent.discussion_id)
|
||||
expect(discussion.notes.size).to eq(3)
|
||||
expect(discussion.notes.map(&:note)).to contain_exactly('Parent note', 'Reply 1', 'Reply 2')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -105,7 +105,7 @@ RSpec.describe WorkItems::DataSync::Widgets::Notes, feature_category: :team_plan
|
||||
|
||||
# 4 notes are copied to the target work item: 2 system notes and 2 user notes
|
||||
# 2 system notes had also description version metadata
|
||||
# 2 user notes notes had also description version metadata
|
||||
# 2 user notes had also description version metadata
|
||||
expect { callback.after_create }.to change { ::Note.count }.by(5).and(
|
||||
change { ::SystemNoteMetadata.count }.by(2)).and(
|
||||
change { ::DescriptionVersion.count }.by(1)).and(
|
||||
@ -116,7 +116,11 @@ RSpec.describe WorkItems::DataSync::Widgets::Notes, feature_category: :team_plan
|
||||
change { ::IssueUserMention.count }.by(2))
|
||||
|
||||
notes_details = target_work_item.reload.notes.pluck(:note, :discussion_id)
|
||||
expect(notes_details).to match_array(expected_notes_details)
|
||||
# size and notes would match
|
||||
expect(notes_details.size).to eq(expected_notes_details.size)
|
||||
expect(notes_details.map(&:first)).to match_array(expected_notes_details.map(&:first))
|
||||
# but discussion_ids would not
|
||||
expect(notes_details.map(&:last)).not_to match_array(expected_notes_details.map(&:last))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
<% def humanize(feature_category) %>
|
||||
<% case feature_category %>
|
||||
<% when 'duo_workflow' %>
|
||||
<% "GitLab Duo Workflow" %>
|
||||
<% "GitLab Duo Agent Platform" %>
|
||||
<% when 'mlops' %>
|
||||
<% "MLOps" %>
|
||||
<% when 'not_owned' %>
|
||||
|
Reference in New Issue
Block a user