Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
735165a16c
commit
31d92b51ea
|
|
@ -35,6 +35,12 @@ module Resolvers
|
|||
|
||||
private
|
||||
|
||||
def preloads
|
||||
{
|
||||
last_edited_by: :last_edited_by
|
||||
}
|
||||
end
|
||||
|
||||
# Allows to apply lookahead for fields
|
||||
# selected from WidgetInterface
|
||||
override :node_selection
|
||||
|
|
|
|||
|
|
@ -13,8 +13,18 @@ module Types
|
|||
implements Types::WorkItems::WidgetInterface
|
||||
|
||||
field :description, GraphQL::Types::String,
|
||||
null: true,
|
||||
description: 'Description of the work item.'
|
||||
null: true,
|
||||
description: 'Description of the work item.'
|
||||
field :edited, GraphQL::Types::Boolean,
|
||||
null: false,
|
||||
description: 'Whether the description has been edited since the work item was created.',
|
||||
method: :edited?
|
||||
field :last_edited_at, Types::TimeType,
|
||||
null: true,
|
||||
description: 'Timestamp of when the work item\'s description was last edited.'
|
||||
field :last_edited_by, Types::UserType,
|
||||
null: true,
|
||||
description: 'User that made the last edit to the work item\'s description.'
|
||||
|
||||
markdown_field :description_html, null: true do |resolved_object|
|
||||
resolved_object.work_item
|
||||
|
|
|
|||
|
|
@ -3,7 +3,13 @@
|
|||
module WorkItems
|
||||
module Widgets
|
||||
class Description < Base
|
||||
delegate :description, to: :work_item
|
||||
delegate :description, :edited?, :last_edited_at, to: :work_item
|
||||
|
||||
def last_edited_by
|
||||
return unless work_item.edited?
|
||||
|
||||
work_item.last_edited_by
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19367,6 +19367,9 @@ Represents a description widget.
|
|||
| ---- | ---- | ----------- |
|
||||
| <a id="workitemwidgetdescriptiondescription"></a>`description` | [`String`](#string) | Description of the work item. |
|
||||
| <a id="workitemwidgetdescriptiondescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
|
||||
| <a id="workitemwidgetdescriptionedited"></a>`edited` | [`Boolean!`](#boolean) | Whether the description has been edited since the work item was created. |
|
||||
| <a id="workitemwidgetdescriptionlasteditedat"></a>`lastEditedAt` | [`Time`](#time) | Timestamp of when the work item's description was last edited. |
|
||||
| <a id="workitemwidgetdescriptionlasteditedby"></a>`lastEditedBy` | [`UserCore`](#usercore) | User that made the last edit to the work item's description. |
|
||||
| <a id="workitemwidgetdescriptiontype"></a>`type` | [`WorkItemWidgetType`](#workitemwidgettype) | Widget type. |
|
||||
|
||||
### `WorkItemWidgetHierarchy`
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ For Free, Premium, and Ultimate plan customers, jobs on these instances consume
|
|||
| | Small | Medium | Large |
|
||||
|-------------------|---------------------------|---------------------------|--------------------------|
|
||||
| Specs | 1 vCPU, 3.75GB RAM | 2 vCPUs, 8GB RAM | 4 vCPUs, 16GB RAM |
|
||||
| GitLab CI/CD tags | `saas-linux-medium-amd64` | `saas-linux-medium-amd64` | `saas-linux-large-amd64` |
|
||||
| GitLab CI/CD tags | `saas-linux-small-amd64` | `saas-linux-medium-amd64` | `saas-linux-large-amd64` |
|
||||
| Subscription | Free, Premium, Ultimate | Free, Premium, Ultimate | Premium, Ultimate |
|
||||
|
||||
The `small` machine type is the default. Your job runs on this machine type if you don't specify
|
||||
|
|
|
|||
|
|
@ -23,5 +23,9 @@ FactoryBot.define do
|
|||
issue_type { :incident }
|
||||
association :work_item_type, :default, :incident
|
||||
end
|
||||
|
||||
trait :last_edited_by_user do
|
||||
association :last_edited_by, factory: :user
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ RSpec.describe GitlabSchema.types['WorkItem'] do
|
|||
closed_at
|
||||
]
|
||||
|
||||
fields.each do |field_name|
|
||||
expect(described_class).to have_graphql_fields(*fields)
|
||||
end
|
||||
expect(described_class).to have_graphql_fields(*fields)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Types::WorkItems::Widgets::DescriptionType do
|
||||
it 'exposes the expected fields' do
|
||||
expected_fields = %i[description description_html type]
|
||||
expected_fields = %i[description description_html edited last_edited_at last_edited_by type]
|
||||
|
||||
expect(described_class).to have_graphql_fields(*expected_fields)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe WorkItems::Widgets::Description do
|
||||
let_it_be(:work_item) { create(:work_item, description: '# Title') }
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:work_item, refind: true) do
|
||||
create(:work_item, description: 'Title', last_edited_at: 10.days.ago, last_edited_by: user)
|
||||
end
|
||||
|
||||
describe '.type' do
|
||||
subject { described_class.type }
|
||||
|
|
@ -22,4 +25,42 @@ RSpec.describe WorkItems::Widgets::Description do
|
|||
|
||||
it { is_expected.to eq(work_item.description) }
|
||||
end
|
||||
|
||||
describe '#edited?' do
|
||||
subject { described_class.new(work_item).edited? }
|
||||
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
|
||||
describe '#last_edited_at' do
|
||||
subject { described_class.new(work_item).last_edited_at }
|
||||
|
||||
it { is_expected.to eq(work_item.last_edited_at) }
|
||||
end
|
||||
|
||||
describe '#last_edited_by' do
|
||||
subject { described_class.new(work_item).last_edited_by }
|
||||
|
||||
context 'when the work item is edited' do
|
||||
context 'when last edited user still exists in the DB' do
|
||||
it { is_expected.to eq(user) }
|
||||
end
|
||||
|
||||
context 'when last edited user no longer exists' do
|
||||
before do
|
||||
work_item.update!(last_edited_by: nil)
|
||||
end
|
||||
|
||||
it { is_expected.to eq(User.ghost) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the work item is not edited yet' do
|
||||
before do
|
||||
work_item.update!(last_edited_at: nil)
|
||||
end
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@ RSpec.describe 'getting an work item list for a project' do
|
|||
let_it_be(:current_user) { create(:user) }
|
||||
|
||||
let_it_be(:item1) { create(:work_item, project: project, discussion_locked: true, title: 'item1') }
|
||||
let_it_be(:item2) { create(:work_item, project: project, title: 'item2') }
|
||||
let_it_be(:item2) do
|
||||
create(:work_item, project: project, title: 'item2', last_edited_by: current_user, last_edited_at: 1.day.ago)
|
||||
end
|
||||
|
||||
let_it_be(:confidential_item) { create(:work_item, confidential: true, project: project, title: 'item3') }
|
||||
let_it_be(:other_item) { create(:work_item) }
|
||||
|
||||
|
|
@ -75,6 +78,40 @@ RSpec.describe 'getting an work item list for a project' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when fetching description edit information' do
|
||||
let(:fields) do
|
||||
<<~GRAPHQL
|
||||
nodes {
|
||||
widgets {
|
||||
type
|
||||
... on WorkItemWidgetDescription {
|
||||
edited
|
||||
lastEditedAt
|
||||
lastEditedBy {
|
||||
webPath
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GRAPHQL
|
||||
end
|
||||
|
||||
it 'avoids N+1 queries' do
|
||||
post_graphql(query, current_user: current_user) # warm-up
|
||||
|
||||
control = ActiveRecord::QueryRecorder.new do
|
||||
post_graphql(query, current_user: current_user)
|
||||
end
|
||||
expect_graphql_errors_to_be_empty
|
||||
|
||||
create_list(:work_item, 3, :last_edited_by_user, last_edited_at: 1.week.ago, project: project)
|
||||
|
||||
expect_graphql_errors_to_be_empty
|
||||
expect { post_graphql(query, current_user: current_user) }.not_to exceed_query_limit(control)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when filtering by search' do
|
||||
it_behaves_like 'query with a search term' do
|
||||
let(:issuable_data) { items_data }
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ RSpec.describe 'Query.work_item(id)' do
|
|||
project: project,
|
||||
description: '- List item',
|
||||
start_date: Date.today,
|
||||
due_date: 1.week.from_now
|
||||
due_date: 1.week.from_now,
|
||||
created_at: 1.week.ago,
|
||||
last_edited_at: 1.day.ago,
|
||||
last_edited_by: guest
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -67,6 +70,12 @@ RSpec.describe 'Query.work_item(id)' do
|
|||
... on WorkItemWidgetDescription {
|
||||
description
|
||||
descriptionHtml
|
||||
edited
|
||||
lastEditedBy {
|
||||
webPath
|
||||
username
|
||||
}
|
||||
lastEditedAt
|
||||
}
|
||||
}
|
||||
GRAPHQL
|
||||
|
|
@ -79,7 +88,13 @@ RSpec.describe 'Query.work_item(id)' do
|
|||
hash_including(
|
||||
'type' => 'DESCRIPTION',
|
||||
'description' => work_item.description,
|
||||
'descriptionHtml' => ::MarkupHelper.markdown_field(work_item, :description, {})
|
||||
'descriptionHtml' => ::MarkupHelper.markdown_field(work_item, :description, {}),
|
||||
'edited' => true,
|
||||
'lastEditedAt' => work_item.last_edited_at.iso8601,
|
||||
'lastEditedBy' => {
|
||||
'webPath' => "/#{guest.full_path}",
|
||||
'username' => guest.username
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue