diff --git a/app/filters/tim/user_keys_filter.rb b/app/filters/tim/user_keys_filter.rb index fbe4949..643a52a 100644 --- a/app/filters/tim/user_keys_filter.rb +++ b/app/filters/tim/user_keys_filter.rb @@ -4,49 +4,54 @@ module Tim class UserKeysFilter - @@user_keys = { "base_image" => "base_image_attributes", - "image_versions" => "image_versions_attributes", - "image_version" => "image_version_attributes", - "target_images" => "target_image_attributes", - "target_image" => "target_image_attributes", - "provider_images" => "provider_images_attributes", - "provider_image" => "provider_image_attributes", - "template" => "template_attributes" } + @@user_keys = YAML.load(File.read(File.join(Tim::Engine.root, "config", "user_keys.yml"))) def self.before(controller) - begin - resource_name = controller.controller_name.singularize.to_sym - set_template_params(resource_name, controller) - controller.params[resource_name] = replace_user_keys(controller.params[resource_name]) + @controller = controller + resource_name = @controller.controller_name.singularize.to_sym + set_template_params(resource_name) + @controller.params[resource_name] = replace_user_keys(@controller.params[resource_name], @@user_keys[resource_name]) rescue => e - controller.head :unprocessable_entity + @controller.head :unprocessable_entity end end # Replaces all instances of user keys with those defined in @@user_keys # Supports N levels of nested maps. - def self.replace_user_keys(map) + def self.replace_user_keys(map, user_keys) modified_map = map.clone map.each_pair do |key, value| - if @@user_keys.has_key? key + # Sets the full template XML in the template.xml attribute + if key == "template" || key == :template + modified_map[key] = { :xml => template_xml } + end + + if user_keys.has_key? key if map[key].instance_of? Hash # FIXME Using recursion in this way increases heap memory usage. # If we decide to stick with this approach a more memory efficient # implementation should be considered. - modified_map[key] = replace_user_keys(map[key]) + modified_map[key] = replace_user_keys(map[key], user_keys) + elsif map[key].instance_of? Array + modified_map[key] = map[key].collect { |v| replace_user_keys(v, user_keys)} end - modified_map[@@user_keys[key]] = modified_map.delete(key) + modified_map[user_keys[key]] = modified_map.delete(key) end end modified_map end - def self.set_template_params(resource_name, controller) + # We are storing raw XML in the templates.xml attributes. Therefore we + # must retrieve the raw XML from the request body. + def self.set_template_params(resource_name) if resource_name == :template - controller.params[:template] = { :xml => controller.request.body.read } + @controller.params[:template] = { :xml => template_xml } end end + def self.template_xml + ::Nokogiri::XML(@controller.request.body.read).xpath("//template").to_xml + end end end \ No newline at end of file diff --git a/app/views/tim/templates/_template.xml.haml b/app/views/tim/templates/_template.xml.haml index 816a19d..17a3672 100644 --- a/app/views/tim/templates/_template.xml.haml +++ b/app/views/tim/templates/_template.xml.haml @@ -1,5 +1,8 @@ !!! XML %template{:id => template.id, :href => template_url(template.id) } != template.xml_elements + %base_images + - template.base_images.each do |base_image| + = render :partial => 'tim/base_images/base_image_minimal', :locals => {:base_image => base_image} - if controller.template_exists?("custom", "tim/templates", true) = render :partial => 'tim/templates/custom', :locals => {:template => template} \ No newline at end of file diff --git a/config/user_keys.yml b/config/user_keys.yml new file mode 100644 index 0000000..dc323d9 --- /dev/null +++ b/config/user_keys.yml @@ -0,0 +1,26 @@ +:template: + base_image: base_image_attributes + +:base_image: + template: template_attributes + image_versions: image_versions_attributes + target_images: target_images_attributes + provider_images: provider_images_attributes + +:image_version: + template: template_attributes + base_image: base_image_attributes + target_images: target_images_attributes + provider_images: provider_images_attributes + +:target_image: + template: template_attributes + base_image: base_image_attributes + image_version: image_version_attributes + provider_images: provider_images_attributes + +:provider_image: + template: template_attributes + base_image: base_image_attributes + image_version: image_version_attributes + target_image: target_image_attributes \ No newline at end of file diff --git a/spec/controllers/templates_controller_spec.rb b/spec/controllers/templates_controller_spec.rb index 5a9f198..bb6a59b 100644 --- a/spec/controllers/templates_controller_spec.rb +++ b/spec/controllers/templates_controller_spec.rb @@ -22,7 +22,7 @@ module Tim response.code.should == "201" template_xml = ::Nokogiri::XML::Document.parse(response.body) template_xml.xpath("//template/*").to_xml - .should == template.xml_elements + .include?(template.xml_elements).should == true template_xml.xpath("//template/@*").map { |node| node.name} .should =~ ["id", "href"] end diff --git a/spec/filters/user_keys_filter_spec.rb b/spec/filters/user_keys_filter_spec.rb index 82bdec0..cd7f49c 100644 --- a/spec/filters/user_keys_filter_spec.rb +++ b/spec/filters/user_keys_filter_spec.rb @@ -4,17 +4,12 @@ module Tim describe UserKeysFilter do before(:all) do |spec| - @user_keys = UserKeysFilter.class_variable_get(:@@user_keys) - UserKeysFilter.class_variable_set(:@@user_keys, {:k1 => :a1, :k2 => :a2}) - end - - after(:all) do |spec| - UserKeysFilter.class_variable_set(:@@user_keys, @user_keys) + @user_keys = {:k1 => :a1, :k2 => :a2} end describe "replace user keys" do it 'should replace user keys with respective specified alternate' do - hash = UserKeysFilter.replace_user_keys({:k1 => :v1, :k2 => :v2}) + hash = UserKeysFilter.replace_user_keys({:k1 => :v1, :k2 => :v2}, @user_keys) hash[:a1].should == :v1 hash[:a2].should == :v2 hash.has_key?(:k1).should == false @@ -22,7 +17,7 @@ module Tim end it 'should replace nested user keys' do - hash = UserKeysFilter.replace_user_keys({:k1 => {:k2 => :v2}}) + hash = UserKeysFilter.replace_user_keys({:k1 => {:k2 => :v2}}, @user_keys) hash[:a1].should == {:a2 => :v2} end end @@ -33,8 +28,8 @@ module Tim controller.stub(:controller_name).and_return "resources" controller.stub(:params).and_return({:resource => {:k1 => {:k2 => :v2}}}) - UserKeysFilter.should_receive(:replace_user_keys).with({:k1 => {:k2 => :v2}}) - UserKeysFilter.stub(:replace_user_keys).and_return({:a1 => {:a2 => :v2}}) + UserKeysFilter.should_receive(:replace_user_keys).with({:k1 => {:k2 => :v2}}, nil) + UserKeysFilter.stub(:replace_user_keys).and_return({:a1 => {:a2 => :v2}}, nil) UserKeysFilter.before(controller) end