Permalink
Browse files

Collection search - Collections and Resources know their full path

  • Loading branch information...
1 parent 3b8857a commit db4334803264b3d4db66c783d78b8e384c2f7224 @mnoble mnoble committed Mar 14, 2011
Showing with 82 additions and 13 deletions.
  1. +3 −1 .gitignore
  2. +14 −2 lib/aweber/collection.rb
  3. +14 −0 lib/aweber/resource.rb
  4. +40 −1 spec/collection_spec.rb
  5. +10 −9 spec/resource_spec.rb
  6. +1 −0 spec/spec_helper.rb
View
@@ -22,4 +22,6 @@ Gemfile.lock
## PROJECT::SPECIFIC
.yardoc
-.bundle
+.bundle
+examples/staging.rb
+examples/production.rb
View
@@ -32,6 +32,7 @@ class Collection < Resource
attr_reader :prev_collection_link
attr_reader :resource_type_link
attr_reader :total_size
+ attr_reader :parent
alias_method :size, :total_size
alias_method :length, :total_size
@@ -45,10 +46,17 @@ def initialize(client, klass, data={})
@client = client
@klass = klass
@entries = {}
- create_entries(data["entries"])
+ create_entries(data["entries"]) if data.include?("entries")
@_entries = @entries.to_a
end
+ def search(params={})
+ params = params.map { |k, v| "#{k}=#{v}" }.join("&")
+ uri = "#{path}?ws.op=search&#{params}"
+
+ self.class.new(client, @klass, client.get(uri).merge(:parent => parent))
+ end
+
def [](id)
@entries[id] ||= fetch_entry(id)
end
@@ -60,6 +68,10 @@ def each
def inspect
"#<AW::Collection(#{@klass.to_s}) size=\"#{size}\">"
end
+
+ def path
+ parent and parent.path.to_s + @klass.path.to_s or @klass.path.to_s
+ end
private
@@ -73,7 +85,7 @@ def get_entry(n)
end
def fetch_entry(id)
- @klass.new(client, get(File.join(base_path, id.to_s)))
+ @klass.new(client, get(path).merge(:parent => self))
end
def fetch_next_group(amount=20)
View
@@ -16,6 +16,12 @@ class Resource
class << self
attr_accessor :writable_attrs
+ attr_accessor :path
+
+ def basepath(path)
+ @path = path
+ end
+
# Works the same as +alias_method+, but for attributes created via
# +attr*+ methods.
#
@@ -93,6 +99,10 @@ def has_many(name)
alias_attribute :etag, :http_etag
alias_attribute :link, :self_link
alias_attribute :resource_type, :resource_type_link
+
+ def_delegators :client, :get, :post, :put
+
+ attr_reader :parent
def initialize(client, data={})
@client = client
@@ -120,6 +130,10 @@ def writable_attrs
def <=>(other)
@id <=> other.id
end
+
+ def path
+ parent and "#{parent.path}/#{id}" or id.to_s
+ end
private
View
@@ -1,7 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
describe AWeber::Collection do
-
before :each do
@oauth = AWeber::OAuth.new("token", "secret")
@aweber = AWeber::Base.new(@oauth)
@@ -37,4 +36,44 @@
lists = @lists.find_by_resource_type_link("https://api.aweber.com/1.0/#list")
lists.length.should == 3
end
+
+ it "should not have an empty path" do
+ @lists.path.should be_empty
+ end
+
+ it "should create resource with itself as a parent" do
+ collection = AWeber::Collection.new(@aweber, FakeParent)
+ @aweber.stub(:get).and_return({ :name => "Bob" })
+ collection[1].parent.should == collection
+ end
+
+ it "should pass path request through its parent" do
+ root = AWeber::Collection.new(@aweber, FakeParent)
+ leaf = AWeber::Resource.new(@aweber, :id => 1, :parent => root)
+ branch = AWeber::Collection.new(@aweber, FakeChild, :parent => leaf)
+ leafy = AWeber::Resource.new(@aweber, :id => 2, :parent => branch)
+ leafy.path.should == "/parents/1/children/2"
+ end
+
+ context "when searching" do
+ before do
+ @root = AWeber::Collection.new(@aweber, FakeParent)
+ @parent = AWeber::Resource.new(@aweber, :id => 1, :parent => @root)
+ @collection = AWeber::Collection.new(@aweber, FakeChild, :parent => @parent)
+ path = "/parents/1/children?ws.op=search&name=default123456"
+ @aweber.should_receive(:get).with(path).and_return({})
+ end
+
+ it "should search the API" do
+ @collection.search(:name => "default123456")
+ end
+
+ it "should return a new collection" do
+ @collection.search(:name => "default123456").should be_an AWeber::Collection
+ end
+
+ it "should return a new collection with the same parent" do
+ @collection.search(:name => "default123456").parent.should be @collection.parent
+ end
+ end
end
View
@@ -1,14 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
-class FakeResource < AWeber::Resource
- attr_accessor :foo
- api_attr :name, :writable => true
- alias_attribute :bar, :foo
- has_many :lists
-end
-
describe AWeber::Resource do
-
before :each do
@oauth = AWeber::OAuth.new("token", "secret")
@aweber = AWeber::Base.new(@oauth)
@@ -72,9 +64,18 @@ class FakeResource < AWeber::Resource
it "should send a JSON respresentation of the object on save" do
resource = FakeResource.new(@aweber)
- @oauth.should_receive(:put).with(resource.link, "{\"name\":\"Bob\"}")
+ @oauth.should_receive(:put).with(resource.link, "{\"name\":\"Bob\"}", anything)
resource.name = "Bob"
resource.save
end
+ it "should return the id as path when no parent is supplied" do
+ FakeResource.new(@aweber, :id => 1).path.should == "1"
+ end
+
+ it "should have a parent" do
+ parent = AWeber::Collection.new(@aweber, FakeParent)
+ child = AWeber::Resource.new(@aweber, :id => 2, :parent => parent)
+ child.path.should == "/parents/2"
+ end
end
View
@@ -1,6 +1,7 @@
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
require "aweber"
+require "support/fake_classes"
require "fakeweb"
require 'rspec'

0 comments on commit db43348

Please sign in to comment.