ruby-trello-wgibbs 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +37 -0
- data/lib/trello/action.rb +46 -0
- data/lib/trello/association.rb +11 -0
- data/lib/trello/association_proxy.rb +42 -0
- data/lib/trello/authorization.rb +114 -0
- data/lib/trello/basic_data.rb +84 -0
- data/lib/trello/board.rb +95 -0
- data/lib/trello/card.rb +162 -0
- data/lib/trello/checklist.rb +82 -0
- data/lib/trello/client.rb +49 -0
- data/lib/trello/has_actions.rb +9 -0
- data/lib/trello/item.rb +18 -0
- data/lib/trello/item_state.rb +23 -0
- data/lib/trello/label.rb +19 -0
- data/lib/trello/list.rb +71 -0
- data/lib/trello/member.rb +93 -0
- data/lib/trello/multi_association.rb +10 -0
- data/lib/trello/net.rb +37 -0
- data/lib/trello/notification.rb +48 -0
- data/lib/trello/organization.rb +47 -0
- data/lib/trello/string.rb +36 -0
- data/lib/trello/token.rb +24 -0
- data/lib/trello.rb +83 -0
- data/spec/action_spec.rb +71 -0
- data/spec/basic_auth_policy_spec.rb +56 -0
- data/spec/board_spec.rb +196 -0
- data/spec/card_spec.rb +213 -0
- data/spec/checklist_spec.rb +50 -0
- data/spec/client_spec.rb +131 -0
- data/spec/integration/how_to_authorize_spec.rb +53 -0
- data/spec/integration/how_to_use_boards_spec.rb +48 -0
- data/spec/integration/integration_test.rb +40 -0
- data/spec/item_spec.rb +27 -0
- data/spec/item_state_spec.rb +0 -0
- data/spec/list_spec.rb +50 -0
- data/spec/member_spec.rb +92 -0
- data/spec/notification_spec.rb +83 -0
- data/spec/oauth_policy_spec.rb +93 -0
- data/spec/organization_spec.rb +26 -0
- data/spec/spec_helper.rb +244 -0
- data/spec/string_spec.rb +50 -0
- data/spec/token_spec.rb +33 -0
- metadata +220 -0
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            include Trello::Authorization
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe BasicAuthPolicy do
         | 
| 6 | 
            +
              before do
         | 
| 7 | 
            +
                BasicAuthPolicy.developer_public_key = "xxx"
         | 
| 8 | 
            +
                BasicAuthPolicy.member_token = "xxx"
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              it "adds key and token query parameters" do
         | 
| 12 | 
            +
                BasicAuthPolicy.developer_public_key = "xxx_developer_public_key_xxx"
         | 
| 13 | 
            +
                BasicAuthPolicy.member_token = "xxx_member_token_xxx"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                uri = Addressable::URI.parse("https://xxx/")
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                request = Request.new :get, uri
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                authorized_request = BasicAuthPolicy.authorize request
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                the_query_parameters = Addressable::URI.parse(authorized_request.uri).query_values
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                the_query_parameters["key"].should === "xxx_developer_public_key_xxx"
         | 
| 24 | 
            +
                the_query_parameters["token"].should === "xxx_member_token_xxx"
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              it "preserves other query parameters" do
         | 
| 28 | 
            +
                uri = Addressable::URI.parse("https://xxx/?name=Phil")
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                request = Request.new :get, uri, {:example_header => "example_value"}
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                authorized_request = BasicAuthPolicy.authorize request
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                the_query_parameters = Addressable::URI.parse(authorized_request.uri).query_values
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                the_query_parameters["name"].should == "Phil"
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              it "preserves headers" do
         | 
| 40 | 
            +
                uri = Addressable::URI.parse("https://xxx/")
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                request = Request.new :get, uri, {:example_header => "example_value"}
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                authorized_request = BasicAuthPolicy.authorize request
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                authorized_request.headers.should === request.headers
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              it "returns nil body if one is supplied" do
         | 
| 50 | 
            +
                uri = Addressable::URI.parse("https://xxx/")
         | 
| 51 | 
            +
                request = Request.new :get, uri, {}, "any body"
         | 
