Merge branch 'bw-serializer-tech-debit' into 'master'
Extract code into IssueBoardEntity / serializer See merge request gitlab-org/gitlab-ce!22760
This commit is contained in:
commit
aa9a662b66
11 changed files with 153 additions and 32 deletions
|
@ -100,18 +100,12 @@ module Boards
|
|||
.merge(board_id: params[:board_id], list_id: params[:list_id], request: request)
|
||||
end
|
||||
|
||||
def serializer
|
||||
IssueSerializer.new(current_user: current_user)
|
||||
end
|
||||
|
||||
def serialize_as_json(resource)
|
||||
resource.as_json(
|
||||
only: [:id, :iid, :project_id, :title, :confidential, :due_date, :relative_position, :weight],
|
||||
labels: true,
|
||||
issue_endpoints: true,
|
||||
include_full_project_path: board.group_board?,
|
||||
include: {
|
||||
project: { only: [:id, :path] },
|
||||
assignees: { only: [:id, :name, :username], methods: [:avatar_url] },
|
||||
milestone: { only: [:id, :title] }
|
||||
}
|
||||
)
|
||||
serializer.represent(resource, serializer: 'board', include_full_project_path: board.group_board?)
|
||||
end
|
||||
|
||||
def whitelist_query_limiting
|
||||
|
|
|
@ -231,20 +231,6 @@ class Issue < ActiveRecord::Base
|
|||
|
||||
def as_json(options = {})
|
||||
super(options).tap do |json|
|
||||
if options.key?(:issue_endpoints) && project
|
||||
url_helper = Gitlab::Routing.url_helpers
|
||||
|
||||
issue_reference = options[:include_full_project_path] ? to_reference(full: true) : to_reference
|
||||
|
||||
json.merge!(
|
||||
reference_path: issue_reference,
|
||||
real_path: url_helper.project_issue_path(project, self),
|
||||
issue_sidebar_endpoint: url_helper.project_issue_path(project, self, format: :json, serializer: 'sidebar'),
|
||||
toggle_subscription_endpoint: url_helper.toggle_subscription_project_issue_path(project, self),
|
||||
assignable_labels_endpoint: url_helper.project_labels_path(project, format: :json, include_ancestor_groups: true)
|
||||
)
|
||||
end
|
||||
|
||||
if options.key?(:labels)
|
||||
json[:labels] = labels.as_json(
|
||||
project: project,
|
||||
|
|
|
@ -180,7 +180,7 @@ def index
|
|||
render json: MyResourceSerializer
|
||||
.new(current_user: @current_user)
|
||||
.represent_details(@project.resources)
|
||||
nd
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
|
@ -196,7 +196,7 @@ def index
|
|||
.represent_details(@project.resources),
|
||||
count: @project.resources.count
|
||||
}
|
||||
nd
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
|
|
51
app/serializers/issue_board_entity.rb
Normal file
51
app/serializers/issue_board_entity.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class IssueBoardEntity < Grape::Entity
|
||||
include RequestAwareEntity
|
||||
|
||||
expose :id
|
||||
expose :iid
|
||||
expose :title
|
||||
|
||||
expose :confidential
|
||||
expose :due_date
|
||||
expose :project_id
|
||||
expose :relative_position
|
||||
expose :weight, if: -> (*) { respond_to?(:weight) }
|
||||
|
||||
expose :project do |issue|
|
||||
API::Entities::Project.represent issue.project, only: [:id, :path]
|
||||
end
|
||||
|
||||
expose :milestone, expose_nil: false do |issue|
|
||||
API::Entities::Project.represent issue.milestone, only: [:id, :title]
|
||||
end
|
||||
|
||||
expose :assignees do |issue|
|
||||
API::Entities::UserBasic.represent issue.assignees, only: [:id, :name, :username, :avatar_url]
|
||||
end
|
||||
|
||||
expose :labels do |issue|
|
||||
LabelEntity.represent issue.labels, project: issue.project, only: [:id, :title, :description, :color, :priority, :text_color]
|
||||
end
|
||||
|
||||
expose :reference_path, if: -> (issue) { issue.project } do |issue, options|
|
||||
options[:include_full_project_path] ? issue.to_reference(full: true) : issue.to_reference
|
||||
end
|
||||
|
||||
expose :real_path, if: -> (issue) { issue.project } do |issue|
|
||||
project_issue_path(issue.project, issue)
|
||||
end
|
||||
|
||||
expose :issue_sidebar_endpoint, if: -> (issue) { issue.project } do |issue|
|
||||
project_issue_path(issue.project, issue, format: :json, serializer: 'sidebar')
|
||||
end
|
||||
|
||||
expose :toggle_subscription_endpoint, if: -> (issue) { issue.project } do |issue|
|
||||
toggle_subscription_project_issue_path(issue.project, issue)
|
||||
end
|
||||
|
||||
expose :assignable_labels_endpoint, if: -> (issue) { issue.project } do |issue|
|
||||
project_labels_path(issue.project, format: :json, include_ancestor_groups: true)
|
||||
end
|
||||
end
|
|
@ -4,15 +4,17 @@ class IssueSerializer < BaseSerializer
|
|||
# This overrided method takes care of which entity should be used
|
||||
# to serialize the `issue` based on `basic` key in `opts` param.
|
||||
# Hence, `entity` doesn't need to be declared on the class scope.
|
||||
def represent(merge_request, opts = {})
|
||||
def represent(issue, opts = {})
|
||||
entity =
|
||||
case opts[:serializer]
|
||||
when 'sidebar'
|
||||
IssueSidebarEntity
|
||||
when 'board'
|
||||
IssueBoardEntity
|
||||
else
|
||||
IssueEntity
|
||||
end
|
||||
|
||||
super(merge_request, opts, entity)
|
||||
super(issue, opts, entity)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,4 +12,8 @@ class LabelEntity < Grape::Entity
|
|||
expose :text_color
|
||||
expose :created_at
|
||||
expose :updated_at
|
||||
|
||||
expose :priority, if: -> (*) { options.key?(:project) } do |label|
|
||||
label.priority(options[:project])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -50,7 +50,7 @@ describe Boards::IssuesController do
|
|||
|
||||
parsed_response = JSON.parse(response.body)
|
||||
|
||||
expect(response).to match_response_schema('issues')
|
||||
expect(response).to match_response_schema('entities/issue_boards')
|
||||
expect(parsed_response['issues'].length).to eq 2
|
||||
expect(development.issues.map(&:relative_position)).not_to include(nil)
|
||||
end
|
||||
|
@ -121,7 +121,7 @@ describe Boards::IssuesController do
|
|||
|
||||
parsed_response = JSON.parse(response.body)
|
||||
|
||||
expect(response).to match_response_schema('issues')
|
||||
expect(response).to match_response_schema('entities/issue_boards')
|
||||
expect(parsed_response['issues'].length).to eq 2
|
||||
end
|
||||
end
|
||||
|
@ -168,7 +168,7 @@ describe Boards::IssuesController do
|
|||
it 'returns the created issue' do
|
||||
create_issue user: user, board: board, list: list1, title: 'New issue'
|
||||
|
||||
expect(response).to match_response_schema('issue')
|
||||
expect(response).to match_response_schema('entities/issue_board')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
38
spec/fixtures/api/schemas/entities/issue_board.json
vendored
Normal file
38
spec/fixtures/api/schemas/entities/issue_board.json
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"type": "object",
|
||||
"properties" : {
|
||||
"id": { "type": "integer" },
|
||||
"iid": { "type": "integer" },
|
||||
"title": { "type": "string" },
|
||||
"confidential": { "type": "boolean" },
|
||||
"due_date": { "type": "date" },
|
||||
"project_id": { "type": "integer" },
|
||||
"relative_position": { "type": ["integer", "null"] },
|
||||
"weight": { "type": "integer" },
|
||||
"project": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "integer" },
|
||||
"path": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"milestone": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "integer" },
|
||||
"title": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"assignees": { "type": ["array", "null"] },
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "label.json" }
|
||||
},
|
||||
"reference_path": { "type": "string" },
|
||||
"real_path": { "type": "string" },
|
||||
"issue_sidebar_endpoint": { "type": "string" },
|
||||
"toggle_subscription_endpoint": { "type": "string" },
|
||||
"assignable_labels_endpoint": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
15
spec/fixtures/api/schemas/entities/issue_boards.json
vendored
Normal file
15
spec/fixtures/api/schemas/entities/issue_boards.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"type": "object",
|
||||
"required" : [
|
||||
"issues",
|
||||
"size"
|
||||
],
|
||||
"properties" : {
|
||||
"issues": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "issue_board.json" }
|
||||
},
|
||||
"size": { "type": "integer" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
23
spec/serializers/issue_board_entity_spec.rb
Normal file
23
spec/serializers/issue_board_entity_spec.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe IssueBoardEntity do
|
||||
let(:project) { create(:project) }
|
||||
let(:resource) { create(:issue, project: project) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
let(:request) { double('request', current_user: user) }
|
||||
|
||||
subject { described_class.new(resource, request: request).as_json }
|
||||
|
||||
it 'has basic attributes' do
|
||||
expect(subject).to include(:id, :iid, :title, :confidential, :due_date, :project_id, :relative_position,
|
||||
:project, :labels)
|
||||
end
|
||||
|
||||
it 'has path and endpoints' do
|
||||
expect(subject).to include(:reference_path, :real_path, :issue_sidebar_endpoint,
|
||||
:toggle_subscription_endpoint, :assignable_labels_endpoint)
|
||||
end
|
||||
end
|
|
@ -24,4 +24,12 @@ describe IssueSerializer do
|
|||
expect(json_entity).to match_schema('entities/issue_sidebar')
|
||||
end
|
||||
end
|
||||
|
||||
context 'board issue serialization' do
|
||||
let(:serializer) { 'board' }
|
||||
|
||||
it 'matches board issue json schema' do
|
||||
expect(json_entity).to match_schema('entities/issue_board')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue