ketchup 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE +20 -0
- data/README.textile +123 -0
- data/lib/ketchup.rb +36 -0
- data/lib/ketchup/api.rb +80 -0
- data/lib/ketchup/item.rb +75 -0
- data/lib/ketchup/item_array.rb +85 -0
- data/lib/ketchup/meeting.rb +96 -0
- data/lib/ketchup/meeting_array.rb +92 -0
- data/lib/ketchup/note.rb +73 -0
- data/lib/ketchup/note_array.rb +85 -0
- data/lib/ketchup/profile.rb +125 -0
- data/lib/ketchup/project.rb +51 -0
- data/spec/ketchup/api_spec.rb +120 -0
- data/spec/ketchup/item_array_spec.rb +125 -0
- data/spec/ketchup/item_spec.rb +127 -0
- data/spec/ketchup/meeting_array_spec.rb +141 -0
- data/spec/ketchup/meeting_spec.rb +142 -0
- data/spec/ketchup/note_array_spec.rb +125 -0
- data/spec/ketchup/note_spec.rb +126 -0
- data/spec/ketchup/profile_spec.rb +148 -0
- data/spec/ketchup/project_spec.rb +75 -0
- data/spec/ketchup_spec.rb +20 -0
- data/spec/spec_helper.rb +30 -0
- metadata +116 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
# A collection of meeting for the current profile, which allows for the creation
|
2
|
+
# of new meetings. It's really just a slightly special subclass of Array.
|
3
|
+
#
|
4
|
+
class Ketchup::MeetingArray < Array
|
5
|
+
# Create a new array from a given api connection. This will make the request
|
6
|
+
# to the API to retrieve all meetings for the profile.
|
7
|
+
#
|
8
|
+
# This isn't something you need to call yourself - just call the meetings
|
9
|
+
# method on your profile object instead.
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# meetings = Ketchup::MeetingArray.new api
|
13
|
+
#
|
14
|
+
# @param [Ketchup::API] api an API instance
|
15
|
+
# @see Ketchup::Profile#meetings
|
16
|
+
#
|
17
|
+
def initialize(api)
|
18
|
+
@api = api
|
19
|
+
|
20
|
+
replace @api.get('/meetings.json').collect { |hash|
|
21
|
+
Ketchup::Meeting.new(@api, hash)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
# Create a new unsaved meeting object. The only parameters you really need to
|
26
|
+
# worry about are the title and date - the rest are optional, but mentioned in
|
27
|
+
# the notes for the Meeting class.
|
28
|
+
#
|
29
|
+
# Don't forget: the parameter keys need to be strings, not symbols.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# profile.meetings.build 'title' => 'Job Interview', 'date' => 'Tomorrow'
|
33
|
+
#
|
34
|
+
# @param [Hash] params The meeting's details
|
35
|
+
# @return [Ketchup::Meeting] An unsaved meeting
|
36
|
+
# @see Ketchup::Meeting
|
37
|
+
#
|
38
|
+
def build(params = {})
|
39
|
+
meeting = Ketchup::Meeting.new @api, params
|
40
|
+
push meeting
|
41
|
+
meeting
|
42
|
+
end
|
43
|
+
|
44
|
+
# Create a new (saved) meeting object. The only parameters you really need to
|
45
|
+
# worry about are the title and date - the rest are optional, but mentioned in
|
46
|
+
# the notes for the Meeting class.
|
47
|
+
#
|
48
|
+
# Don't forget: the parameter keys need to be strings, not symbols.
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
# profile.meetings.create 'title' => 'Job Interview', 'date' => 'Tomorrow'
|
52
|
+
#
|
53
|
+
# @param [Hash] params The meeting's details
|
54
|
+
# @return [Ketchup::Meeting] A saved meeting
|
55
|
+
# @see Ketchup::Meeting
|
56
|
+
#
|
57
|
+
def create(params = {})
|
58
|
+
meeting = build(params)
|
59
|
+
meeting.save
|
60
|
+
meeting
|
61
|
+
end
|
62
|
+
|
63
|
+
# Requests a set of meetings that happen on days after today from the API.
|
64
|
+
#
|
65
|
+
# @return [Array] An array of upcoming meetings
|
66
|
+
#
|
67
|
+
def upcoming
|
68
|
+
@upcoming ||= @api.get('/meetings/upcoming.json').collect { |hash|
|
69
|
+
Ketchup::Meeting.new(@api, hash)
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
# Requests a set of meetings that have already happened from the API.
|
74
|
+
#
|
75
|
+
# @return [Array] An array of previous meetings
|
76
|
+
#
|
77
|
+
def previous
|
78
|
+
@previous ||= @api.get('/meetings/previous.json').collect { |hash|
|
79
|
+
Ketchup::Meeting.new(@api, hash)
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
# Requests a set of meetings that will happen today from the API.
|
84
|
+
#
|
85
|
+
# @return [Array] An array of today's meetings
|
86
|
+
#
|
87
|
+
def today
|
88
|
+
@today ||= @api.get('/meetings/todays.json').collect { |hash|
|
89
|
+
Ketchup::Meeting.new(@api, hash)
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
data/lib/ketchup/note.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Represents a note for list/agenda item in a meeting. Only the content is
|
2
|
+
# editable.
|
3
|
+
#
|
4
|
+
# If you want to change the order of notes, you can do that using
|
5
|
+
# Ketchup::NoteArray (the item's note array).
|
6
|
+
#
|
7
|
+
class Ketchup::Note
|
8
|
+
attr_reader :shortcode_url, :updated_at, :created_at, :item_id, :position,
|
9
|
+
:item, :api
|
10
|
+
attr_accessor :content
|
11
|
+
|
12
|
+
# Create a new note for a given item, using an existing api connection. You
|
13
|
+
# generally won't want to call this yourself - the better interface to create
|
14
|
+
# new notes is via a item's note array.
|
15
|
+
#
|
16
|
+
# However, if you are doing some internal hacking, it's worth noting that all
|
17
|
+
# keys for parameters in the hash should be strings, not symbols.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# Ketchup::Note.new api, item, 'content' => "Motion passed."
|
21
|
+
#
|
22
|
+
# @param [Ketchup::API] api The API connection
|
23
|
+
# @param [Ketchup::Item] item The item the note will belong to
|
24
|
+
# @param [Hash] params Any other details for the note.
|
25
|
+
# @see Ketchup::NoteArray#build
|
26
|
+
# @see Ketchup::NoteArray#create
|
27
|
+
#
|
28
|
+
def initialize(api, item, params = {})
|
29
|
+
@api = api
|
30
|
+
@item = item
|
31
|
+
|
32
|
+
overwrite params
|
33
|
+
end
|
34
|
+
|
35
|
+
# Indicates whether the note exists on the server yet.
|
36
|
+
#
|
37
|
+
# @return [Boolean] True if the note does not exist on the server.
|
38
|
+
#
|
39
|
+
def new_record?
|
40
|
+
shortcode_url.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
# Saves the note to the server, whether it's a new note or an existing one.
|
44
|
+
#
|
45
|
+
def save
|
46
|
+
if new_record?
|
47
|
+
overwrite @api.post("/items/#{item.shortcode_url}/notes.json",
|
48
|
+
'content' => content)
|
49
|
+
else
|
50
|
+
overwrite @api.put("/notes/#{shortcode_url}.json", 'content' => content)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Deletes the note from the server. If the note has never been saved, this
|
55
|
+
# method will do nothing at all.
|
56
|
+
#
|
57
|
+
def destroy
|
58
|
+
return if new_record?
|
59
|
+
|
60
|
+
@api.delete "/notes/#{shortcode_url}.json"
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def overwrite(attributes = {})
|
66
|
+
@shortcode_url = attributes['shortcode_url']
|
67
|
+
@created_at = attributes['created_at']
|
68
|
+
@updated_at = attributes['updated_at']
|
69
|
+
@item_id = attributes['item_id']
|
70
|
+
@position = attributes['position']
|
71
|
+
@content = attributes['content']
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# A collection of notes for a specific item, and allows for the creation of
|
2
|
+
# new notes, and re-ordering of the full set of notes. It's really just a
|
3
|
+
# slightly special subclass of Array.
|
4
|
+
#
|
5
|
+
class Ketchup::NoteArray < Array
|
6
|
+
# Create a new NoteArray for a given api, item, and set of notes. The set
|
7
|
+
# of notes should be hashes taken from the API server, not actual note
|
8
|
+
# objects.
|
9
|
+
#
|
10
|
+
# Like many of the methods in this library, you really don't need to call this
|
11
|
+
# one yourself. An item object will create its own NoteArray without any
|
12
|
+
# help.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# Ketchup::NoteArray.new api, item, [{'content' => 'foo', #... }]
|
16
|
+
#
|
17
|
+
# @param [Ketchup::API] api A connected API instance
|
18
|
+
# @param [Ketchup::Item] item The item all notes are attached to.
|
19
|
+
# @param [Array] items An array of hashes that map to attributes of notes.
|
20
|
+
#
|
21
|
+
def initialize(api, item, notes = [])
|
22
|
+
@api = api
|
23
|
+
@item = item
|
24
|
+
|
25
|
+
replace notes.collect { |hash|
|
26
|
+
Ketchup::Note.new(@api, @item, hash)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
# Create a new unsaved note object. The only parameter you really need to
|
31
|
+
# worry about is the content - the rest is all internal values, managed by the
|
32
|
+
# API server.
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# item.notes.build 'content' => 'Targets are being met.'
|
36
|
+
#
|
37
|
+
# @param [Hash] params The note's details
|
38
|
+
# @return [Ketchup::Note] An unsaved note
|
39
|
+
#
|
40
|
+
def build(params = {})
|
41
|
+
note = Ketchup::Note.new @api, @item, params
|
42
|
+
push note
|
43
|
+
note
|
44
|
+
end
|
45
|
+
|
46
|
+
# Create a new (saved) note object. The only parameter you really need to
|
47
|
+
# worry about is the content - the rest is all internal values, managed by the
|
48
|
+
# API server.
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
# item.notes.create 'content' => 'Targets are being met.'
|
52
|
+
#
|
53
|
+
# @param [Hash] params The note's details
|
54
|
+
# @return [Ketchup::Note] A saved note
|
55
|
+
#
|
56
|
+
def create(params = {})
|
57
|
+
note = build(params)
|
58
|
+
note.save
|
59
|
+
note
|
60
|
+
end
|
61
|
+
|
62
|
+
# Re-order the notes in this array, by passing them through in the order you
|
63
|
+
# would prefer. This makes the change directly to the API server, as well as
|
64
|
+
# within this array.
|
65
|
+
#
|
66
|
+
# Make sure you're passing in all the notes that are in this array, and no
|
67
|
+
# others. This can't be used as a shortcut to add new notes.
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# item.notes.reorder second_note, fourth_note, first_note, third_note
|
71
|
+
#
|
72
|
+
# @param [Ketchup::Note] notes The notes of the array, in a new order.
|
73
|
+
# @raise ArgumentError if you don't provide the exact same set of notes.
|
74
|
+
#
|
75
|
+
def reorder(*notes)
|
76
|
+
if notes.collect(&:shortcode_url).sort != collect(&:shortcode_url).sort
|
77
|
+
raise ArgumentError, 'cannot sort a different set of notes'
|
78
|
+
end
|
79
|
+
|
80
|
+
@api.put "/items/#{@item.shortcode_url}/sort_notes.json", {
|
81
|
+
'notes' => notes.collect(&:shortcode_url)
|
82
|
+
}
|
83
|
+
replace notes
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# A user profile, which provides an interface to the user's meetings and
|
2
|
+
# projects. You can either create it yourself, using an email and password, or
|
3
|
+
# through the Ketchup module's authenticate method - they're exactly the same.
|
4
|
+
#
|
5
|
+
# This is the central object for all of your operations through the Ketchup API.
|
6
|
+
# You don't need to create or manually request any other objects, but instead,
|
7
|
+
# access them all through the collections on this class.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# profile = Ketchup::Profile.load 'foo@bar.com', 'secret'
|
11
|
+
# profile.meetings.each do |meeting|
|
12
|
+
# puts meeting.title
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
class Ketchup::Profile
|
16
|
+
attr_reader :api, :single_access_token
|
17
|
+
attr_accessor :name, :timezone, :email
|
18
|
+
|
19
|
+
# Set up a connection to an existing profile.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# profile = Ketchup::Profile.load 'foo@bar.com', 'secret'
|
23
|
+
#
|
24
|
+
# @param [String] email The user's email address
|
25
|
+
# @param [String] password The user's passwords
|
26
|
+
# @return [Ketchup::Profile] A new profile instance
|
27
|
+
# @raise [Ketchup::AccessDenied] when the email or password is incorrect
|
28
|
+
#
|
29
|
+
def self.load(email, password)
|
30
|
+
Ketchup::Profile.new Ketchup::API.new(email, password)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Create a completely new user account. You (currently) don't need to have
|
34
|
+
# any existing authentication to the server to call this method - just specify
|
35
|
+
# the new user's email address and password.
|
36
|
+
#
|
37
|
+
# Other extra parameters are the name and timezone of the user account, but
|
38
|
+
# these are optional.
|
39
|
+
#
|
40
|
+
# Please note: This method doesn't return a new profile, just sets the account
|
41
|
+
# up.
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# Ketchup::Profile.create 'bar@foo.com', 'swordfish', 'name' => 'Bruce'
|
45
|
+
#
|
46
|
+
# @param [String] email The email address of the new user.
|
47
|
+
# @param [String] password The chosen password of the new user.
|
48
|
+
# @param [Hash] options Other optional user details, such as the name and
|
49
|
+
# timezone.
|
50
|
+
#
|
51
|
+
def self.create(email, password, options = {})
|
52
|
+
Ketchup::API.post '/users.json', :body => options.merge(
|
53
|
+
'email' => email,
|
54
|
+
'password' => password
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Set up a new profile object with an active API connection.
|
59
|
+
#
|
60
|
+
# @param [Ketchup::API] api An authenticated API object
|
61
|
+
#
|
62
|
+
def initialize(api)
|
63
|
+
@api = api
|
64
|
+
|
65
|
+
overwrite @api.get('/profile.json')
|
66
|
+
end
|
67
|
+
|
68
|
+
# Reset the meeting and project objects of this profile, allowing them to
|
69
|
+
# be reloaded from the server when next requested.
|
70
|
+
#
|
71
|
+
def reload!
|
72
|
+
@meetings = nil
|
73
|
+
@projects = nil
|
74
|
+
end
|
75
|
+
|
76
|
+
# Get an array of meetings attached to this profile. Note that the returned
|
77
|
+
# object is actually an instance of Ketchup::MeetingArray, which has helper
|
78
|
+
# methods for creating and re-ordering meetings.
|
79
|
+
#
|
80
|
+
# @return [Ketchup::MeetingArray] The collection of meetings.
|
81
|
+
#
|
82
|
+
def meetings
|
83
|
+
@meetings ||= Ketchup::MeetingArray.new api
|
84
|
+
end
|
85
|
+
|
86
|
+
# Get an array of projects attached to this profile. This is not a special
|
87
|
+
# project array, as you can only edit projects, not create them. They are
|
88
|
+
# created explicitly from meetings.
|
89
|
+
#
|
90
|
+
# @return [Array] The collection of projects.
|
91
|
+
#
|
92
|
+
def projects
|
93
|
+
@projects ||= api.get('/projects.json').collect { |hash|
|
94
|
+
Ketchup::Project.new(api, hash)
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
# Saves any profile changes to the name, timezone and/or email. This does not
|
99
|
+
# save any changes made to underlying meetings and projects.
|
100
|
+
#
|
101
|
+
def save
|
102
|
+
overwrite @api.put('/profile.json',
|
103
|
+
'name' => name,
|
104
|
+
'timezone' => timezone,
|
105
|
+
'email' => email
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Change the password for this profile account.
|
110
|
+
#
|
111
|
+
# @param [String] password The new password for the account.
|
112
|
+
#
|
113
|
+
def change_password(password)
|
114
|
+
@api.put '/profile.json', 'password' => password
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def overwrite(attributes = {})
|
120
|
+
@single_access_token = attributes['single_access_token']
|
121
|
+
@name = attributes['name']
|
122
|
+
@timezone = attributes['timezone']
|
123
|
+
@email = attributes['email']
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Represents a project, which meetings can be grouped under.
|
2
|
+
#
|
3
|
+
# Projects cannot be created manually - just create meetings with project names,
|
4
|
+
# and the corresponding projects will be created if they don't already exist.
|
5
|
+
#
|
6
|
+
# You can, however, change the name of a project.
|
7
|
+
#
|
8
|
+
class Ketchup::Project
|
9
|
+
attr_accessor :name
|
10
|
+
attr_reader :shortcode_url, :created_at, :updated_at
|
11
|
+
|
12
|
+
# Set up a new Project object - although there's not much point calling this
|
13
|
+
# yourself, as it's only useful when populating with data from the server.
|
14
|
+
#
|
15
|
+
# @param [Ketchup::API] api An established API connection.
|
16
|
+
# @param [Hash] params The project details
|
17
|
+
#
|
18
|
+
def initialize(api, params = {})
|
19
|
+
@api = api
|
20
|
+
|
21
|
+
overwrite params
|
22
|
+
end
|
23
|
+
|
24
|
+
# Saves any changes to the project's name.
|
25
|
+
#
|
26
|
+
def save
|
27
|
+
overwrite @api.put("/projects/#{shortcode_url}.json", 'name' => name)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Gets all the meetings tied to this particular project. This is not a special
|
31
|
+
# array, so it's best to create new meetings for a given project via the
|
32
|
+
# profile's meetings collection object instead.
|
33
|
+
#
|
34
|
+
# @return [Array] Meetings associated with this project.
|
35
|
+
#
|
36
|
+
def meetings
|
37
|
+
@meetings ||= @api.get("/projects/#{shortcode_url}/meetings.json").
|
38
|
+
collect { |hash|
|
39
|
+
Ketchup::Meeting.new @api, hash
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def overwrite(attributes = {})
|
46
|
+
@shortcode_url = attributes['shortcode_url']
|
47
|
+
@created_at = attributes['created_at']
|
48
|
+
@updated_at = attributes['updated_at']
|
49
|
+
@name = attributes['name']
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Ketchup::API do
|
4
|
+
describe '#initialize' do
|
5
|
+
it "should return a new API object on success" do
|
6
|
+
FakeWeb.register_uri :get, /#{KetchupAPI}\/profile.json$/,
|
7
|
+
:body => '{"single_access_token":"foo"}'
|
8
|
+
|
9
|
+
Ketchup::API.new('user@domain.com', 'secret').should be_a(Ketchup::API)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should set the access token on success" do
|
13
|
+
stub_initial_api_request
|
14
|
+
|
15
|
+
Ketchup::API.new('user@domain.com', 'secret').
|
16
|
+
access_token.should == 'y3chHxh9Qk1Drkg1j0Bw'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should raise an exception on failure" do
|
20
|
+
FakeWeb.register_uri :get, /#{KetchupAPI}\/profile.json$/,
|
21
|
+
:body => 'Access Denied'
|
22
|
+
|
23
|
+
lambda {
|
24
|
+
Ketchup::API.new('user@domain.com', 'secret')
|
25
|
+
}.should raise_error(Ketchup::AccessDenied)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#get' do
|
30
|
+
before :each do
|
31
|
+
stub_initial_api_request
|
32
|
+
@api = Ketchup::API.new('user@domain.com', 'secret')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should include the access token" do
|
36
|
+
Ketchup::API.should_receive(:get) do |path, options|
|
37
|
+
options[:query][:u].should == 'y3chHxh9Qk1Drkg1j0Bw'
|
38
|
+
end
|
39
|
+
|
40
|
+
@api.get '/'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should send through any provided options" do
|
44
|
+
Ketchup::API.should_receive(:get) do |path, options|
|
45
|
+
options[:query][:page].should == 4
|
46
|
+
end
|
47
|
+
|
48
|
+
@api.get '/', :page => 4
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#post' do
|
53
|
+
before :each do
|
54
|
+
stub_initial_api_request
|
55
|
+
@api = Ketchup::API.new('user@domain.com', 'secret')
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should include the access token" do
|
59
|
+
Ketchup::API.should_receive(:post) do |path, options|
|
60
|
+
options[:body][:u].should == 'y3chHxh9Qk1Drkg1j0Bw'
|
61
|
+
end
|
62
|
+
|
63
|
+
@api.post '/'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should send through any provided options" do
|
67
|
+
Ketchup::API.should_receive(:post) do |path, options|
|
68
|
+
options[:body][:page].should == 4
|
69
|
+
end
|
70
|
+
|
71
|
+
@api.post '/', :page => 4
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#put' do
|
76
|
+
before :each do
|
77
|
+
stub_initial_api_request
|
78
|
+
@api = Ketchup::API.new('user@domain.com', 'secret')
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should include the access token" do
|
82
|
+
Ketchup::API.should_receive(:put) do |path, options|
|
83
|
+
options[:body][:u].should == 'y3chHxh9Qk1Drkg1j0Bw'
|
84
|
+
end
|
85
|
+
|
86
|
+
@api.put '/'
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should send through any provided options" do
|
90
|
+
Ketchup::API.should_receive(:put) do |path, options|
|
91
|
+
options[:body][:page].should == 4
|
92
|
+
end
|
93
|
+
|
94
|
+
@api.put '/', :page => 4
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#delete' do
|
99
|
+
before :each do
|
100
|
+
stub_initial_api_request
|
101
|
+
@api = Ketchup::API.new('user@domain.com', 'secret')
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should include the access token" do
|
105
|
+
Ketchup::API.should_receive(:delete) do |path, options|
|
106
|
+
options[:body][:u].should == 'y3chHxh9Qk1Drkg1j0Bw'
|
107
|
+
end
|
108
|
+
|
109
|
+
@api.delete '/'
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should send through any provided options" do
|
113
|
+
Ketchup::API.should_receive(:delete) do |path, options|
|
114
|
+
options[:body][:page].should == 4
|
115
|
+
end
|
116
|
+
|
117
|
+
@api.delete '/', :page => 4
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|