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.
@@ -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)
@@ -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
- def #{name}
10
- @response_data['#{key}']
11
- end
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)
@@ -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}.json")
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
@@ -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
@@ -3,7 +3,7 @@ module Unfuzzle
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 1
6
- TINY = 0
6
+ TINY = 1
7
7
 
8
8
  def self.to_s # :nodoc:
9
9
  [MAJOR, MINOR, TINY].join('.')
data/lib/unfuzzle.rb CHANGED
@@ -3,6 +3,7 @@ $:.unshift File.dirname(__FILE__)
3
3
  require 'uri'
4
4
  require 'net/http'
5
5
  require 'json'
6
+ require 'builder'
6
7
 
7
8
  require 'unfuzzle/request'
8
9
  require 'unfuzzle/response'
@@ -0,0 +1,11 @@
1
+ {
2
+ "archived": false,
3
+ "created_at": "2009-04-02T19:43:16Z",
4
+ "completed": false,
5
+ "title": "Projekt",
6
+ "due_on": "2009-04-03",
7
+ "person_responsible_id": 123,
8
+ "updated_at": "2009-07-02T16:40:28Z",
9
+ "id": 2,
10
+ "project_id": 1
11
+ }
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
@@ -99,7 +99,7 @@ module Unfuzzle
99
99
  @project.stubs(:id).with().returns(id)
100
100
  @project.tickets.should == 'tickets'
101
101
  end
102
-
102
+
103
103
  end
104
104
  end
105
105
 
@@ -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(stub()) }
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.0
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-24 00:00:00 -07:00
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: true
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: 2
86
+ specification_version: 3
85
87
  summary: This gem provides an interface to the Unfuddle JSON API
86
88
  test_files: []
87
89