| 52 | 
            +
                BasicAuthPolicy.authorize(request).body.should be_nil
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              it "does what when a query parameter already exists called key or token?"
         | 
| 56 | 
            +
            end
         | 
    
        data/spec/board_spec.rb
    ADDED
    
    | @@ -0,0 +1,196 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Trello
         | 
| 4 | 
            +
              describe Board do
         | 
| 5 | 
            +
                include Helpers
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                before(:each) do
         | 
| 8 | 
            +
                  Client.stub(:get).with("/boards/abcdef123456789123456789").
         | 
| 9 | 
            +
                    and_return JSON.generate(boards_details.first)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  @board = Board.find('abcdef123456789123456789')
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                context "fields" do
         | 
| 15 | 
            +
                  it "gets an id" do
         | 
| 16 | 
            +
                    @board.id.should_not be_nil
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  it "gets a name" do
         | 
| 20 | 
            +
                    @board.name.should_not be_nil
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  it "gets the description" do
         | 
| 24 | 
            +
                    @board.description.should_not be_nil
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  it "knows if it is closed or open" do
         | 
| 28 | 
            +
                    @board.closed?.should_not be_nil
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  it "gets its url" do
         | 
| 32 | 
            +
                    @board.url.should_not be_nil
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                context "actions" do
         | 
| 37 | 
            +
                  it "has a list of actions" do
         | 
| 38 | 
            +
                    Client.stub(:get).with("/boards/abcdef123456789123456789/actions", {:filter => :all}).
         | 
| 39 | 
            +
                      and_return actions_payload
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    @board.actions.count.should be > 0
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                context "cards" do
         | 
| 46 | 
            +
                  it "gets its list of cards" do
         | 
| 47 | 
            +
                    Client.stub(:get).with("/boards/abcdef123456789123456789/cards", { :filter => :open }).
         | 
| 48 | 
            +
                      and_return cards_payload
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    @board.cards.count.should be > 0
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                context "lists" do
         | 
| 55 | 
            +
                  it "has a list of lists" do
         | 
| 56 | 
            +
                    Client.stub(:get).with("/boards/abcdef123456789123456789/lists", hash_including(:filter => :open)).
         | 
| 57 | 
            +
                      and_return lists_payload
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    @board.has_lists?.should be true
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                context "members" do
         | 
| 64 | 
            +
                  it "has a list of members" do
         | 
| 65 | 
            +
                    Client.stub(:get).with("/boards/abcdef123456789123456789/members", hash_including(:filter => :all)).
         | 
| 66 | 
            +
                      and_return JSON.generate([user_details])
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                    @board.members.count.should be > 0
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                context "organization" do
         | 
| 73 | 
            +
                  it "belongs to an organization" do
         | 
| 74 | 
            +
                    Client.stub(:get).with("/organizations/abcdef123456789123456789").
         | 
| 75 | 
            +
                      and_return JSON.generate(orgs_details.first)
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    @board.organization.should_not be_nil
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                it "is not closed" do
         | 
| 82 | 
            +
                  @board.closed?.should_not be_true
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
              describe "#update_fields" do
         | 
| 87 | 
            +
                it "does not set any fields when the fields argument is empty" do
         | 
| 88 | 
            +
                  expected = {
         | 
| 89 | 
            +
                   'id' => "id",
         | 
| 90 | 
            +
                   'name' => "name",
         | 
| 91 | 
            +
                   'desc' => "desc",
         | 
| 92 | 
            +
                   'closed' => false,
         | 
| 93 | 
            +
                   'url' => "url",
         | 
| 94 | 
            +
                   'idOrganization' => "org_id"
         | 
| 95 | 
            +
                  }
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  board = Board.new(expected)
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                  board.update_fields({})
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                  expected.each_pair do |key, value|
         | 
| 102 | 
            +
                    if board.respond_to?(key)
         | 
| 103 | 
            +
                      board.send(key).should == value
         | 
| 104 | 
            +
                    end
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  board.description.should == expected['desc']
         | 
| 108 | 
            +
                  board.organization_id.should == expected['idOrganization']
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                it "sets any attributes supplied in the fields argument"
         | 
