ketchup 1.0.0
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/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,125 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Ketchup::NoteArray do
|
4
|
+
before :each do
|
5
|
+
@api = stub('api', :get => [])
|
6
|
+
@meeting = Ketchup::Meeting.new @api
|
7
|
+
@item = Ketchup::Item.new @api, @meeting, 'shortcode_url' => 'bar'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be a subclass of Array" do
|
11
|
+
Ketchup::NoteArray.superclass.should == Array
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#initialize' do
|
15
|
+
it "should instantiate notes from the provided array" do
|
16
|
+
time = Time.now
|
17
|
+
notes = Ketchup::NoteArray.new @api, @item, [{
|
18
|
+
'updated_at' => time,
|
19
|
+
'shortcode_url' => 'ZCTYXAeDb_rQ3IkRq9nutcwfxUpNPLBOsHM28Ela',
|
20
|
+
'content' => 'Foo',
|
21
|
+
'position' => 1,
|
22
|
+
'item_id' => 4321,
|
23
|
+
'created_at' => time
|
24
|
+
}]
|
25
|
+
notes.first.should be_a(Ketchup::Note)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#build' do
|
30
|
+
before :each do
|
31
|
+
@notes = Ketchup::NoteArray.new @api, @item
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should set the note's API object" do
|
35
|
+
note = @notes.build 'content' => 'foo'
|
36
|
+
note.api.should == @api
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should pass on the options to the new note" do
|
40
|
+
note = @notes.build 'content' => 'foo'
|
41
|
+
note.content.should == 'foo'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should add the note to the array" do
|
45
|
+
note = @notes.build 'content' => 'foo'
|
46
|
+
@notes.should include(note)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#create' do
|
51
|
+
before :each do
|
52
|
+
@api.stub!(:post => {'content' => 'foo'})
|
53
|
+
@notes = Ketchup::NoteArray.new @api, @item
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should set the note's API object" do
|
57
|
+
note = @notes.create 'content' => 'foo'
|
58
|
+
note.api.should == @api
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should pass on the options to the new note" do
|
62
|
+
note = @notes.create 'content' => 'foo'
|
63
|
+
note.content.should == 'foo'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should add the note to the array" do
|
67
|
+
note = @notes.create 'content' => 'foo'
|
68
|
+
@notes.should include(note)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should have already saved the item" do
|
72
|
+
@api.should_receive(:post)
|
73
|
+
|
74
|
+
note = @notes.create 'content' => 'foo'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#reorder' do
|
79
|
+
before :each do
|
80
|
+
@api.stub!(:put => [])
|
81
|
+
@notes = Ketchup::NoteArray.new @api, @item, [
|
82
|
+
{'shortcode_url' => 'alpha', 'content' => 'Alpha'},
|
83
|
+
{'shortcode_url' => 'beta', 'content' => 'Beta' },
|
84
|
+
{'shortcode_url' => 'gamma', 'content' => 'Gamma'}
|
85
|
+
]
|
86
|
+
@alpha, @beta, @gamma = @notes
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should send a put request to the correct url" do
|
90
|
+
@api.should_receive(:put) do |query, options|
|
91
|
+
query.should == '/items/bar/sort_notes.json'
|
92
|
+
end
|
93
|
+
|
94
|
+
@notes.reorder @beta, @gamma, @alpha
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should send the shortcode urls in the given order" do
|
98
|
+
@api.should_receive(:put) do |query, options|
|
99
|
+
options['notes'].should == ['beta', 'gamma', 'alpha']
|
100
|
+
end
|
101
|
+
|
102
|
+
@notes.reorder @beta, @gamma, @alpha
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should change the order of the array" do
|
106
|
+
@notes.reorder @beta, @gamma, @alpha
|
107
|
+
@notes[0].should == @beta
|
108
|
+
@notes[1].should == @gamma
|
109
|
+
@notes[2].should == @alpha
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should raise an error if not the same notes" do
|
113
|
+
note = Ketchup::Note.new @api, @item, 'shortcode_url' => 'delta'
|
114
|
+
lambda {
|
115
|
+
@notes.reorder note, @beta, @alpha
|
116
|
+
}.should raise_error(ArgumentError)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should raise an error if not all the notes" do
|
120
|
+
lambda {
|
121
|
+
@notes.reorder @alpha, @gamma
|
122
|
+
}.should raise_error(ArgumentError)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Ketchup::Note do
|
4
|
+
before :each do
|
5
|
+
@api = stub('api')
|
6
|
+
@meeting = Ketchup::Meeting.new @api
|
7
|
+
@item = Ketchup::Item.new @api, @meeting
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#initialize' do
|
11
|
+
it "should initialize all the attributes" do
|
12
|
+
time = Time.now
|
13
|
+
note = Ketchup::Note.new(@api, @item,
|
14
|
+
'updated_at' => time,
|
15
|
+
'shortcode_url' => 'ZTmyXjQEwRuNderHIqvfhlUP0VS172nMD-WLOtio',
|
16
|
+
'content' => 'Foo',
|
17
|
+
'position' => 1,
|
18
|
+
'item_id' => 4321,
|
19
|
+
'created_at' => time
|
20
|
+
)
|
21
|
+
|
22
|
+
note.updated_at.should == time
|
23
|
+
note.shortcode_url.should == 'ZTmyXjQEwRuNderHIqvfhlUP0VS172nMD-WLOtio'
|
24
|
+
note.content.should == 'Foo'
|
25
|
+
note.position.should == 1
|
26
|
+
note.item_id.should == 4321
|
27
|
+
note.created_at.should == time
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#new_record?' do
|
32
|
+
it "should return true if note has no shortcode_url" do
|
33
|
+
note = Ketchup::Note.new @api, @item
|
34
|
+
note.should be_new_record
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return false if note has a shortcode_url" do
|
38
|
+
note = Ketchup::Note.new @api, @item, 'shortcode_url' => 'foo'
|
39
|
+
note.should_not be_new_record
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#save' do
|
44
|
+
it "should send a post if creating" do
|
45
|
+
@api.should_receive(:post).and_return({})
|
46
|
+
|
47
|
+
note = Ketchup::Note.new @api, @item, 'content' => 'foo'
|
48
|
+
note.save
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should include writeable attributes in the post" do
|
52
|
+
@api.should_receive(:post) do |query, options|
|
53
|
+
options['content'].should == 'foo'
|
54
|
+
{}
|
55
|
+
end
|
56
|
+
|
57
|
+
note = Ketchup::Note.new @api, @item, 'content' => 'foo'
|
58
|
+
note.save
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should not include read-only attributes in the post" do
|
62
|
+
@api.should_receive(:post) do |query, options|
|
63
|
+
options.keys.should_not include('created_at')
|
64
|
+
{}
|
65
|
+
end
|
66
|
+
|
67
|
+
note = Ketchup::Note.new @api, @item, 'created_at' => Time.now
|
68
|
+
note.save
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should update the object with the response" do
|
72
|
+
@api.stub!(:post => {'shortcode_url' => 'foo'})
|
73
|
+
|
74
|
+
note = Ketchup::Note.new @api, @item, 'content' => 'Foo'
|
75
|
+
note.save
|
76
|
+
note.shortcode_url.should == 'foo'
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should send a put if updating" do
|
80
|
+
@api.should_receive(:put).and_return({})
|
81
|
+
|
82
|
+
note = Ketchup::Note.new @api, @item, 'shortcode_url' => 'foo'
|
83
|
+
note.save
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should include writeable attributes in the put" do
|
87
|
+
@api.should_receive(:put) do |query, options|
|
88
|
+
options['content'].should == 'foo'
|
89
|
+
{}
|
90
|
+
end
|
91
|
+
|
92
|
+
note = Ketchup::Note.new @api, @item,
|
93
|
+
'shortcode_url' => 'foo', 'content' => 'foo'
|
94
|
+
note.save
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should not include read-only attributes in the put" do
|
98
|
+
@api.should_receive(:put) do |query, options|
|
99
|
+
options.keys.should_not include('created_at')
|
100
|
+
{}
|
101
|
+
end
|
102
|
+
|
103
|
+
note = Ketchup::Note.new @api, @item,
|
104
|
+
'shortcode_url' => 'foo', 'created_at' => Time.now
|
105
|
+
note.save
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#destroy' do
|
110
|
+
it "should delete the note" do
|
111
|
+
@api.should_receive(:delete) do |query, options|
|
112
|
+
query.should == '/notes/foo.json'
|
113
|
+
end
|
114
|
+
|
115
|
+
note = Ketchup::Note.new @api, @item, 'shortcode_url' => 'foo'
|
116
|
+
note.destroy
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should do nothing if the record isn't already saved" do
|
120
|
+
@api.should_not_receive(:delete)
|
121
|
+
|
122
|
+
note = Ketchup::Note.new @api, @item
|
123
|
+
note.destroy
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Ketchup::Profile do
|
4
|
+
describe '.load' do
|
5
|
+
it "should return a new instance if valid details are provided" do
|
6
|
+
Ketchup::API.stub!(:new => stub('api', :get => {}))
|
7
|
+
|
8
|
+
Ketchup::Profile.load('user@domain.com', 'secret').
|
9
|
+
should be_a(Ketchup::Profile)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should raise an exception if invalid details are provided" do
|
13
|
+
Ketchup::API.stub!(:new).and_raise(Ketchup::AccessDenied)
|
14
|
+
|
15
|
+
lambda {
|
16
|
+
Ketchup::Profile.load('user@domain.com', 'secret')
|
17
|
+
}.should raise_error(Ketchup::AccessDenied)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.create' do
|
22
|
+
it "should send a post" do
|
23
|
+
Ketchup::API.should_receive(:post) do |query, options|
|
24
|
+
query.should == '/users.json'
|
25
|
+
{}
|
26
|
+
end
|
27
|
+
|
28
|
+
Ketchup::Profile.create 'foo@bar.com', 'password'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should include the email and password" do
|
32
|
+
Ketchup::API.should_receive(:post) do |query, options|
|
33
|
+
options[:body]['email'].should == 'foo@bar.com'
|
34
|
+
options[:body]['password'].should == 'secret'
|
35
|
+
{}
|
36
|
+
end
|
37
|
+
|
38
|
+
Ketchup::Profile.create 'foo@bar.com', 'secret'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should include any other extra parameters" do
|
42
|
+
Ketchup::API.should_receive(:post) do |query, options|
|
43
|
+
options[:body]['timezone'].should == 'UTC'
|
44
|
+
{}
|
45
|
+
end
|
46
|
+
|
47
|
+
Ketchup::Profile.create 'foo@bar.com', 'secret', 'timezone' => 'UTC'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#reload!' do
|
52
|
+
it "should clear the stored meetings" do
|
53
|
+
api = stub('api', :get => {})
|
54
|
+
profile = Ketchup::Profile.new(api)
|
55
|
+
api.stub!(:get => [])
|
56
|
+
|
57
|
+
profile.meetings
|
58
|
+
profile.reload!
|
59
|
+
|
60
|
+
api.should_receive(:get)
|
61
|
+
profile.meetings
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#projects' do
|
66
|
+
it "should return an array of projects" do
|
67
|
+
api = stub('api', :get => {})
|
68
|
+
profile = Ketchup::Profile.new(api)
|
69
|
+
api.stub!(:get => [])
|
70
|
+
|
71
|
+
profile.projects.should be_a(Array)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#meetings' do
|
76
|
+
it "should return a meeting array of meetings" do
|
77
|
+
api = stub('api', :get => {})
|
78
|
+
profile = Ketchup::Profile.new(api)
|
79
|
+
api.stub!(:get => [])
|
80
|
+
|
81
|
+
profile.meetings.should be_a(Ketchup::MeetingArray)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#save' do
|
86
|
+
before :each do
|
87
|
+
@api = stub('api', :get => {
|
88
|
+
"name" => "foo",
|
89
|
+
"single_access_token" => "bar"
|
90
|
+
})
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should include writeable attributes in the put" do
|
94
|
+
@api.should_receive(:put) do |query, options|
|
95
|
+
options['name'].should == 'foo'
|
96
|
+
{}
|
97
|
+
end
|
98
|
+
|
99
|
+
profile = Ketchup::Profile.new @api
|
100
|
+
profile.save
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should not include read-only attributes in the put" do
|
104
|
+
@api.should_receive(:put) do |query, options|
|
105
|
+
options.keys.should_not include('single_access_token')
|
106
|
+
{}
|
107
|
+
end
|
108
|
+
|
109
|
+
profile = Ketchup::Profile.new @api
|
110
|
+
profile.save
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should update the object with the response" do
|
114
|
+
@api.stub!(:put => {'single_access_token' => 'baz'})
|
115
|
+
|
116
|
+
profile = Ketchup::Profile.new @api
|
117
|
+
profile.save
|
118
|
+
profile.single_access_token.should == 'baz'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe '#change_password' do
|
123
|
+
before :each do
|
124
|
+
@api = stub('api', :get => {
|
125
|
+
"name" => "foo",
|
126
|
+
"single_access_token" => "bar"
|
127
|
+
})
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should update the profile" do
|
131
|
+
@api.should_receive(:put) do |query, options|
|
132
|
+
query.should == '/profile.json'
|
133
|
+
end
|
134
|
+
|
135
|
+
profile = Ketchup::Profile.new @api
|
136
|
+
profile.change_password 'baz'
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should use the given password" do
|
140
|
+
@api.should_receive(:put) do |query, options|
|
141
|
+
options['password'].should == 'baz'
|
142
|
+
end
|
143
|
+
|
144
|
+
profile = Ketchup::Profile.new @api
|
145
|
+
profile.change_password 'baz'
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
describe Ketchup::Project do
|
4
|
+
before :each do
|
5
|
+
@api = stub('api')
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#initialize' do
|
9
|
+
it "should initialize all the attributes" do
|
10
|
+
time = Time.now
|
11
|
+
project = Ketchup::Project.new(@api,
|
12
|
+
"name" => 'Trampoline',
|
13
|
+
"updated_at" => time,
|
14
|
+
"shortcode_url" => 'foo',
|
15
|
+
"created_at" => time
|
16
|
+
)
|
17
|
+
|
18
|
+
project.name.should == 'Trampoline'
|
19
|
+
project.updated_at.should == time
|
20
|
+
project.created_at.should == time
|
21
|
+
project.shortcode_url.should == 'foo'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#save' do
|
26
|
+
it "should include writeable attributes in the put" do
|
27
|
+
@api.should_receive(:put) do |query, options|
|
28
|
+
options['name'].should == 'foo'
|
29
|
+
{}
|
30
|
+
end
|
31
|
+
|
32
|
+
project = Ketchup::Project.new @api, 'name' => 'foo'
|
33
|
+
project.save
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not include read-only attributes in the put" do
|
37
|
+
@api.should_receive(:put) do |query, options|
|
38
|
+
options.keys.should_not include('created_at')
|
39
|
+
{}
|
40
|
+
end
|
41
|
+
|
42
|
+
project = Ketchup::Project.new @api, 'created_at' => Time.now
|
43
|
+
project.save
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should update the object with the response" do
|
47
|
+
@api.stub!(:put => {'shortcode_url' => 'foo'})
|
48
|
+
|
49
|
+
project = Ketchup::Project.new @api, 'name' => 'Foo'
|
50
|
+
project.save
|
51
|
+
project.shortcode_url.should == 'foo'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#meetings' do
|
56
|
+
before :each do
|
57
|
+
@api.stub!(:get => [])
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should request meetings for just the project" do
|
61
|
+
@api.should_receive(:get) do |query, options|
|
62
|
+
query.should == '/projects/foo/meetings.json'
|
63
|
+
[]
|
64
|
+
end
|
65
|
+
|
66
|
+
project = Ketchup::Project.new @api, 'shortcode_url' => 'foo'
|
67
|
+
project.meetings
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return an array of meetings" do
|
71
|
+
project = Ketchup::Project.new @api, 'shortcode_url' => 'foo'
|
72
|
+
project.meetings.should be_an(Array)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|