|
| 1 | +require 'spec_helper' |
| 2 | + |
| 3 | +describe Grape::Entity do |
| 4 | + let(:fresh_class){ Class.new(Grape::Entity) } |
| 5 | + |
| 6 | + context 'class methods' do |
| 7 | + subject{ fresh_class } |
| 8 | + |
| 9 | + describe '.expose' do |
| 10 | + context 'multiple attributes' do |
| 11 | + it 'should be able to add multiple exposed attributes with a single call' do |
| 12 | + subject.expose :name, :email, :location |
| 13 | + subject.exposures.size.should == 3 |
| 14 | + end |
| 15 | + |
| 16 | + it 'should set the same options for all exposures passed' do |
| 17 | + subject.expose :name, :email, :location, :foo => :bar |
| 18 | + subject.exposures.values.each{|v| v.should == {:foo => :bar}} |
| 19 | + end |
| 20 | + end |
| 21 | + |
| 22 | + context 'option validation' do |
| 23 | + it 'should make sure that :as only works on single attribute calls' do |
| 24 | + expect{ subject.expose :name, :email, :as => :foo }.to raise_error(ArgumentError) |
| 25 | + expect{ subject.expose :name, :as => :foo }.not_to raise_error |
| 26 | + end |
| 27 | + end |
| 28 | + end |
| 29 | + |
| 30 | + describe '.represent' do |
| 31 | + it 'should return a single entity if called with one object' do |
| 32 | + subject.represent(Object.new).should be_kind_of(subject) |
| 33 | + end |
| 34 | + |
| 35 | + it 'should return multiple entities if called with a collection' do |
| 36 | + representation = subject.represent(4.times.map{Object.new}) |
| 37 | + representation.should be_kind_of(Array) |
| 38 | + representation.size.should == 4 |
| 39 | + representation.reject{|r| r.kind_of?(subject)}.should be_empty |
| 40 | + end |
| 41 | + |
| 42 | + it 'should add the :collection => true option if called with a collection' do |
| 43 | + representation = subject.represent(4.times.map{Object.new}) |
| 44 | + representation.each{|r| r.options[:collection].should be_true} |
| 45 | + end |
| 46 | + end |
| 47 | + |
| 48 | + describe '#initialize' do |
| 49 | + it 'should take an object and an optional options hash' do |
| 50 | + expect{ subject.new(Object.new) }.not_to raise_error |
| 51 | + expect{ subject.new }.to raise_error(ArgumentError) |
| 52 | + expect{ subject.new(Object.new, {}) }.not_to raise_error |
| 53 | + end |
| 54 | + |
| 55 | + it 'should have attribute readers for the object and options' do |
| 56 | + entity = subject.new('abc', {}) |
| 57 | + entity.object.should == 'abc' |
| 58 | + entity.options.should == {} |
| 59 | + end |
| 60 | + end |
| 61 | + end |
| 62 | + |
| 63 | + context 'instance methods' do |
| 64 | + let(:model){ mock(attributes) } |
| 65 | + let(:attributes){ { |
| 66 | + :name => 'Bob Bobson', |
| 67 | + |
| 68 | + :friends => [ |
| 69 | + mock(:name => "Friend 1", :email => '[email protected]', :friends => []), |
| 70 | + mock(:name => "Friend 2", :email => '[email protected]', :friends => []) |
| 71 | + ] |
| 72 | + } } |
| 73 | + subject{ fresh_class.new(model) } |
| 74 | + |
| 75 | + describe '#serializable_hash' do |
| 76 | + end |
| 77 | + |
| 78 | + describe '#value_for' do |
| 79 | + before do |
| 80 | + fresh_class.class_eval do |
| 81 | + expose :name, :email |
| 82 | + expose :friends, :using => self |
| 83 | + end |
| 84 | + end |
| 85 | + |
| 86 | + it 'should pass through bare expose attributes' do |
| 87 | + subject.send(:value_for, :name).should == attributes[:name] |
| 88 | + end |
| 89 | + |
| 90 | + it 'should instantiate a representation if that is called for' do |
| 91 | + rep = subject.send(:value_for, :friends) |
| 92 | + rep.reject{|r| r.is_a?(fresh_class)}.should be_empty |
| 93 | + rep.first.serializable_hash[:name].should == 'Friend 1' |
| 94 | + rep.last.serializable_hash[:name].should == 'Friend 2' |
| 95 | + end |
| 96 | + end |
| 97 | + |
| 98 | + describe '#key_for' do |
| 99 | + it 'should return the attribute if no :as is set' do |
| 100 | + fresh_class.expose :name |
| 101 | + subject.send(:key_for, :name).should == :name |
| 102 | + end |
| 103 | + |
| 104 | + it 'should return a symbolized version of the attribute' do |
| 105 | + fresh_class.expose :name |
| 106 | + subject.send(:key_for, 'name').should == :name |
| 107 | + end |
| 108 | + |
| 109 | + it 'should return the :as alias if one exists' do |
| 110 | + fresh_class.expose :name, :as => :nombre |
| 111 | + subject.send(:key_for, 'name').should == :nombre |
| 112 | + end |
| 113 | + end |
| 114 | + |
| 115 | + describe '#conditions_met?' do |
| 116 | + it 'should only pass through hash :if exposure if all attributes match' do |
| 117 | + exposure_options = {:if => {:condition1 => true, :condition2 => true}} |
| 118 | + |
| 119 | + subject.send(:conditions_met?, exposure_options, {}).should be_false |
| 120 | + subject.send(:conditions_met?, exposure_options, :condition1 => true).should be_false |
| 121 | + subject.send(:conditions_met?, exposure_options, :condition1 => true, :condition2 => true).should be_true |
| 122 | + subject.send(:conditions_met?, exposure_options, :condition1 => false, :condition2 => true).should be_false |
| 123 | + subject.send(:conditions_met?, exposure_options, :condition1 => true, :condition2 => true, :other => true).should be_true |
| 124 | + end |
| 125 | + |
| 126 | + it 'should only pass through proc :if exposure if it returns truthy value' do |
| 127 | + exposure_options = {:if => lambda{|obj,opts| opts[:true]}} |
| 128 | + |
| 129 | + subject.send(:conditions_met?, exposure_options, :true => false).should be_false |
| 130 | + subject.send(:conditions_met?, exposure_options, :true => true).should be_true |
| 131 | + end |
| 132 | + |
| 133 | + it 'should only pass through hash :unless exposure if any attributes do not match' do |
| 134 | + exposure_options = {:unless => {:condition1 => true, :condition2 => true}} |
| 135 | + |
| 136 | + subject.send(:conditions_met?, exposure_options, {}).should be_true |
| 137 | + subject.send(:conditions_met?, exposure_options, :condition1 => true).should be_false |
| 138 | + subject.send(:conditions_met?, exposure_options, :condition1 => true, :condition2 => true).should be_false |
| 139 | + subject.send(:conditions_met?, exposure_options, :condition1 => false, :condition2 => true).should be_false |
| 140 | + subject.send(:conditions_met?, exposure_options, :condition1 => true, :condition2 => true, :other => true).should be_false |
| 141 | + subject.send(:conditions_met?, exposure_options, :condition1 => false, :condition2 => false).should be_true |
| 142 | + end |
| 143 | + |
| 144 | + it 'should only pass through proc :unless exposure if it returns falsy value' do |
| 145 | + exposure_options = {:unless => lambda{|object,options| options[:true] == true}} |
| 146 | + |
| 147 | + subject.send(:conditions_met?, exposure_options, :true => false).should be_true |
| 148 | + subject.send(:conditions_met?, exposure_options, :true => true).should be_false |
| 149 | + end |
| 150 | + end |
| 151 | + end |
| 152 | +end |
0 commit comments