| 112 | 
            +
              end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
              describe "#save" do
         | 
| 115 | 
            +
                include Helpers
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                let(:any_board_json) do
         | 
| 118 | 
            +
                  JSON.generate(boards_details.first)      
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                it "cannot currently save a new instance" do
         | 
| 122 | 
            +
                  Client.should_not_receive :put
         | 
| 123 | 
            +
                  
         | 
| 124 | 
            +
                  the_new_board = Board.new
         | 
| 125 | 
            +
                  lambda{the_new_board.save}.should raise_error
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                it "puts all fields except id" do
         | 
| 129 | 
            +
                  expected_fields = %w{name description closed}.map{|s| s.to_sym}
         | 
| 130 | 
            +
                    
         | 
| 131 | 
            +
                  Client.should_receive(:put) do |anything, body|
         | 
| 132 | 
            +
                    body.keys.should =~ expected_fields
         | 
| 133 | 
            +
                    any_board_json
         | 
| 134 | 
            +
                  end
         | 
| 135 | 
            +
                  
         | 
| 136 | 
            +
                  the_new_board = Board.new 'id' => "xxx"
         | 
| 137 | 
            +
                  the_new_board.save
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                it "mutates the current instance" do
         | 
| 141 | 
            +
                  Client.stub(:put).and_return any_board_json
         | 
| 142 | 
            +
                  
         | 
| 143 | 
            +
                  board = Board.new 'id' => "xxx"
         | 
| 144 | 
            +
                  
         | 
| 145 | 
            +
                  the_result_of_save = board.save
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                  the_result_of_save.should equal board
         | 
| 148 | 
            +
                end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                it "uses the correct resource" do
         | 
| 151 | 
            +
                  expected_resource_id = "xxx_board_id_xxx"
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  Client.should_receive(:put) do |path, anything|
         | 
| 154 | 
            +
                    path.should =~ /#{expected_resource_id}\/$/
         | 
| 155 | 
            +
                    any_board_json
         | 
| 156 | 
            +
                  end
         | 
| 157 | 
            +
                  
         | 
| 158 | 
            +
                  the_new_board = Board.new 'id' => expected_resource_id
         | 
| 159 | 
            +
                  the_new_board.save
         | 
| 160 | 
            +
                end 
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                it "saves OR updates depending on whether or not it has an id set"
         | 
| 163 | 
            +
              end
         | 
| 164 | 
            +
              
         | 
| 165 | 
            +
              describe "Repository" do
         | 
| 166 | 
            +
                include Helpers
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                let(:any_board_json) do
         | 
| 169 | 
            +
                  JSON.generate(boards_details.first)      
         | 
| 170 | 
            +
                end
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                it "creates a new board with whatever attributes are supplied " do
         | 
| 173 | 
            +
                  expected_attributes = { :name => "Any new board name", :description => "Any new board desription" }
         | 
| 174 | 
            +
                  sent_attributes = { :name => expected_attributes[:name], :desc => expected_attributes[:description] }
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                  Client.should_receive(:post).with("/boards", sent_attributes).and_return any_board_json
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                  Board.create expected_attributes
         | 
| 179 | 
            +
                end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                it "posts to the boards collection" do
         | 
| 182 | 
            +
                  Client.should_receive(:post).with("/boards", anything).and_return any_board_json
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                  Board.create :xxx => ""
         | 
| 185 | 
            +
                end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                it "returns a board" do
         | 
| 188 | 
            +
                  Client.stub(:post).with("/boards", anything).and_return any_board_json
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                  the_new_board = Board.create :xxx => ""
         | 
| 191 | 
            +
                  the_new_board.should be_a Board
         | 
| 192 | 
            +
                end
         | 
| 193 | 
            +
                
         | 
| 194 | 
            +
                it "at least name is required"
         | 
| 195 | 
            +
              end
         | 
| 196 | 
            +
            end
         | 
    
        data/spec/card_spec.rb
    ADDED
    
    | @@ -0,0 +1,213 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Trello
         | 
| 4 | 
            +
              describe Card do
         | 
