Commit 211f728a authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'feature/gb/expose-commit-and-mr-pipelines-api' into 'master'

Expose pipelines API for commits and merge requests

See merge request !8837
parents adc0e41f 8e8ec9d7
......@@ -30,6 +30,17 @@ class Projects::CommitController < Projects::ApplicationController
end
def pipelines
@pipelines = @commit.pipelines.order(id: :desc)
respond_to do |format|
format.html
format.json do
render json: PipelineSerializer
.new(project: @project, user: @current_user)
.with_pagination(request, response)
.represent(@pipelines)
end
end
end
def branches
......
......@@ -214,7 +214,16 @@ class Projects::MergeRequestsController < Projects::ApplicationController
render 'show'
end
format.json { render json: { html: view_to_html_string('projects/merge_requests/show/_pipelines') } }
format.json do
render json: {
html: view_to_html_string('projects/merge_requests/show/_pipelines'),
pipelines: PipelineSerializer
.new(project: @project, user: @current_user)
.with_pagination(request, response)
.represent(@pipelines)
}
end
end
end
......
......@@ -6,6 +6,7 @@ class BaseSerializer
def represent(resource, opts = {})
self.class.entity_class
.represent(resource, opts.merge(request: @request))
.as_json
end
def self.entity(entity_class)
......
class PipelineSerializer < BaseSerializer
entity PipelineEntity
class InvalidResourceError < StandardError; end
include API::Helpers::Pagination
Struct.new('Pagination', :request, :response)
entity PipelineEntity
def represent(resource, opts = {})
if paginated?
raise InvalidResourceError unless resource.respond_to?(:page)
......
- page_title "Pipelines", "#{@commit.title} (#{@commit.short_id})", "Commits"
- page_title 'Pipelines', "#{@commit.title} (#{@commit.short_id})", 'Commits'
= render "commit_box"
= render "ci_menu"
= render "pipelines_list", pipelines: @commit.pipelines.order(id: :desc)
= render 'commit_box'
= render 'ci_menu'
= render 'pipelines_list', pipelines: @pipelines
......@@ -13,7 +13,7 @@ module Gitlab
end
def as_json
AnalyticsStageSerializer.new.represent(self).as_json
AnalyticsStageSerializer.new.represent(self)
end
def title
......
......@@ -18,7 +18,7 @@ module Gitlab
private
def serialize(event)
AnalyticsMergeRequestSerializer.new(project: @project).represent(event).as_json
AnalyticsMergeRequestSerializer.new(project: @project).represent(event)
end
end
end
......
......@@ -16,7 +16,7 @@ module Gitlab
private
def serialize(event)
AnalyticsIssueSerializer.new(project: @project).represent(event).as_json
AnalyticsIssueSerializer.new(project: @project).represent(event)
end
end
end
......
......@@ -37,7 +37,7 @@ module Gitlab
def serialize_commit(event, st_commit, query)
commit = Commit.new(Gitlab::Git::Commit.new(st_commit), @project)
AnalyticsCommitSerializer.new(project: @project, total_time: event['total_time']).represent(commit).as_json
AnalyticsCommitSerializer.new(project: @project, total_time: event['total_time']).represent(commit)
end
end
end
......
......@@ -15,7 +15,7 @@ module Gitlab
end
def serialize(event)
AnalyticsMergeRequestSerializer.new(project: @project).represent(event).as_json
AnalyticsMergeRequestSerializer.new(project: @project).represent(event)
end
end
end
......
......@@ -16,7 +16,7 @@ module Gitlab
private
def serialize(summary_object)
AnalyticsSummarySerializer.new.represent(summary_object).as_json
AnalyticsSummarySerializer.new.represent(summary_object)
end
end
end
......
......@@ -23,7 +23,7 @@ module Gitlab
private
def serialize(event)
AnalyticsBuildSerializer.new.represent(event['build']).as_json
AnalyticsBuildSerializer.new.represent(event['build'])
end
end
end
......
......@@ -4,7 +4,6 @@ describe Projects::CommitController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:commit) { project.commit("master") }
let(:pipeline) { create(:ci_pipeline, project: project, commit: commit) }
let(:master_pickable_sha) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
let(:master_pickable_commit) { project.commit(master_pickable_sha) }
......@@ -322,11 +321,26 @@ describe Projects::CommitController do
end
context 'when the commit exists' do
context 'when the commit has one or more pipelines' do
it 'shows pipelines' do
get_pipelines(id: commit.id)
context 'when the commit has pipelines' do
before do
create(:ci_pipeline, project: project, sha: commit.id)
end
context 'when rendering a HTML format' do
it 'shows pipelines' do
get_pipelines(id: commit.id)
expect(response).to be_ok
end
end
expect(response).to be_ok
context 'when rendering a JSON format' do
it 'responds with serialized pipelines' do
get_pipelines(id: commit.id, format: :json)
expect(response).to be_ok
expect(JSON.parse(response.body)).not_to be_empty
end
end
end
end
......
require 'spec_helper'
describe Projects::MergeRequestsController do
include ApiHelpers
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
......@@ -455,7 +457,7 @@ describe Projects::MergeRequestsController do
it 'renders the diffs template to a string' do
expect(response).to render_template('projects/merge_requests/show/_diffs')
expect(JSON.parse(response.body)).to have_key('html')
expect(json_response).to have_key('html')
end
end
......@@ -494,7 +496,7 @@ describe Projects::MergeRequestsController do
it 'renders the diffs template to a string' do
expect(response).to render_template('projects/merge_requests/show/_diffs')
expect(JSON.parse(response.body)).to have_key('html')
expect(json_response).to have_key('html')
end
end
end
......@@ -662,18 +664,45 @@ describe Projects::MergeRequestsController do
go format: 'json'
expect(response).to render_template('projects/merge_requests/show/_commits')
expect(JSON.parse(response.body)).to have_key('html')
expect(json_response).to have_key('html')
end
end
end
describe 'GET pipelines' do
it_behaves_like "loads labels", :pipelines
before do
create(:ci_pipeline, project: merge_request.source_project,
ref: merge_request.source_branch,
sha: merge_request.diff_head_sha)
end
context 'when using HTML format' do
it_behaves_like "loads labels", :pipelines
end
context 'when using JSON format' do
before do
get :pipelines,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
id: merge_request.iid,
format: :json
end
it 'responds with a rendered HTML partial' do
expect(response)
.to render_template('projects/merge_requests/show/_pipelines')
expect(json_response).to have_key 'html'
end
it 'responds with serialized pipelines' do
expect(json_response).to have_key 'pipelines'
expect(json_response['pipelines']).not_to be_empty
end
end
end
describe 'GET conflicts' do
let(:json_response) { JSON.parse(response.body) }
context 'when the conflicts cannot be resolved in the UI' do
before do
allow_any_instance_of(Gitlab::Conflict::Parser).
......@@ -770,8 +799,6 @@ describe Projects::MergeRequestsController do
end
describe 'GET conflict_for_path' do
let(:json_response) { JSON.parse(response.body) }
def conflict_for_path(path)
get :conflict_for_path,
namespace_id: merge_request_with_conflicts.project.namespace.to_param,
......@@ -826,7 +853,6 @@ describe Projects::MergeRequestsController do
end
context 'POST resolve_conflicts' do
let(:json_response) { JSON.parse(response.body) }
let!(:original_head_sha) { merge_request_with_conflicts.diff_head_sha }
def resolve_conflicts(files)
......@@ -1024,7 +1050,6 @@ describe Projects::MergeRequestsController do
let!(:forked) { create(:project) }
let!(:environment) { create(:environment, project: forked) }
let!(:deployment) { create(:deployment, environment: environment, sha: forked.commit.id, ref: 'master') }
let(:json_response) { JSON.parse(response.body) }
let(:admin) { create(:admin) }
let(:merge_request) do
......
require 'spec_helper'
describe AnalyticsBuildSerializer do
let(:serializer) do
described_class
.new.represent(resource)
end
let(:json) { serializer.as_json }
let(:resource) { create(:ci_build) }
subject { described_class.new.represent(resource) }
context 'when there is a single object provided' do
it 'contains important elements of analyticsBuild' do
expect(json)
expect(subject)
.to include(:name, :branch, :short_sha, :date, :total_time, :url, :author)
end
end
......
require 'spec_helper'
describe AnalyticsIssueSerializer do
let(:serializer) do
subject do
described_class
.new(project: project, entity: :merge_request)
.represent(resource)
end
let(:user) { create(:user) }
let(:json) { serializer.as_json }
let(:project) { create(:project) }
let(:resource) do
{
......@@ -23,7 +22,7 @@ describe AnalyticsIssueSerializer do
context 'when there is a single object provided' do
it 'contains important elements of the issue' do
expect(json).to include(:title, :iid, :created_at, :total_time, :url, :author)
expect(subject).to include(:title, :iid, :created_at, :total_time, :url, :author)
end
end
end
require 'spec_helper'
describe AnalyticsMergeRequestSerializer do
let(:serializer) do
subject do
described_class
.new(project: project, entity: :merge_request)
.represent(resource)
end
let(:user) { create(:user) }
let(:json) { serializer.as_json }
let(:project) { create(:project) }
let(:resource) do
{
......@@ -24,7 +23,7 @@ describe AnalyticsMergeRequestSerializer do
context 'when there is a single object provided' do
it 'contains important elements of the merge request' do
expect(json).to include(:title, :iid, :created_at, :total_time, :url, :author, :state)
expect(subject).to include(:title, :iid, :created_at, :total_time, :url, :author, :state)
end
end
end
require 'spec_helper'
describe AnalyticsStageSerializer do
let(:serializer) do
described_class
.new.represent(resource)
subject do
described_class.new.represent(resource)
end
let(:json) { serializer.as_json }
let(:resource) { Gitlab::CycleAnalytics::CodeStage.new(project: double, options: {}) }
let(:resource) do
Gitlab::CycleAnalytics::CodeStage.new(project: double, options: {})
end
before do
allow_any_instance_of(Gitlab::CycleAnalytics::BaseStage).to receive(:median).and_return(1.12)
......@@ -15,10 +15,10 @@ describe AnalyticsStageSerializer do
end
it 'it generates payload for single object' do
expect(json).to be_kind_of Hash
expect(subject).to be_kind_of Hash
end
it 'contains important elements of AnalyticsStage' do
expect(json).to include(:title, :description, :value)
expect(subject).to include(:title, :description, :value)
end
end
require 'spec_helper'
describe AnalyticsSummarySerializer do
let(:serializer) do
described_class
.new.represent(resource)
subject do
described_class.new.represent(resource)
end
let(:json) { serializer.as_json }
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
let(:resource) do
Gitlab::CycleAnalytics::Summary::Issue.new(project: double,
from: 1.day.ago,
current_user: user)
Gitlab::CycleAnalytics::Summary::Issue
.new(project: double, from: 1.day.ago, current_user: user)
end
before do
allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue).to receive(:value).and_return(1.12)
allow_any_instance_of(Gitlab::CycleAnalytics::Summary::Issue)
.to receive(:value).and_return(1.12)
end
it 'it generates payload for single object' do
expect(json).to be_kind_of Hash
expect(subject).to be_kind_of Hash
end
it 'contains important elements of AnalyticsStage' do
expect(json).to include(:title, :value)
expect(subject).to include(:title, :value)
end
end
require 'spec_helper'
describe EnvironmentSerializer do
let(:serializer) do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:json) do
described_class
.new(user: user, project: project)
.represent(resource)
end
let(:json) { serializer.as_json }
let(:user) { create(:user) }
let(:project) { create(:project) }
context 'when there is a single object provided' do
before do
create(:ci_build, :manual, name: 'manual1',
......
......@@ -7,11 +7,7 @@ describe PipelineSerializer do
described_class.new(user: user)
end
let(:entity) do
serializer.represent(resource)
end
subject { entity.as_json }
subject { serializer.represent(resource) }
describe '#represent' do
context 'when used without pagination' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment