diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2016-10-28 14:32:07 +0200 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2016-11-02 14:26:57 +0100 |
commit | acfe394018df50bfc08aa9e41265231747675646 (patch) | |
tree | 776b34a9f27c149d8863775f760036b2484ed866 | |
parent | 2023511753d75545aa76968a2991dc962f7a99db (diff) | |
download | gitlab-ce-acfe394018df50bfc08aa9e41265231747675646.tar.gz |
Add PoC for resource serializers
-rw-r--r-- | app/serializers/base_serializer.rb | 24 | ||||
-rw-r--r-- | app/serializers/entity_request.rb | 16 | ||||
-rw-r--r-- | app/serializers/environment_entity.rb | 17 | ||||
-rw-r--r-- | app/serializers/environment_serializer.rb | 3 | ||||
-rw-r--r-- | app/serializers/project_entity.rb | 8 | ||||
-rw-r--r-- | app/serializers/request_aware_entity.rb | 11 | ||||
-rw-r--r-- | spec/serializers/entity_request_spec.rb | 26 | ||||
-rw-r--r-- | spec/serializers/environment_serializer_spec.rb | 35 |
8 files changed, 140 insertions, 0 deletions
diff --git a/app/serializers/base_serializer.rb b/app/serializers/base_serializer.rb new file mode 100644 index 00000000000..f9f7135551b --- /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 00000000000..12ceb38b284 --- /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 00000000000..9415f1dd450 --- /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 00000000000..91955542f25 --- /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 00000000000..b8e23db470b --- /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 00000000000..f6b6f64d0f8 --- /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 00000000000..1c220a7b95d --- /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 00000000000..3470863681c --- /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 |