| 5 | 
            +
                include Helpers
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                before(:each) do
         | 
| 8 | 
            +
                  Client.stub(:get).with("/cards/abcdef123456789123456789").
         | 
| 9 | 
            +
                    and_return JSON.generate(cards_details.first)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  @card = Card.find('abcdef123456789123456789')
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                context "creating" do
         | 
| 15 | 
            +
                  it "creates a new record" do
         | 
| 16 | 
            +
                    card = Card.new(cards_details.first)
         | 
| 17 | 
            +
                    card.should be_valid
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  it 'must not be valid if not given a name' do
         | 
| 21 | 
            +
                    card = Card.new('idList' => lists_details.first['id'])
         | 
| 22 | 
            +
                    card.should_not be_valid
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  it 'must not be valid if not given a list id' do
         | 
| 26 | 
            +
                    card = Card.new('name' => lists_details.first['name'])
         | 
| 27 | 
            +
                    card.should_not be_valid
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  it 'creates a new record and saves it on Trello', :refactor => true do
         | 
| 31 | 
            +
                    payload = {
         | 
| 32 | 
            +
                      :name    => 'Test Card',
         | 
| 33 | 
            +
                      :desc    => '',
         | 
| 34 | 
            +
                    }
         | 
| 35 | 
            +
             
         | 
| 36 | 
            +
                    result = JSON.generate(cards_details.first.merge(payload.merge(:idList => lists_details.first['id'])))
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    expected_payload = {:name => "Test Card", :desc => nil, :idList => "abcdef123456789123456789"}
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                    Client.should_receive(:post).with("/cards", expected_payload).and_return result
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    card = Card.create(cards_details.first.merge(payload.merge(:list_id => lists_details.first['id'])))
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    card.class.should be Card
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                context "updating" do
         | 
| 49 | 
            +
                  it "updating name does a put on the correct resource with the correct value" do
         | 
| 50 | 
            +
                    expected_new_name = "xxx"
         | 
| 51 | 
            +
                    expected_resource = "/card/#{@card.id}/name"
         | 
| 52 | 
            +
                    payload = {
         | 
| 53 | 
            +
                      :name      => expected_new_name,
         | 
| 54 | 
            +
                      :desc      => "Awesome things are awesome.",
         | 
| 55 | 
            +
                      :due       => nil,
         | 
| 56 | 
            +
                      :closed    => false,
         | 
| 57 | 
            +
                      :idList    => "abcdef123456789123456789",
         | 
| 58 | 
            +
                      :idBoard   => "abcdef123456789123456789",
         | 
| 59 | 
            +
                      :idMembers => ["abcdef123456789123456789"]
         | 
| 60 | 
            +
                    }
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    Client.should_receive(:put).once.with("/cards/abcdef123456789123456789", payload)
         | 
| 63 | 
            +
                    card = @card.dup
         | 
| 64 | 
            +
                    card.name = expected_new_name
         | 
| 65 | 
            +
                    card.save
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                context "fields" do
         | 
| 70 | 
            +
                  it "gets its id" do
         | 
| 71 | 
            +
                    @card.id.should_not be_nil
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  it "gets its short id" do
         | 
| 75 | 
            +
                    @card.short_id.should_not be_nil
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  it "gets its name" do
         | 
| 79 | 
            +
                    @card.name.should_not be_nil
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  it "gets its description" do
         | 
| 83 | 
            +
                    @card.description.should_not be_nil
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  it "knows if it is open or closed" do
         | 
| 87 | 
            +
                    @card.closed.should_not be_nil
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  it "gets its url" do
         | 
| 91 | 
            +
                    @card.url.should_not be_nil
         | 
| 92 | 
            +
                  end
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                context "actions" do
         | 
| 96 | 
            +
                  it "asks for all actions by default" do
         | 
| 97 | 
            +
                    Client.stub(:get).with("/cards/abcdef123456789123456789/actions", { :filter => :all }).and_return actions_payload
         | 
| 98 | 
            +
                    @card.actions.count.should be > 0
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                  it "allows overriding the filter" do
         | 
| 102 | 
            +
                    Client.stub(:get).with("/cards/abcdef123456789123456789/actions", { :filter => :updateCard }).and_return actions_payload
         | 
| 103 | 
            +
                    @card.actions(:filter => :updateCard).count.should be > 0
         | 
| 104 | 
            +
                  end
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                context "boards" do
         | 
| 108 | 
            +
                  it "has a board" do
         | 
| 109 | 
            +
                    Client.stub(:get).with("/boards/abcdef123456789123456789").and_return JSON.generate(boards_details.first)
         | 
| 110 | 
            +
                    @card.board.should_not be_nil
         | 
| 111 | 
            +
                  end
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                context "checklists" do
         | 
| 115 | 
            +
                  it "has a list of checklists" do
         | 
| 116 | 
            +
                    Client.stub(:get).with("/cards/abcdef123456789123456789/checklists", { :filter => :all }).and_return checklists_payload
         | 
| 117 | 
            +
                    @card.checklists.count.should be > 0
         | 
| 118 | 
            +
                  end
         | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                context "list" do
         | 
| 122 | 
            +
                  it 'has a list' do
         | 
| 123 | 
            +
                    Client.stub(:get).with("/lists/abcdef123456789123456789").and_return JSON.generate(lists_details.first)
         | 
| 124 | 
            +
                    @card.list.should_not be_nil
         | 
| 125 | 
            +
                  end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                  it 'can be moved to another list' do
         | 
| 128 | 
            +
                    other_list = stub(:id => '987654321987654321fedcba')
         | 
| 129 | 
            +
                    payload = {:value => other_list.id}
         | 
| 130 | 
            +
                    Client.should_receive(:put).with("/cards/abcdef123456789123456789/idList", payload)
         | 
| 131 | 
            +
                    @card.move_to_list(other_list)
         | 
| 132 | 
            +
                  end
         | 
| 133 | 
            +
                end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                context "members" do
         | 
| 136 | 
            +
                  it "has a list of members" do
         | 
| 137 | 
            +
                    Client.stub(:get).with("/boards/abcdef123456789123456789").and_return JSON.generate(boards_details.first)
         | 
| 138 | 
            +
                    Client.stub(:get).with("/members/abcdef123456789123456789").and_return user_payload
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                    @card.board.should_not be_nil
         | 
| 141 | 
            +
                    @card.members.should_not be_nil
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                  it "allows a member to be added to a card" do
         | 
| 145 | 
            +
                    new_member = stub(:id => '4ee7df3ce582acdec80000b2')
         | 
| 146 | 
            +
                    payload = {
         | 
| 147 | 
            +
                      :value => new_member.id
         | 
| 148 | 
            +
                    }
         | 
| 149 | 
            +
                    Client.should_receive(:post).with("/cards/abcdef123456789123456789/members", payload)
         | 
| 150 | 
            +
                    @card.add_member(new_member)
         | 
| 151 | 
            +
                  end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  it "allows a member to be removed from a card" do
         | 
| 154 | 
            +
                    existing_member = stub(:id => '4ee7df3ce582acdec80000b2')
         | 
| 155 | 
            +
                    Client.should_receive(:delete).with("/cards/abcdef123456789123456789/members/#{existing_member.id}")
         | 
| 156 | 
            +
                    @card.remove_member(existing_member)
         | 
| 157 | 
            +
                  end
         | 
| 158 | 
            +
                end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                context "comments" do
         | 
| 161 | 
            +
                  it "posts a comment" do
         | 
| 162 | 
            +
                    Client.should_receive(:post).
         | 
| 163 | 
            +
                      with("/cards/abcdef123456789123456789/actions/comments", { :text => 'testing' }).
         | 
| 164 | 
            +
                      and_return JSON.generate(boards_details.first)
         | 
| 165 | 
            +
                    
         | 
| 166 | 
            +
                    @card.add_comment "testing"
         | 
| 167 | 
            +
                  end
         | 
| 168 | 
            +
                end
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                context "labels" do
         | 
| 171 | 
            +
                  it "can retrieve labels" do
         | 
| 172 | 
            +
                    Client.stub(:get).with("/cards/abcdef123456789123456789/labels").
         | 
