Refine incremental pipeline serializer
This commit is contained in:
parent
f41c3c02b1
commit
b0c6037a3a
|
@ -17,8 +17,12 @@ class Projects::PipelinesController < Projects::ApplicationController
|
||||||
format.html
|
format.html
|
||||||
format.json do
|
format.json do
|
||||||
render json: {
|
render json: {
|
||||||
pipelines: PipelineSerializer.new(project: @project).
|
pipelines: PipelineSerializer
|
||||||
represent(@pipelines, current_user: current_user, last_updated: @last_updated),
|
.incremental(
|
||||||
|
project: @project,
|
||||||
|
user: @current_user,
|
||||||
|
last_updated: @last_updated)
|
||||||
|
.represent
|
||||||
updated_at: Time.now,
|
updated_at: Time.now,
|
||||||
count: {
|
count: {
|
||||||
all: @pipelines_count,
|
all: @pipelines_count,
|
||||||
|
|
|
@ -2,7 +2,8 @@ class PipelineEntity < Grape::Entity
|
||||||
include RequestAwareEntity
|
include RequestAwareEntity
|
||||||
|
|
||||||
expose :id
|
expose :id
|
||||||
expose :user, if: -> (pipeline, opts) { created?(pipeline, opts) }, using: UserEntity
|
expose :user, if: proc { created_exposure? }, using: UserEntity
|
||||||
|
|
||||||
expose :url do |pipeline|
|
expose :url do |pipeline|
|
||||||
namespace_project_pipeline_path(
|
namespace_project_pipeline_path(
|
||||||
pipeline.project.namespace,
|
pipeline.project.namespace,
|
||||||
|
@ -10,7 +11,7 @@ class PipelineEntity < Grape::Entity
|
||||||
pipeline)
|
pipeline)
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :details, if: -> (pipeline, opts) { updated?(pipeline, opts) } do
|
expose :details, if: proc { updated_exposure? } do
|
||||||
expose :status
|
expose :status
|
||||||
expose :duration
|
expose :duration
|
||||||
expose :finished_at
|
expose :finished_at
|
||||||
|
@ -19,18 +20,20 @@ class PipelineEntity < Grape::Entity
|
||||||
expose :manual_actions, using: PipelineActionEntity
|
expose :manual_actions, using: PipelineActionEntity
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :flags, if: -> (pipeline, opts) { created?(pipeline, opts) } do
|
expose :flags, if: proc { created_exposure? } do
|
||||||
expose :latest?, as: :latest
|
expose :latest?, as: :latest
|
||||||
expose :triggered?, as: :triggered
|
expose :triggered?, as: :triggered
|
||||||
|
|
||||||
expose :yaml_errors?, as: :yaml_errors do |pipeline|
|
expose :yaml_errors?, as: :yaml_errors do |pipeline|
|
||||||
pipeline.yaml_errors.present?
|
pipeline.yaml_errors.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :stuck?, as: :stuck do |pipeline|
|
expose :stuck?, as: :stuck do |pipeline|
|
||||||
pipeline.builds.any?(&:stuck?)
|
pipeline.builds.any?(&:stuck?)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :ref, if: -> (pipeline, opts) { created?(pipeline, opts) } do
|
expose :ref, if: proc { updated_exposure? } do
|
||||||
expose :name do |pipeline|
|
expose :name do |pipeline|
|
||||||
pipeline.ref
|
pipeline.ref
|
||||||
end
|
end
|
||||||
|
@ -45,31 +48,43 @@ class PipelineEntity < Grape::Entity
|
||||||
expose :tag?
|
expose :tag?
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :commit, if: -> (pipeline, opts) { created?(pipeline, opts) }, using: CommitEntity
|
expose :commit, if: proc { created_exposure? }, using: CommitEntity
|
||||||
|
|
||||||
expose :retry_url, if: -> (pipeline, opts) { updated?(pipeline, opts) } do |pipeline|
|
expose :retry_url, if: proc { updated_exposure? } do |pipeline|
|
||||||
can?(current_user, :update_pipeline, pipeline.project) &&
|
can?(request.user, :update_pipeline, pipeline.project) &&
|
||||||
pipeline.retryable? &&
|
pipeline.retryable? &&
|
||||||
retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id)
|
retry_namespace_project_pipeline_path(pipeline.project.namespace,
|
||||||
|
pipeline.project, pipeline.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :cancel_url, if: -> (pipeline, opts) { updated?(pipeline, opts) } do |pipeline|
|
expose :cancel_url, if: proc { updated_exposure? } do |pipeline|
|
||||||
can?(current_user, :update_pipeline, pipeline.project) &&
|
can?(request.user, :update_pipeline, pipeline.project) &&
|
||||||
pipeline.cancelable? &&
|
pipeline.cancelable? &&
|
||||||
cancel_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id)
|
cancel_namespace_project_pipeline_path(pipeline.project.namespace,
|
||||||
|
pipeline.project, pipeline.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
def created_exposure?
|
||||||
|
!incremental? || created?
|
||||||
def last_updated(opts)
|
|
||||||
opts.fetch(:last_updated)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def created?(pipeline, opts)
|
def updated_exposure?
|
||||||
!last_updated(opts) || pipeline.created_at > last_updated(opts)
|
!incremental? || updated?
|
||||||
end
|
end
|
||||||
|
|
||||||
def updated?(pipeline, opts)
|
def incremental?
|
||||||
!last_updated(opts) || pipeline.updated_at > last_updated(opts)
|
options[:incremental]
|
||||||
|
end
|
||||||
|
|
||||||
|
def last_updated
|
||||||
|
options.fetch(:last_updated)
|
||||||
|
end
|
||||||
|
|
||||||
|
def updated?
|
||||||
|
@object.updated_at > last_updated
|
||||||
|
end
|
||||||
|
|
||||||
|
def created?
|
||||||
|
@object.created_at > last_updated
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
class PipelineSerializer < BaseSerializer
|
class PipelineSerializer < BaseSerializer
|
||||||
entity PipelineEntity
|
entity PipelineEntity
|
||||||
|
|
||||||
|
def incremental(resource, last_updated)
|
||||||
|
represent(resource, incremental: true,
|
||||||
|
last_updated: last_updated)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe PipelineSerializer do
|
||||||
|
let(:serializer) do
|
||||||
|
described_class.new(user: user)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:pipelines) do
|
||||||
|
create_list(:ci_pipeline, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
context 'when using incremental serializer' do
|
||||||
|
let(:json) do
|
||||||
|
serializer.incremental(pipelines, time).as_json
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when pipeline has been already updated' do
|
||||||
|
let(:time) { Time.now }
|
||||||
|
|
||||||
|
it 'exposes only minimal information' do
|
||||||
|
expect(json.first.keys).to contain_exactly(:id, :url)
|
||||||
|
expect(json.second.keys).to contain_exactly(:id, :url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when pipeline updated in the meantime' do
|
||||||
|
let(:time) { Time.now - 10.minutes }
|
||||||
|
|
||||||
|
it 'exposes new data incrementally' do
|
||||||
|
expect(json.first.keys.count).to eq 9
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue