vigetlabs-unfuzzle 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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