| 173 | 
            +
                      and_return label_payload
         | 
| 174 | 
            +
                    labels = @card.labels
         | 
| 175 | 
            +
                    labels.size.should == 2
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                    labels[0].color.should == 'yellow'
         | 
| 178 | 
            +
                    labels[0].name.should == 'iOS'
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                    labels[1].color.should == 'purple'
         | 
| 181 | 
            +
                    labels[1].name.should == 'Issue or bug'
         | 
| 182 | 
            +
                  end
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                  it "can add a label" do
         | 
| 185 | 
            +
                    Client.stub(:post).with("/cards/abcdef123456789123456789/labels", { :value => 'green' }).
         | 
| 186 | 
            +
                      and_return "not important"
         | 
| 187 | 
            +
                    @card.add_label('green')
         | 
| 188 | 
            +
                    @card.errors.should be_empty
         | 
| 189 | 
            +
                  end
         | 
| 190 | 
            +
             | 
| 191 | 
            +
                  it "can remove a label" do
         | 
| 192 | 
            +
                    Client.stub(:delete).with("/cards/abcdef123456789123456789/labels/green").
         | 
| 193 | 
            +
                      and_return "not important"
         | 
| 194 | 
            +
                    @card.remove_label('green')
         | 
| 195 | 
            +
                    @card.errors.should be_empty
         | 
| 196 | 
            +
                  end
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                  it "throws an error when trying to add a label with an unknown colour" do
         | 
| 199 | 
            +
                    Client.stub(:post).with("/cards/abcdef123456789123456789/labels", { :value => 'green' }).
         | 
| 200 | 
            +
                      and_return "not important"
         | 
| 201 | 
            +
                    @card.add_label('mauve')
         | 
| 202 | 
            +
                    @card.errors.full_messages.to_sentence.should == "Label colour 'mauve' does not exist"
         | 
| 203 | 
            +
                  end
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                  it "throws an error when trying to remove a label with an unknown colour" do
         | 
| 206 | 
            +
                    Client.stub(:delete).with("/cards/abcdef123456789123456789/labels/mauve").
         | 
| 207 | 
            +
                      and_return "not important"
         | 
| 208 | 
            +
                    @card.remove_label('mauve')
         | 
| 209 | 
            +
                    @card.errors.full_messages.to_sentence.should == "Label colour 'mauve' does not exist"
         | 
| 210 | 
            +
                  end
         | 
| 211 | 
            +
                end
         | 
| 212 | 
            +
              end
         | 
| 213 | 
            +
            end
         | 
| @@ -0,0 +1,50 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Trello
         | 
| 4 | 
            +
              describe Checklist do
         | 
| 5 | 
            +
                include Helpers
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                before(:each) do
         | 
| 8 | 
            +
                  Client.stub(:get).with("/checklists/abcdef123456789123456789").
         | 
| 9 | 
            +
                    and_return JSON.generate(checklists_details.first)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  @checklist = Checklist.find('abcdef123456789123456789')
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                context "creating" do
         | 
| 15 | 
            +
                  it 'creates a new record and saves it on Trello', :refactor => true do
         | 
| 16 | 
            +
                    payload = {
         | 
| 17 | 
            +
                      :name    => 'Test Checklist',
         | 
| 18 | 
            +
                      :desc    => '',
         | 
| 19 | 
            +
                    }
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    result = JSON.generate(checklists_details.first.merge(payload.merge(:idBoard => boards_details.first['id'])))
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    expected_payload = {:name => "Test Checklist", :idBoard => "abcdef123456789123456789"}
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    Client.should_receive(:post).with("/checklists", expected_payload).and_return result
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    checklist = Checklist.create(checklists_details.first.merge(payload.merge(:board_id => boards_details.first['id'])))
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    checklist.class.should be Checklist
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                context "updating" do
         | 
| 34 | 
            +
                  it "updating name does a put on the correct resource with the correct value" do
         | 
| 35 | 
            +
                    expected_new_name = "xxx"
         | 
| 36 | 
            +
                    expected_resource = "/checklists/#{@checklist.id}"
         | 
