diff --git a/app/serializers/base_serializer.rb b/app/serializers/base_serializer.rb new file mode 100644 index 0000000000000000000000000000000000000000..f9f7135551b50c54c58d932b862e2215efcf4bab --- /dev/null +++ b/app/serializers/base_serializer.rb @@ -0,0 +1,24 @@ +class BaseSerializer + def initialize(request = {}) + @request = EntityRequest.new(request) + @opts = { request: @request } + end + + def set(opts) + @request.merge!(opts) + self + end + + def represent(resource, opts = {}) + self.class.entity_class + .represent(resource, @opts.reverse_merge(opts)) + end + + def self.entity(entity_class) + @entity_class ||= entity_class + end + + def self.entity_class + @entity_class + end +end diff --git a/app/serializers/entity_request.rb b/app/serializers/entity_request.rb new file mode 100644 index 0000000000000000000000000000000000000000..12ceb38b28469e5bc06594ada78908ff5a9717c1 --- /dev/null +++ b/app/serializers/entity_request.rb @@ -0,0 +1,16 @@ +class EntityRequest + # We use EntityRequest object to collect parameters and variables + # from the controller. Because options that are being passed to the entity + # do appear in each entity object in the chain, we need a way to pass data + # that is present in the controller (see #20045). + # + def initialize(parameters) + merge!(parameters) + end + + def merge!(parameters) + parameters.each do |key, value| + define_singleton_method(key) { value } + end + end +end diff --git a/app/serializers/environment_entity.rb b/app/serializers/environment_entity.rb new file mode 100644 index 0000000000000000000000000000000000000000..9415f1dd4505bc6940c1d4fd6acdf6a19501e8b1 --- /dev/null +++ b/app/serializers/environment_entity.rb @@ -0,0 +1,17 @@ +class EnvironmentEntity < Grape::Entity + include RequestAwareEntity + include Gitlab::Routing.url_helpers + + expose :id + expose :name + expose :project, with: ProjectEntity + expose :last_deployment, + as: :deployment, + using: API::Entities::Deployment + + expose :environment_path + + def environment_path + request.path + end +end diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb new file mode 100644 index 0000000000000000000000000000000000000000..91955542f2540bda42e7c0fb58c515a2902ffde5 --- /dev/null +++ b/app/serializers/environment_serializer.rb @@ -0,0 +1,3 @@ +class EnvironmentSerializer < BaseSerializer + entity EnvironmentEntity +end diff --git a/app/serializers/project_entity.rb b/app/serializers/project_entity.rb new file mode 100644 index 0000000000000000000000000000000000000000..b8e23db470b9c243f969fac043ddd7ead26479db --- /dev/null +++ b/app/serializers/project_entity.rb @@ -0,0 +1,8 @@ +class ProjectEntity < Grape::Entity + expose :id + expose :name + + expose :test do |project| + 'something' + end +end diff --git a/app/serializers/request_aware_entity.rb b/app/serializers/request_aware_entity.rb new file mode 100644 index 0000000000000000000000000000000000000000..f6b6f64d0f84ba7d057525bd13f417c35bbd6f52 --- /dev/null +++ b/app/serializers/request_aware_entity.rb @@ -0,0 +1,11 @@ +module RequestAwareEntity + # We use SerializableRequest class to collect parameters and variables + # from the controller. Because options that are being passed to the entity + # are appear in each entity in the chain, we need a way to access data + # that is present in the controller (see #20045). + # + def request + options[:request] || + raise(StandardError, 'Request not set!!') + end +end diff --git a/spec/serializers/entity_request_spec.rb b/spec/serializers/entity_request_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..1c220a7b95d6b4cc471f5c9b89532e3b3c5e19d6 --- /dev/null +++ b/spec/serializers/entity_request_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe EntityRequest do + subject do + described_class.new(user: 'user', project: 'some project') + end + + describe 'methods created' do + it 'defines accessible attributes' do + expect(subject.user).to eq 'user' + expect(subject.project).to eq 'some project' + end + + it 'raises error when attribute is not defined' do + expect { subject.some_method }.to raise_error NoMethodError + end + end + + describe '#merge!' do + before { subject.merge!(build: 'some build') } + + it 'appends parameters' do + expect(subject.build).to eq 'some build' + end + end +end diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..3470863681cab1ac8eb28417bb901a6775c27fa9 --- /dev/null +++ b/spec/serializers/environment_serializer_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe EnvironmentSerializer do + let(:serializer) do + described_class.new(path: 'some path').represent(resource) + end + + context 'when there is a single object provided' do + let(:resource) { create(:environment) } + + it 'shows json' do + puts serializer.to_json + end + + it 'it generates payload for single object' do + expect(parsed_json).to be_an_instance_of Hash + end + end + + context 'when there is a collection of objects provided' do + let(:resource) { create_list(:environment, 2) } + + it 'shows json' do + puts serializer.to_json + end + + it 'generates payload for collection' do + expect(parsed_json).to be_an_instance_of Array + end + end + + def parsed_json + JSON.parse(serializer.to_json) + end +end