vigetlabs-unfuzzle 0.1.0 → 0.1.1
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/lib/unfuzzle/milestone.rb +9 -0
- data/lib/unfuzzle/model.rb +31 -5
- data/lib/unfuzzle/request.rb +21 -2
- data/lib/unfuzzle/ticket.rb +11 -0
- data/lib/unfuzzle/version.rb +1 -1
- data/lib/unfuzzle.rb +1 -0
- data/test/fixtures/milestone.json +11 -0
- data/test/test_helper.rb +13 -0
- data/test/unit/unfuzzle/milestone_test.rb +35 -0
- data/test/unit/unfuzzle/model_test.rb +55 -0
- data/test/unit/unfuzzle/project_test.rb +1 -1
- data/test/unit/unfuzzle/request_test.rb +51 -0
- data/test/unit/unfuzzle/ticket_test.rb +30 -2
- metadata +6 -4
data/lib/unfuzzle/milestone.rb
CHANGED
@@ -25,6 +25,11 @@ module Unfuzzle
|
|
25
25
|
response.data.map {|data| new(data) }
|
26
26
|
end
|
27
27
|
|
28
|
+
def self.find_by_project_id_and_milestone_id(project_id, milestone_id)
|
29
|
+
response = Request.get("/projects/#{project_id}/milestones/#{milestone_id}")
|
30
|
+
new response.data
|
31
|
+
end
|
32
|
+
|
28
33
|
# Has this milestone been archived?
|
29
34
|
def archived?
|
30
35
|
archived == true
|
@@ -45,6 +50,10 @@ module Unfuzzle
|
|
45
50
|
Date.parse(due_datestamp) unless due_datestamp.nil?
|
46
51
|
end
|
47
52
|
|
53
|
+
def past?
|
54
|
+
due_on < Date.today
|
55
|
+
end
|
56
|
+
|
48
57
|
# The collection of Tickets associated to this milestone
|
49
58
|
def tickets
|
50
59
|
Ticket.find_all_by_project_id_and_milestone_id(project_id, id)
|
data/lib/unfuzzle/model.rb
CHANGED
@@ -5,11 +5,15 @@ module Unfuzzle
|
|
5
5
|
def attribute(name, options = {}) # :nodoc:
|
6
6
|
key = options.delete(:from) || name
|
7
7
|
|
8
|
-
class_eval
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
class_eval <<-CODE
|
9
|
+
def #{name}
|
10
|
+
@response_data['#{key}']
|
11
|
+
end
|
12
|
+
|
13
|
+
def #{name}=(value)
|
14
|
+
@response_data['#{key}'] = value
|
15
|
+
end
|
16
|
+
CODE
|
13
17
|
end
|
14
18
|
end
|
15
19
|
|
@@ -19,6 +23,28 @@ module Unfuzzle
|
|
19
23
|
@response_data = response_data
|
20
24
|
end
|
21
25
|
|
26
|
+
def to_hash
|
27
|
+
@response_data
|
28
|
+
end
|
29
|
+
|
30
|
+
def tag_name
|
31
|
+
full_class_name = self.class.to_s
|
32
|
+
class_name = full_class_name.split('::').last
|
33
|
+
|
34
|
+
class_name.downcase
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_xml
|
38
|
+
xml = Builder::XmlMarkup.new
|
39
|
+
xml.instruct!
|
40
|
+
xml.tag! tag_name do
|
41
|
+
to_hash.each do |attribute, value|
|
42
|
+
xml.tag! attribute, value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
xml.target!
|
46
|
+
end
|
47
|
+
|
22
48
|
end
|
23
49
|
|
24
50
|
def self.included(other)
|
data/lib/unfuzzle/request.rb
CHANGED
@@ -12,13 +12,24 @@ module Unfuzzle
|
|
12
12
|
request.get
|
13
13
|
end
|
14
14
|
|
15
|
+
def self.put(resource_path, payload)
|
16
|
+
request = new(resource_path, payload, :format => :xml)
|
17
|
+
request.put
|
18
|
+
end
|
19
|
+
|
15
20
|
# Create a new request for the given resource path
|
16
|
-
def initialize(resource_path)
|
21
|
+
def initialize(resource_path, payload = nil, options = {})
|
17
22
|
@resource_path = resource_path
|
23
|
+
@payload = payload
|
24
|
+
@options = options
|
25
|
+
end
|
26
|
+
|
27
|
+
def request_format
|
28
|
+
(@options[:format] || 'json').to_s
|
18
29
|
end
|
19
30
|
|
20
31
|
def endpoint_uri # :nodoc:
|
21
|
-
URI.parse("http://#{Unfuzzle.subdomain}.unfuddle.com/api/v1#{@resource_path}
|
32
|
+
URI.parse("http://#{Unfuzzle.subdomain}.unfuddle.com/api/v1#{@resource_path}.#{request_format}")
|
22
33
|
end
|
23
34
|
|
24
35
|
def client # :nodoc:
|
@@ -32,6 +43,14 @@ module Unfuzzle
|
|
32
43
|
|
33
44
|
Response.new(client.request(request))
|
34
45
|
end
|
46
|
+
|
47
|
+
def put
|
48
|
+
request = Net::HTTP::Put.new(endpoint_uri.path)
|
49
|
+
request.basic_auth Unfuzzle.username, Unfuzzle.password
|
50
|
+
request.content_type = 'application/xml'
|
51
|
+
|
52
|
+
Response.new(client.request(request, @payload))
|
53
|
+
end
|
35
54
|
|
36
55
|
end
|
37
56
|
end
|
data/lib/unfuzzle/ticket.rb
CHANGED
@@ -16,6 +16,8 @@ module Unfuzzle
|
|
16
16
|
include Unfuzzle::Model
|
17
17
|
|
18
18
|
attribute :id
|
19
|
+
attribute :project_id
|
20
|
+
attribute :milestone_id
|
19
21
|
attribute :number
|
20
22
|
attribute :title, :from => :summary
|
21
23
|
attribute :description
|
@@ -50,6 +52,15 @@ module Unfuzzle
|
|
50
52
|
def due_on
|
51
53
|
Date.parse(due_datestamp) unless due_datestamp.nil?
|
52
54
|
end
|
55
|
+
|
56
|
+
def milestone
|
57
|
+
Milestone.find_by_project_id_and_milestone_id(project_id, milestone_id)
|
58
|
+
end
|
59
|
+
|
60
|
+
def update
|
61
|
+
resource_path = "/projects/#{project_id}/tickets/#{id}"
|
62
|
+
Request.put(resource_path, self.to_xml)
|
63
|
+
end
|
53
64
|
|
54
65
|
end
|
55
66
|
end
|
data/lib/unfuzzle/version.rb
CHANGED
data/lib/unfuzzle.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -46,4 +46,17 @@ class Test::Unit::TestCase
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
def self.should_set_a_value_for(attribute, value = nil)
|
50
|
+
class_name = self.to_s.sub(/^Unfuzzle::(.*)Test$/, '\\1')
|
51
|
+
klass = Unfuzzle.const_get(class_name)
|
52
|
+
|
53
|
+
value = attribute if value.nil?
|
54
|
+
|
55
|
+
should "be able to set a value for :#{attribute}" do
|
56
|
+
object = klass.new({})
|
57
|
+
object.send("#{attribute}=", value)
|
58
|
+
object.send(attribute).should == value
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
49
62
|
end
|
@@ -20,6 +20,16 @@ module Unfuzzle
|
|
20
20
|
|
21
21
|
Milestone.find_all_by_project_id(1).should == milestones
|
22
22
|
end
|
23
|
+
|
24
|
+
should "be able to find one by project ID an milestone ID" do
|
25
|
+
project_id = 1
|
26
|
+
milestone_id = 2
|
27
|
+
response = mock_request_cycle :for => "/projects/#{project_id}/milestones/#{milestone_id}", :data => 'milestone'
|
28
|
+
|
29
|
+
Unfuzzle::Milestone.expects(:new).with(response.data).returns('milestone')
|
30
|
+
|
31
|
+
Milestone.find_by_project_id_and_milestone_id(1, 2).should == 'milestone'
|
32
|
+
end
|
23
33
|
|
24
34
|
end
|
25
35
|
|
@@ -88,6 +98,31 @@ module Unfuzzle
|
|
88
98
|
|
89
99
|
@milestone.tickets.should == 'tickets'
|
90
100
|
end
|
101
|
+
|
102
|
+
should "know that it's in the past if the due date is in the past" do
|
103
|
+
due_date = Date.today
|
104
|
+
today = due_date.next
|
105
|
+
|
106
|
+
@milestone.stubs(:due_on).with().returns(due_date)
|
107
|
+
Date.expects(:today).with().returns(today)
|
108
|
+
|
109
|
+
@milestone.past?.should be(true)
|
110
|
+
end
|
111
|
+
|
112
|
+
should "know that it's not in the past if the date is today" do
|
113
|
+
due_date = Date.today
|
114
|
+
@milestone.stubs(:due_on).with().returns(due_date)
|
115
|
+
|
116
|
+
@milestone.past?.should be(false)
|
117
|
+
end
|
118
|
+
|
119
|
+
should "know that it's not in the past if the due date is in the future" do
|
120
|
+
due_date = Date.today.next
|
121
|
+
@milestone.stubs(:due_on).with().returns(due_date)
|
122
|
+
|
123
|
+
@milestone.past?.should be(false)
|
124
|
+
end
|
125
|
+
|
91
126
|
|
92
127
|
end
|
93
128
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
class MyModel
|
4
|
+
include Unfuzzle::Model
|
5
|
+
attribute :foo
|
6
|
+
end
|
7
|
+
|
8
|
+
module MyModule
|
9
|
+
class MyModel
|
10
|
+
include Unfuzzle::Model
|
11
|
+
attribute :bar
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Unfuzzle
|
16
|
+
class ModelTest < Test::Unit::TestCase
|
17
|
+
|
18
|
+
context "An instance of the MyModel class" do
|
19
|
+
should "have an accessor for :foo" do
|
20
|
+
m = MyModel.new({})
|
21
|
+
m.foo = 'bar'
|
22
|
+
m.foo.should == 'bar'
|
23
|
+
end
|
24
|
+
|
25
|
+
should "be able to generate a hash representation of its data" do
|
26
|
+
m = MyModel.new('foo' => 'bar')
|
27
|
+
m.to_hash.should == {'foo' => 'bar'}
|
28
|
+
end
|
29
|
+
|
30
|
+
should "be able to generate its tag name when the class is not namespaced" do
|
31
|
+
m = MyModel.new({})
|
32
|
+
m.tag_name.should == 'mymodel'
|
33
|
+
end
|
34
|
+
|
35
|
+
should "be able to generate its tag name when the class is namespaced" do
|
36
|
+
m = MyModule::MyModel.new({})
|
37
|
+
m.tag_name.should == 'mymodel'
|
38
|
+
end
|
39
|
+
|
40
|
+
should "be able to generate an XML representation of its data" do
|
41
|
+
m = MyModel.new('foo' => 'bar')
|
42
|
+
m.foo = 'bar'
|
43
|
+
|
44
|
+
xml = <<-XML
|
45
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
46
|
+
|
47
|
+
XML
|
48
|
+
|
49
|
+
m.to_xml.should == '<?xml version="1.0" encoding="UTF-8"?><mymodel><foo>bar</foo></mymodel>'
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -12,9 +12,26 @@ module Unfuzzle
|
|
12
12
|
Unfuzzle::Request.get('/projects').should == 'response'
|
13
13
|
end
|
14
14
|
|
15
|
+
should "be able to perform a PUT request" do
|
16
|
+
request = mock() {|r| r.expects(:put).with().returns('response') }
|
17
|
+
Unfuzzle::Request.expects(:new).with('/projects', '<payload>', :format => :xml).returns(request)
|
18
|
+
|
19
|
+
Unfuzzle::Request.put('/projects', '<payload>').should == 'response'
|
20
|
+
end
|
21
|
+
|
15
22
|
end
|
16
23
|
|
17
24
|
context "An instance of the Request class" do
|
25
|
+
|
26
|
+
should "default the data format to JSON" do
|
27
|
+
request = Unfuzzle::Request.new('/projects')
|
28
|
+
request.request_format.should == 'json'
|
29
|
+
end
|
30
|
+
|
31
|
+
should "be able to override the request data format" do
|
32
|
+
request = Unfuzzle::Request.new('/projects', nil, :format => :xml)
|
33
|
+
request.request_format.should == 'xml'
|
34
|
+
end
|
18
35
|
|
19
36
|
should "have an endpoint URI" do
|
20
37
|
Unfuzzle.stubs(:subdomain).with().returns('viget')
|
@@ -23,6 +40,13 @@ module Unfuzzle
|
|
23
40
|
request.endpoint_uri.should == URI.parse('http://viget.unfuddle.com/api/v1/projects.json')
|
24
41
|
end
|
25
42
|
|
43
|
+
should "have an endpoint URI with the appropriate format when specified" do
|
44
|
+
Unfuzzle.stubs(:subdomain).with().returns('viget')
|
45
|
+
|
46
|
+
request = Unfuzzle::Request.new('/projects', nil, :format => :xml)
|
47
|
+
request.endpoint_uri.should == URI.parse('http://viget.unfuddle.com/api/v1/projects.xml')
|
48
|
+
end
|
49
|
+
|
26
50
|
should "have a client" do
|
27
51
|
client = stub()
|
28
52
|
|
@@ -57,6 +81,33 @@ module Unfuzzle
|
|
57
81
|
request.get.should == response
|
58
82
|
end
|
59
83
|
|
84
|
+
should "be able to perform a PUT request" do
|
85
|
+
Unfuzzle.stubs(:username).with().returns('username')
|
86
|
+
Unfuzzle.stubs(:password).with().returns('password')
|
87
|
+
|
88
|
+
request_body = '<payload>'
|
89
|
+
|
90
|
+
request = Unfuzzle::Request.new('/projects', request_body)
|
91
|
+
|
92
|
+
request.stubs(:endpoint_uri).returns(URI.parse('http://example.com/projects'))
|
93
|
+
|
94
|
+
put_request = mock() do |p|
|
95
|
+
p.expects(:basic_auth).with('username', 'password')
|
96
|
+
p.expects(:content_type=).with('application/xml')
|
97
|
+
end
|
98
|
+
|
99
|
+
client = mock() {|c| c.expects(:request).with(put_request, request_body).returns('response') }
|
100
|
+
|
101
|
+
response = stub()
|
102
|
+
Unfuzzle::Response.expects(:new).with('response').returns(response)
|
103
|
+
|
104
|
+
Net::HTTP::Put.expects(:new).with('/projects').returns(put_request)
|
105
|
+
|
106
|
+
request.stubs(:client).with().returns(client)
|
107
|
+
|
108
|
+
request.put.should == response
|
109
|
+
end
|
110
|
+
|
60
111
|
end
|
61
112
|
|
62
113
|
end
|
@@ -45,6 +45,8 @@ module Unfuzzle
|
|
45
45
|
when_populating Ticket, :from => 'tickets' do
|
46
46
|
|
47
47
|
value_for :id, :is => 1
|
48
|
+
value_for :project_id, :is => 1
|
49
|
+
value_for :milestone_id, :is => 1
|
48
50
|
value_for :created_timestamp, :is => '2008-11-25T14:00:19Z'
|
49
51
|
value_for :updated_timestamp, :is => '2008-12-31T15:51:41Z'
|
50
52
|
value_for :number, :is => 1
|
@@ -54,9 +56,12 @@ module Unfuzzle
|
|
54
56
|
value_for :status, :is => 'closed'
|
55
57
|
|
56
58
|
end
|
57
|
-
|
59
|
+
|
60
|
+
should_set_a_value_for :title
|
61
|
+
should_set_a_value_for :description
|
62
|
+
|
58
63
|
context "with a new instance" do
|
59
|
-
setup { @ticket = Ticket.new(
|
64
|
+
setup { @ticket = Ticket.new({}) }
|
60
65
|
|
61
66
|
should "have a create date/time" do
|
62
67
|
DateTime.expects(:parse).with('2008-07-28T16:57:10Z').returns('create_date')
|
@@ -83,6 +88,29 @@ module Unfuzzle
|
|
83
88
|
@ticket.stubs(:due_datestamp).with().returns(nil)
|
84
89
|
@ticket.due_on.should be(nil)
|
85
90
|
end
|
91
|
+
|
92
|
+
should "have an associated milestone" do
|
93
|
+
Milestone.expects(:find_by_project_id_and_milestone_id).with(1, 2).returns('milestone')
|
94
|
+
|
95
|
+
@ticket.stubs(:project_id).with().returns(1)
|
96
|
+
@ticket.stubs(:milestone_id).with().returns(2)
|
97
|
+
|
98
|
+
@ticket.milestone.should == 'milestone'
|
99
|
+
end
|
100
|
+
|
101
|
+
should "be able to perform an update" do
|
102
|
+
@ticket.stubs(:project_id).with().returns(1)
|
103
|
+
@ticket.stubs(:id).with().returns(2)
|
104
|
+
|
105
|
+
resource_path = '/projects/1/tickets/2'
|
106
|
+
ticket_xml = '<ticket />'
|
107
|
+
|
108
|
+
@ticket.stubs(:to_xml).with().returns(ticket_xml)
|
109
|
+
|
110
|
+
Unfuzzle::Request.expects(:put).with(resource_path, ticket_xml).returns('response')
|
111
|
+
|
112
|
+
@ticket.update.should == 'response'
|
113
|
+
end
|
86
114
|
|
87
115
|
end
|
88
116
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vigetlabs-unfuzzle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patrick Reagan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-06
|
12
|
+
date: 2009-07-06 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- lib/unfuzzle/version.rb
|
44
44
|
- lib/unfuzzle.rb
|
45
45
|
- test/fixtures
|
46
|
+
- test/fixtures/milestone.json
|
46
47
|
- test/fixtures/milestones.json
|
47
48
|
- test/fixtures/project.json
|
48
49
|
- test/fixtures/projects.json
|
@@ -51,12 +52,13 @@ files:
|
|
51
52
|
- test/unit
|
52
53
|
- test/unit/unfuzzle
|
53
54
|
- test/unit/unfuzzle/milestone_test.rb
|
55
|
+
- test/unit/unfuzzle/model_test.rb
|
54
56
|
- test/unit/unfuzzle/project_test.rb
|
55
57
|
- test/unit/unfuzzle/request_test.rb
|
56
58
|
- test/unit/unfuzzle/response_test.rb
|
57
59
|
- test/unit/unfuzzle/ticket_test.rb
|
58
60
|
- test/unit/unfuzzle_test.rb
|
59
|
-
has_rdoc:
|
61
|
+
has_rdoc: false
|
60
62
|
homepage: http://www.viget.com/extend
|
61
63
|
post_install_message:
|
62
64
|
rdoc_options:
|
@@ -81,7 +83,7 @@ requirements: []
|
|
81
83
|
rubyforge_project:
|
82
84
|
rubygems_version: 1.2.0
|
83
85
|
signing_key:
|
84
|
-
specification_version:
|
86
|
+
specification_version: 3
|
85
87
|
summary: This gem provides an interface to the Unfuddle JSON API
|
86
88
|
test_files: []
|
87
89
|
|