| 37 | 
            +
                    payload = {
         | 
| 38 | 
            +
                      :name      => expected_new_name
         | 
| 39 | 
            +
                    }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    result = JSON.generate(checklists_details.first)
         | 
| 42 | 
            +
                    Client.should_receive(:put).once.with("/checklists/abcdef123456789123456789", payload).and_return result
         | 
| 43 | 
            +
                    checklist = @checklist.dup
         | 
| 44 | 
            +
                    checklist.name = expected_new_name
         | 
| 45 | 
            +
                    checklist.save
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
            end
         | 
    
        data/spec/client_spec.rb
    ADDED
    
    | @@ -0,0 +1,131 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            include Trello
         | 
| 4 | 
            +
            include Trello::Authorization
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            describe Client, "and how it handles authorization" do
         | 
| 7 | 
            +
              let (:fake_ok_response) {
         | 
| 8 | 
            +
                stub "A fake OK response",
         | 
| 9 | 
            +
                  :code => 200,
         | 
| 10 | 
            +
                  :body => "A fake response body"
         | 
| 11 | 
            +
              }
         | 
| 12 | 
            +
              
         | 
| 13 | 
            +
              before do
         | 
| 14 | 
            +
                TInternet.stub(:execute).and_return fake_ok_response
         | 
| 15 | 
            +
                Authorization::AuthPolicy.stub(:authorize) do |request|
         | 
| 16 | 
            +
                  request
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              it "authorizes before it queries the internet" do
         | 
| 21 | 
            +
                AuthPolicy.should_receive(:authorize).once.ordered
         | 
| 22 | 
            +
                TInternet.should_receive(:execute).once.ordered
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                Client.get "/xxx"
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              it "queries the internet with expanded earl and query parameters" do
         | 
| 28 | 
            +
                expected_uri = Addressable::URI.parse("https://api.trello.com/1/xxx?a=1&b=2")
         | 
| 29 | 
            +
                expected_request = Request.new :get, expected_uri, {}
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                TInternet.should_receive(:execute).once.with expected_request
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                Client.get "/xxx", :a => "1", :b => "2"
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              it "encodes parameters" do
         | 
| 37 | 
            +
                expected_uri = Addressable::URI.parse("https://api.trello.com/1/xxx?name=Jazz%20Kang")
         | 
| 38 | 
            +
                expected_request = Request.new :get, expected_uri, {}
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                TInternet.should_receive(:execute).once.with expected_request
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                Client.get "/xxx", :name => "Jazz Kang"
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              it "raises an error when response has non-200 status" do
         | 
| 46 | 
            +
                expected_error_message = "An error response"
         | 
| 47 | 
            +
                response_with_non_200_status = stub "A fake OK response", 
         | 
| 48 | 
            +
                  :code => 404,
         | 
| 49 | 
            +
                  :body => expected_error_message
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                TInternet.stub(:execute).and_return response_with_non_200_status
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                lambda{Client.get "/xxx"}.should raise_error expected_error_message
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              it "uses version 1 of the API" do
         | 
| 57 | 
            +
                TInternet.should_receive(:execute).once do |request|
         | 
| 58 | 
            +
                  request.uri.to_s.should =~ /1\//
         | 
| 59 | 
            +
                  fake_ok_response
         | 
| 60 | 
            +
                end 
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                Client.get "/"
         | 
| 63 | 
            +
              end 
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              it "omits the \"?\" when no parameters" do
         | 
| 66 | 
            +
                TInternet.should_receive(:execute).once do |request|
         | 
| 67 | 
            +
                  request.uri.to_s.should_not =~ /\?$/
         | 
| 68 | 
            +
                  fake_ok_response
         | 
| 69 | 
            +
                end 
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                Client.get "/xxx"
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
              it "supports post" do
         | 
| 75 | 
            +
                TInternet.should_receive(:execute).once.and_return fake_ok_response
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                Client.post "/xxx", { :phil => "T' north" }
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              it "supplies the body for a post" do
         | 
| 81 | 
            +
                expected_body = { :name => "Phil", :nickname => "The Crack Fox" }
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                TInternet.should_receive(:execute).once do |request|
         | 
