From 625e0888eaf77ac4db5f705a99607bae13c66d9c Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 4 Nov 2015 12:10:50 +1100 Subject: [PATCH] Adding logic to Admin::BaseController to standardise rendering of data with AMS --- .../spree/admin/base_controller_decorator.rb | 19 +++++ .../spree/admin/base_controller_spec.rb | 78 +++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/app/controllers/spree/admin/base_controller_decorator.rb b/app/controllers/spree/admin/base_controller_decorator.rb index 4579e905e7..6ce007adf3 100644 --- a/app/controllers/spree/admin/base_controller_decorator.rb +++ b/app/controllers/spree/admin/base_controller_decorator.rb @@ -66,4 +66,23 @@ Spree::Admin::BaseController.class_eval do def json_request? request.format.json? end + + def render_as_json(data, options={}) + ams_prefix = options.delete :ams_prefix + if [Array, ActiveRecord::Relation].include? data.class + render options.merge(json: data, each_serializer: serializer(ams_prefix)) + else + render options.merge(json: data, serializer: serializer(ams_prefix)) + end + end + + def serializer(ams_prefix) + if ams_prefix_whitelist.include?(ams_prefix) || ams_prefix.nil? + prefix = ams_prefix.andand.classify || "" + name = controller_name.classify + "Api::Admin::#{prefix}#{name}Serializer".constantize + else + raise "Suffix '#{ams_prefix}' not found in ams_prefix_whitelist for #{self.class.name}." + end + end end diff --git a/spec/controllers/spree/admin/base_controller_spec.rb b/spec/controllers/spree/admin/base_controller_spec.rb index c56b3ae0db..8619131d9f 100644 --- a/spec/controllers/spree/admin/base_controller_spec.rb +++ b/spec/controllers/spree/admin/base_controller_spec.rb @@ -35,4 +35,82 @@ describe Spree::Admin::BaseController do "Until you set these up, customers will not be able to shop at these hubs." end end + + describe "rendering as json ActiveModelSerializer" do + context "when data is an object" do + let(:data) { { attr: 'value' } } + + context "when an ams prefix is passed" do + let(:prefix) { "prefix" } + + it "passes a prefix to the serializer method and renders with serializer" do + expect(controller).to receive(:serializer).with(prefix) { "SerializerClass" } + expect(controller).to receive(:render).with({ json: data, serializer: "SerializerClass" }) + controller.send(:render_as_json, data, ams_prefix: prefix) + end + end + + context "when no ams prefix is passed" do + let(:prefix) { "prefix" } + + it "does not pass a prefix to the serializer method and renders with serializer" do + expect(controller).to receive(:serializer).with(prefix) { "SerializerClass" } + expect(controller).to receive(:render).with({ json: data, serializer: "SerializerClass" }) + controller.send(:render_as_json, data, ams_prefix: prefix) + end + end + end + + context "when data is an array" do + let(:data) { [{ attr: 'value' }] } + + context "when an ams prefix is passed" do + let(:prefix) { "prefix" } + + it "passes a prefix to the serializer method and renders with each_serializer" do + expect(controller).to receive(:serializer).with(prefix) { "SerializerClass" } + expect(controller).to receive(:render).with({ json: data, each_serializer: "SerializerClass" }) + controller.send(:render_as_json, data, ams_prefix: prefix) + end + end + + context "when no ams prefix is passed" do + let(:prefix) { "prefix" } + + it "does not pass a prefix to the serializer method and renders with each_serializer" do + expect(controller).to receive(:serializer).with(prefix) { "SerializerClass" } + expect(controller).to receive(:render).with({ json: data, each_serializer: "SerializerClass" }) + controller.send(:render_as_json, data, ams_prefix: prefix) + end + end + end + end + + describe "determining the name of the serializer to be used" do + before do + class Api::Admin::AllowedPrefixAnonymouSerializer;end; + class Api::Admin::AnonymouSerializer;end; + allow(controller).to receive(:ams_prefix_whitelist) { ['allowed_prefix'] } + end + + context "when a prefix is passed in" do + context "and the prefix appears in the whitelist" do + it "returns the requested serializer" do + expect(controller.send(:serializer, 'allowed_prefix')).to eq Api::Admin::AllowedPrefixAnonymouSerializer + end + end + + context "and the prefix does not appear in the whitelist" do + it "raises an error" do + expect{controller.send(:serializer, 'other_prefix')}.to raise_error RuntimeError + end + end + end + + context "when no prefix is passed in" do + it "returns the default serializer" do + expect(controller.send(:serializer, nil)).to eq Api::Admin::AnonymouSerializer + end + end + end end