| 84 | 
            +
                  request.body.should == expected_body
         | 
| 85 | 
            +
                  fake_ok_response
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                Client.post "/xxx", expected_body
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              it "supplies the path for a post" do
         | 
| 92 | 
            +
                expected_path = "/xxx"
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                TInternet.should_receive(:execute).once do |request|
         | 
| 95 | 
            +
                  request.uri.path.should =~ /#{expected_path}$/
         | 
| 96 | 
            +
                  fake_ok_response
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                Client.post "/xxx", {}
         | 
| 100 | 
            +
              end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
              it "supports put" do
         | 
| 103 | 
            +
                expected_path = "/xxx"
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                TInternet.should_receive(:execute).once.and_return fake_ok_response
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                Client.put "/xxx", { :phil => "T' north" }
         | 
| 108 | 
            +
              end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
              it "supplies the body for a put" do
         | 
| 111 | 
            +
                expected_body = { :name => "Phil", :nickname => "The Crack Fox" }
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                TInternet.should_receive(:execute).once do |request|
         | 
| 114 | 
            +
                  request.body.should == expected_body
         | 
| 115 | 
            +
                  fake_ok_response
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                Client.put "/xxx", expected_body
         | 
| 119 | 
            +
              end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
              it "supplies the path for a put" do
         | 
| 122 | 
            +
                expected_path = "/xxx"
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                TInternet.should_receive(:execute).once do |request|
         | 
| 125 | 
            +
                  request.uri.path.should =~ /#{expected_path}$/
         | 
| 126 | 
            +
                  fake_ok_response
         | 
| 127 | 
            +
                end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                Client.put "/xxx", {}
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
            end
         | 
| @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'integration/integration_test'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe "Authorizing read-only requests", :broken => true do
         | 
| 5 | 
            +
              include IntegrationTest
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              it "Reading public resources requires just a developer public key" do
         | 
| 8 | 
            +
                uri = Addressable::URI.parse("https://api.trello.com/1/boards/4ed7e27fe6abb2517a21383d")
         | 
| 9 | 
            +
                uri.query_values = {
         | 
| 10 | 
            +
                  :key => @developer_public_key
         | 
| 11 | 
            +
                }
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                get(uri).code.should === 200
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              it "Reading private resources requires developer public key AND a member token" do
         | 
| 17 | 
            +
                uri = Addressable::URI.parse("https://api.trello.com/1/boards/#{@welcome_board}")
         | 
| 18 | 
            +
                uri.query_values = {
         | 
| 19 | 
            +
                  :key => @developer_public_key,
         | 
| 20 | 
            +
                  :token => @member_token
         | 
| 21 | 
            +
                }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                get(uri).code.should === 200
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              it "can fetch the welcome board" do
         | 
| 27 | 
            +
                BasicAuthPolicy.developer_public_key = @developer_public_key
         | 
| 28 | 
            +
                BasicAuthPolicy.member_token = @member_token
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                Container.set Trello::Authorization, "AuthPolicy", BasicAuthPolicy
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                welcome_board = Board.find @welcome_board
         | 
| 33 | 
            +
                welcome_board.name.should === "Welcome Board"
         | 
| 34 | 
            +
                welcome_board.id.should === @welcome_board
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            describe "OAuth", :broken => true do
         | 
| 39 | 
            +
              include IntegrationTest
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              before do
         | 
| 42 | 
            +
                Container.set Trello::Authorization, "AuthPolicy", OAuthPolicy
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              it "[!] actually does not enforce signature at all, only the keys are required" do
         | 
| 46 | 
            +
                OAuthPolicy.consumer_credential = OAuthCredential.new @developer_public_key, nil
         | 
| 47 | 
            +
                OAuthPolicy.token = OAuthCredential.new @access_token_key, nil
         | 
| 48 | 
            +
                
         | 
| 49 | 
            +
                pending "I would expect this to fail because I have signed with nil secrets" do
         | 
| 50 | 
            +
                  lambda{Client.get("/boards/#{@welcome_board}/")}.should raise_error
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
            end
         |