vigetlabs-unfuzzle 0.1.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/README.rdoc +109 -0
- data/Rakefile +39 -0
- data/lib/unfuzzle/milestone.rb +54 -0
- data/lib/unfuzzle/model.rb +30 -0
- data/lib/unfuzzle/project.rb +68 -0
- data/lib/unfuzzle/request.rb +37 -0
- data/lib/unfuzzle/response.rb +32 -0
- data/lib/unfuzzle/ticket.rb +55 -0
- data/lib/unfuzzle/version.rb +13 -0
- data/lib/unfuzzle.rb +72 -0
- data/test/fixtures/milestones.json +22 -0
- data/test/fixtures/project.json +16 -0
- data/test/fixtures/projects.json +32 -0
- data/test/fixtures/tickets.json +44 -0
- data/test/test_helper.rb +49 -0
- data/test/unit/unfuzzle/milestone_test.rb +97 -0
- data/test/unit/unfuzzle/project_test.rb +107 -0
- data/test/unit/unfuzzle/request_test.rb +63 -0
- data/test/unit/unfuzzle/response_test.rb +65 -0
- data/test/unit/unfuzzle/ticket_test.rb +92 -0
- data/test/unit/unfuzzle_test.rb +39 -0
- metadata +87 -0
data/README.rdoc
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
= Unfuzzle
|
2
|
+
|
3
|
+
== Description
|
4
|
+
|
5
|
+
The Unfuzzle gem provides an interface to the Unfuddle JSON API
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
sudo gem install vigetlabs-unfuzzle --source=http://gems.github.com
|
10
|
+
|
11
|
+
== Usage
|
12
|
+
|
13
|
+
To get started, you'll need your Unfuddle subdomain and a valid username /
|
14
|
+
password combination:
|
15
|
+
|
16
|
+
require 'unfuzzle'
|
17
|
+
|
18
|
+
Unfuzzle.subdomain = 'viget'
|
19
|
+
Unfuzzle.username = 'bopbip'
|
20
|
+
Unfuzzle.password = 'bleep'
|
21
|
+
|
22
|
+
Once that is configured, you can start accessing data from the API.
|
23
|
+
|
24
|
+
=== Projects
|
25
|
+
|
26
|
+
Pulling back a list of projects is simple. Based on the currently logged-in
|
27
|
+
user, you can see which ones he has access to:
|
28
|
+
|
29
|
+
projects = Unfuzzle.projects # => [#<Unfuzzle::Project:0x11e9280 ...> , ...]
|
30
|
+
|
31
|
+
If you don't want all projects, you can find one by its slug (or short name):
|
32
|
+
|
33
|
+
Unfuzzle.project('salty') # => #<Unfuzzle::Project:0x11e9280 ...>
|
34
|
+
|
35
|
+
Or by ID:
|
36
|
+
|
37
|
+
Unfuzzle.project(1) # => #<Unfuzzle::Project:0x11e9280 ...>
|
38
|
+
|
39
|
+
There are a few attributes available for a project:
|
40
|
+
|
41
|
+
project = Unfuzzle.projects.first
|
42
|
+
project.id # => 123
|
43
|
+
project.slug # => "salty"
|
44
|
+
project.name # => "Salty Co."
|
45
|
+
project.archived? # => false
|
46
|
+
project.created_at.strftime('%Y-%m-%d') # => "2008-07-28"
|
47
|
+
|
48
|
+
To see a list of additional attributes, take a look at the documentation for
|
49
|
+
Project.
|
50
|
+
|
51
|
+
=== Milestones
|
52
|
+
|
53
|
+
Each project can have milestones. You can access these from a single project:
|
54
|
+
|
55
|
+
project.milestones # => [#<Unfuzzle::Milestone:0x10bdca8 ...>, ...]
|
56
|
+
|
57
|
+
Milestones have attributes:
|
58
|
+
|
59
|
+
milestone = project.milestones.first
|
60
|
+
milestone.id # => 1
|
61
|
+
milestone.name # => "Milestone #1"
|
62
|
+
milestone.due_on.strftime('%m/%d/%Y') # => "07/30/2008"
|
63
|
+
|
64
|
+
A full list is available in the Milestone documentation.
|
65
|
+
|
66
|
+
=== Tickets
|
67
|
+
|
68
|
+
Tickets exist for a project:
|
69
|
+
|
70
|
+
ticket = project.tickets.first
|
71
|
+
ticket.title # => "Ticket #23"
|
72
|
+
ticket.number # => 23
|
73
|
+
ticket.description # => "Yo dawg, I hear you like tickets in your project ..."
|
74
|
+
ticket.status # => "closed"
|
75
|
+
|
76
|
+
And can also be associated to a milestone for the project:
|
77
|
+
|
78
|
+
ticket = project.milestones.first.tickets.first
|
79
|
+
ticket.title # => "Ticket #1"
|
80
|
+
ticket.number # => 1
|
81
|
+
ticket.description # => "Wash my car"
|
82
|
+
ticket.status # => "closed"
|
83
|
+
|
84
|
+
See the Ticket documentation for more information.
|
85
|
+
|
86
|
+
== License
|
87
|
+
|
88
|
+
Copyright (c) 2009 Patrick Reagan of Viget Labs (mailto:patrick.reagan@viget.com)
|
89
|
+
|
90
|
+
Permission is hereby granted, free of charge, to any person
|
91
|
+
obtaining a copy of this software and associated documentation
|
92
|
+
files (the "Software"), to deal in the Software without
|
93
|
+
restriction, including without limitation the rights to use,
|
94
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
95
|
+
copies of the Software, and to permit persons to whom the
|
96
|
+
Software is furnished to do so, subject to the following
|
97
|
+
conditions:
|
98
|
+
|
99
|
+
The above copyright notice and this permission notice shall be
|
100
|
+
included in all copies or substantial portions of the Software.
|
101
|
+
|
102
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
103
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
104
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
105
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
106
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
107
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
108
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
109
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
require 'lib/unfuzzle/version'
|
6
|
+
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
spec = Gem::Specification.new do |s|
|
10
|
+
s.name = 'unfuzzle'
|
11
|
+
s.version = Unfuzzle::Version.to_s
|
12
|
+
s.has_rdoc = true
|
13
|
+
s.extra_rdoc_files = %w(README.rdoc)
|
14
|
+
s.rdoc_options = %w(--main README.rdoc)
|
15
|
+
s.summary = "This gem provides an interface to the Unfuddle JSON API"
|
16
|
+
s.author = 'Patrick Reagan'
|
17
|
+
s.email = 'patrick.reagan@viget.com'
|
18
|
+
s.homepage = 'http://www.viget.com/extend'
|
19
|
+
s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
|
20
|
+
|
21
|
+
s.add_dependency('json', '>= 1.1.6')
|
22
|
+
end
|
23
|
+
|
24
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
25
|
+
pkg.gem_spec = spec
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::TestTask.new do |t|
|
29
|
+
t.libs << 'test'
|
30
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
31
|
+
t.verbose = true
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'Generate the gemspec to serve this Gem from Github'
|
35
|
+
task :github do
|
36
|
+
file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
|
37
|
+
File.open(file, 'w') {|f| f << spec.to_ruby }
|
38
|
+
puts "Created gemspec: #{file}"
|
39
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Unfuzzle
|
2
|
+
|
3
|
+
# = Milestone
|
4
|
+
#
|
5
|
+
# A representation of an Unfuddle Milestone. Has the following attributes:
|
6
|
+
#
|
7
|
+
# [id] Unique identifier for this milestone
|
8
|
+
# [name] Name of the milestone
|
9
|
+
#
|
10
|
+
class Milestone
|
11
|
+
|
12
|
+
include Unfuzzle::Model
|
13
|
+
|
14
|
+
attribute :id
|
15
|
+
attribute :project_id
|
16
|
+
attribute :archived
|
17
|
+
attribute :name, :from => :title
|
18
|
+
attribute :created_timestamp, :from => :created_at
|
19
|
+
attribute :updated_timestamp, :from => :updated_at
|
20
|
+
attribute :due_datestamp, :from => :due_on
|
21
|
+
|
22
|
+
# Return a list of all milestones for a given project
|
23
|
+
def self.find_all_by_project_id(project_id)
|
24
|
+
response = Request.get("/projects/#{project_id}/milestones")
|
25
|
+
response.data.map {|data| new(data) }
|
26
|
+
end
|
27
|
+
|
28
|
+
# Has this milestone been archived?
|
29
|
+
def archived?
|
30
|
+
archived == true
|
31
|
+
end
|
32
|
+
|
33
|
+
# The DateTime that this milestone was created
|
34
|
+
def created_at
|
35
|
+
DateTime.parse(created_timestamp)
|
36
|
+
end
|
37
|
+
|
38
|
+
# The DateTime that this milestone was last updated
|
39
|
+
def updated_at
|
40
|
+
DateTime.parse(updated_timestamp)
|
41
|
+
end
|
42
|
+
|
43
|
+
# The Date that this milestone is due
|
44
|
+
def due_on
|
45
|
+
Date.parse(due_datestamp) unless due_datestamp.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
# The collection of Tickets associated to this milestone
|
49
|
+
def tickets
|
50
|
+
Ticket.find_all_by_project_id_and_milestone_id(project_id, id)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Unfuzzle
|
2
|
+
module Model # :nodoc:
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
def attribute(name, options = {}) # :nodoc:
|
6
|
+
key = options.delete(:from) || name
|
7
|
+
|
8
|
+
class_eval %(
|
9
|
+
def #{name}
|
10
|
+
@response_data['#{key}']
|
11
|
+
end
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
|
18
|
+
def initialize(response_data)
|
19
|
+
@response_data = response_data
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(other)
|
25
|
+
other.send(:extend, Unfuzzle::Model::ClassMethods)
|
26
|
+
other.send(:include, Unfuzzle::Model::InstanceMethods)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Unfuzzle
|
2
|
+
|
3
|
+
# = Project
|
4
|
+
#
|
5
|
+
# Represents an Unfuddle project. Has the following attributes:
|
6
|
+
#
|
7
|
+
# [id] The unique identifier for this project
|
8
|
+
# [slug] The "short name" for this project
|
9
|
+
# [name] The name of this project
|
10
|
+
# [description] The description for the project
|
11
|
+
#
|
12
|
+
class Project
|
13
|
+
|
14
|
+
include Unfuzzle::Model
|
15
|
+
|
16
|
+
attribute :id
|
17
|
+
attribute :slug, :from => :short_name
|
18
|
+
attribute :archived
|
19
|
+
attribute :name, :from => :title
|
20
|
+
attribute :description
|
21
|
+
attribute :created_timestamp, :from => :created_at
|
22
|
+
attribute :updated_timestamp, :from => :updated_at
|
23
|
+
|
24
|
+
# Return a list of all projects to which the current user has access
|
25
|
+
def self.all
|
26
|
+
response = Request.get('/projects')
|
27
|
+
response.data.map {|data| new(data) }
|
28
|
+
end
|
29
|
+
|
30
|
+
# Find a single project by its slug (short name)
|
31
|
+
def self.find_by_slug(slug)
|
32
|
+
response = Request.get("/projects/by_short_name/#{slug}")
|
33
|
+
new(response.data)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Find a single project by its ID
|
37
|
+
def self.find_by_id(id)
|
38
|
+
response = Request.get("/projects/#{id}")
|
39
|
+
new(response.data)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Has this project been archived?
|
43
|
+
def archived?
|
44
|
+
archived == true
|
45
|
+
end
|
46
|
+
|
47
|
+
# The DateTime that this project was created
|
48
|
+
def created_at
|
49
|
+
DateTime.parse(created_timestamp)
|
50
|
+
end
|
51
|
+
|
52
|
+
# The DateTime that this project was last updated
|
53
|
+
def updated_at
|
54
|
+
DateTime.parse(updated_timestamp)
|
55
|
+
end
|
56
|
+
|
57
|
+
# The collection of Milestones associated to this project
|
58
|
+
def milestones
|
59
|
+
Milestone.find_all_by_project_id(id)
|
60
|
+
end
|
61
|
+
|
62
|
+
# The collection of Tickets associated to this project
|
63
|
+
def tickets
|
64
|
+
Ticket.find_all_by_project_id(id)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Unfuzzle
|
2
|
+
|
3
|
+
# = Request
|
4
|
+
#
|
5
|
+
# A basic wrapper for GET requests to the Unfuddle API
|
6
|
+
#
|
7
|
+
class Request
|
8
|
+
|
9
|
+
# Retrieve a response from the given resource path
|
10
|
+
def self.get(resource_path)
|
11
|
+
request = new(resource_path)
|
12
|
+
request.get
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create a new request for the given resource path
|
16
|
+
def initialize(resource_path)
|
17
|
+
@resource_path = resource_path
|
18
|
+
end
|
19
|
+
|
20
|
+
def endpoint_uri # :nodoc:
|
21
|
+
URI.parse("http://#{Unfuzzle.subdomain}.unfuddle.com/api/v1#{@resource_path}.json")
|
22
|
+
end
|
23
|
+
|
24
|
+
def client # :nodoc:
|
25
|
+
Net::HTTP.new(endpoint_uri.host)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Retrieve a response from the current resource path
|
29
|
+
def get
|
30
|
+
request = Net::HTTP::Get.new(endpoint_uri.path)
|
31
|
+
request.basic_auth Unfuzzle.username, Unfuzzle.password
|
32
|
+
|
33
|
+
Response.new(client.request(request))
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Unfuzzle
|
2
|
+
|
3
|
+
# = Response
|
4
|
+
#
|
5
|
+
# A simple wrapper around an HTTP response from the Unfuddle API
|
6
|
+
#
|
7
|
+
class Response
|
8
|
+
|
9
|
+
# Create a new response from an HTTP response object
|
10
|
+
def initialize(http_response)
|
11
|
+
@http_response = http_response
|
12
|
+
end
|
13
|
+
|
14
|
+
# Was there an error produced as part of the request?
|
15
|
+
def error?
|
16
|
+
!@http_response.is_a?(Net::HTTPSuccess)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Raw body of the HTTP response
|
20
|
+
def body
|
21
|
+
@http_response.body
|
22
|
+
end
|
23
|
+
|
24
|
+
# Parsed JSON response body
|
25
|
+
def data
|
26
|
+
if !error?
|
27
|
+
@parsed_data ||= JSON.parse(body)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Unfuzzle
|
2
|
+
|
3
|
+
# = Ticket
|
4
|
+
#
|
5
|
+
# Represents a single Unfuddle Ticket - is associated to a project
|
6
|
+
# and optionally a project's milestone. Has the following attributes:
|
7
|
+
#
|
8
|
+
# [id] The unique identifier for this ticket
|
9
|
+
# [number] The ticket's number - this is displayed in the web interface
|
10
|
+
# [title] The title of the ticket (short)
|
11
|
+
# [description] The full description of the ticket
|
12
|
+
# [status] The ticket's status (new / accepted / resolved / closed)
|
13
|
+
#
|
14
|
+
class Ticket
|
15
|
+
|
16
|
+
include Unfuzzle::Model
|
17
|
+
|
18
|
+
attribute :id
|
19
|
+
attribute :number
|
20
|
+
attribute :title, :from => :summary
|
21
|
+
attribute :description
|
22
|
+
attribute :due_datestamp, :from => :due_on
|
23
|
+
attribute :created_timestamp, :from => :created_at
|
24
|
+
attribute :updated_timestamp, :from => :updated_at
|
25
|
+
attribute :status
|
26
|
+
|
27
|
+
# Return a list of all tickets for an individual project
|
28
|
+
def self.find_all_by_project_id(project_id)
|
29
|
+
response = Request.get("/projects/#{project_id}/tickets")
|
30
|
+
response.data.map {|data| new(data) }
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return a list of all tickets for a given milestone as part of a project
|
34
|
+
def self.find_all_by_project_id_and_milestone_id(project_id, milestone_id)
|
35
|
+
response = Request.get("/projects/#{project_id}/milestones/#{milestone_id}/tickets")
|
36
|
+
response.data.map {|data| new(data) }
|
37
|
+
end
|
38
|
+
|
39
|
+
# The DateTime that this milestone was created
|
40
|
+
def created_at
|
41
|
+
DateTime.parse(created_timestamp)
|
42
|
+
end
|
43
|
+
|
44
|
+
# The DateTime that this milestone was last updated
|
45
|
+
def updated_at
|
46
|
+
DateTime.parse(updated_timestamp)
|
47
|
+
end
|
48
|
+
|
49
|
+
# The Date that this milestone is due
|
50
|
+
def due_on
|
51
|
+
Date.parse(due_datestamp) unless due_datestamp.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
data/lib/unfuzzle.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
require 'net/http'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
require 'unfuzzle/request'
|
8
|
+
require 'unfuzzle/response'
|
9
|
+
require 'unfuzzle/model'
|
10
|
+
require 'unfuzzle/project'
|
11
|
+
require 'unfuzzle/milestone'
|
12
|
+
require 'unfuzzle/ticket'
|
13
|
+
|
14
|
+
# = Unfuzzle: A simple wrapper around the Unfuddle JSON API
|
15
|
+
#
|
16
|
+
# == Quick Start
|
17
|
+
#
|
18
|
+
# To get started, you need to set the subdomain and a valid username /
|
19
|
+
# password combination:
|
20
|
+
#
|
21
|
+
# require 'rubygems'
|
22
|
+
# require 'unfuzzle'
|
23
|
+
#
|
24
|
+
# Unfuzzle.subdomain = 'viget'
|
25
|
+
# Unfuzzle.username = 'bopbip'
|
26
|
+
# Unfuzzle.password = 'bleep'
|
27
|
+
#
|
28
|
+
# From there, you can start accessing a list of projects:
|
29
|
+
#
|
30
|
+
# Project.all
|
31
|
+
#
|
32
|
+
module Unfuzzle
|
33
|
+
|
34
|
+
# Set the subdomain for all requests
|
35
|
+
def self.subdomain=(subdomain)
|
36
|
+
@subdomain = subdomain
|
37
|
+
end
|
38
|
+
|
39
|
+
# Set the username for all requests. Data retrieved from the API will be
|
40
|
+
# scoped to the data that this user has access to.
|
41
|
+
def self.username=(username)
|
42
|
+
@username = username
|
43
|
+
end
|
44
|
+
|
45
|
+
# Set the password for the supplied username
|
46
|
+
def self.password=(password)
|
47
|
+
@password = password
|
48
|
+
end
|
49
|
+
|
50
|
+
# Retrieve a project for the current user by its ID or slug
|
51
|
+
def self.project(id_or_slug)
|
52
|
+
id_or_slug.is_a?(String) ? Project.find_by_slug(id_or_slug) : Project.find_by_id(id_or_slug)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Get a list of all projects for this user
|
56
|
+
def self.projects
|
57
|
+
Project.all
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.subdomain # :nodoc:
|
61
|
+
@subdomain
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.username # :nodoc:
|
65
|
+
@username
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.password # :nodoc:
|
69
|
+
@password
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
[{
|
2
|
+
"archived": false,
|
3
|
+
"created_at": "2008-07-30T22:12:37Z",
|
4
|
+
"completed": true,
|
5
|
+
"title": "Milestone 1",
|
6
|
+
"person_responsible_id": 12345,
|
7
|
+
"due_on": "2008-07-30",
|
8
|
+
"updated_at": "2008-12-26T22:32:03Z",
|
9
|
+
"id": 1,
|
10
|
+
"project_id": 1
|
11
|
+
},
|
12
|
+
{
|
13
|
+
"archived": false,
|
14
|
+
"created_at": "2009-02-09T15:15:30Z",
|
15
|
+
"completed": true,
|
16
|
+
"title": "Milestone 2",
|
17
|
+
"person_responsible_id": 12344,
|
18
|
+
"due_on": "2009-02-13",
|
19
|
+
"updated_at": "2009-02-17T15:37:01Z",
|
20
|
+
"id": 2,
|
21
|
+
"project_id": 1
|
22
|
+
}]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"archived": false,
|
3
|
+
"short_name": "blip",
|
4
|
+
"created_at": "2008-07-28T16:57:10Z",
|
5
|
+
"title": "Blip Bleep Co.",
|
6
|
+
"close_ticket_simultaneously_default": true,
|
7
|
+
"account_id": 1,
|
8
|
+
"description": "This is the project for Blip Bleep Co.",
|
9
|
+
"enable_time_tracking": true,
|
10
|
+
"default_ticket_report_id": 0,
|
11
|
+
"updated_at": "2009-04-28T18:48:52Z",
|
12
|
+
"id": 1,
|
13
|
+
"theme": "teal",
|
14
|
+
"disk_usage": 1416,
|
15
|
+
"assignee_on_resolve": "none"
|
16
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
[{
|
2
|
+
"archived": false,
|
3
|
+
"short_name": "aa",
|
4
|
+
"created_at": "2008-07-28T16:57:10Z",
|
5
|
+
"title": "A Client",
|
6
|
+
"close_ticket_simultaneously_default": true,
|
7
|
+
"account_id": 12345,
|
8
|
+
"description": "A great project",
|
9
|
+
"enable_time_tracking": true,
|
10
|
+
"default_ticket_report_id": 0,
|
11
|
+
"updated_at": "2009-04-28T18:48:52Z",
|
12
|
+
"id": 1,
|
13
|
+
"theme": "teal",
|
14
|
+
"disk_usage": 1416,
|
15
|
+
"assignee_on_resolve": "none"
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"archived": true,
|
19
|
+
"short_name": "zz",
|
20
|
+
"created_at": "2008-06-23T21:06:01Z",
|
21
|
+
"title": "Zee Client",
|
22
|
+
"close_ticket_simultaneously_default": false,
|
23
|
+
"account_id": 12345,
|
24
|
+
"description": null,
|
25
|
+
"enable_time_tracking": true,
|
26
|
+
"default_ticket_report_id": null,
|
27
|
+
"updated_at": "2009-05-20T23:15:24Z",
|
28
|
+
"id": 2,
|
29
|
+
"theme": "grey",
|
30
|
+
"disk_usage": 14008,
|
31
|
+
"assignee_on_resolve": "reporter"
|
32
|
+
}]
|
@@ -0,0 +1,44 @@
|
|
1
|
+
[{
|
2
|
+
"severity_id": null,
|
3
|
+
"hours_estimate_current": 0.0,
|
4
|
+
"resolution_description": "",
|
5
|
+
"reporter_id": 1,
|
6
|
+
"created_at": "2008-11-25T14:00:19Z",
|
7
|
+
"priority": "4",
|
8
|
+
"number": 1,
|
9
|
+
"milestone_id": 1,
|
10
|
+
"description": "Do something important",
|
11
|
+
"assignee_id": null,
|
12
|
+
"due_on": null,
|
13
|
+
"status": "closed",
|
14
|
+
"summary": "Ticket #1",
|
15
|
+
"resolution": "fixed",
|
16
|
+
"component_id": null,
|
17
|
+
"version_id": null,
|
18
|
+
"updated_at": "2008-12-31T15:51:41Z",
|
19
|
+
"id": 1,
|
20
|
+
"project_id": 1,
|
21
|
+
"hours_estimate_initial": 1.75
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"severity_id": null,
|
25
|
+
"hours_estimate_current": 0.25,
|
26
|
+
"resolution_description": "",
|
27
|
+
"reporter_id": 1,
|
28
|
+
"created_at": "2009-02-09T15:17:52Z",
|
29
|
+
"priority": "3",
|
30
|
+
"number": 2,
|
31
|
+
"milestone_id": 1,
|
32
|
+
"description": "Do something else important",
|
33
|
+
"assignee_id": null,
|
34
|
+
"due_on": null,
|
35
|
+
"status": "closed",
|
36
|
+
"summary": "Ticket #2",
|
37
|
+
"resolution": "fixed",
|
38
|
+
"component_id": null,
|
39
|
+
"version_id": null,
|
40
|
+
"updated_at": "2009-02-17T15:36:40Z",
|
41
|
+
"id": 2,
|
42
|
+
"project_id": 1,
|
43
|
+
"hours_estimate_initial": 0.0
|
44
|
+
}]
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# http://sneaq.net/textmate-wtf
|
2
|
+
$:.reject! { |e| e.include? 'TextMate' }
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'throat_punch'
|
6
|
+
|
7
|
+
require File.dirname(__FILE__) + '/../lib/unfuzzle'
|
8
|
+
|
9
|
+
|
10
|
+
class Test::Unit::TestCase
|
11
|
+
|
12
|
+
def self.read_fixture(method_name)
|
13
|
+
file = File.dirname(__FILE__) + "/fixtures/#{method_name}.json"
|
14
|
+
JSON.parse(File.read(file))
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_fixture(method_name)
|
18
|
+
self.class.read_fixture(method_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def mock_request_cycle(options)
|
22
|
+
response = Unfuzzle::Response.new(stub())
|
23
|
+
|
24
|
+
data = read_fixture(options[:data])
|
25
|
+
|
26
|
+
response.stubs(:data).with().returns(data)
|
27
|
+
|
28
|
+
Unfuzzle::Request.stubs(:get).with(options[:for]).returns(response)
|
29
|
+
|
30
|
+
response
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.when_populating(klass, options, &block)
|
34
|
+
# data = options[:from].is_a?(String) ? read_fixture(options[:from])[0] : options[:from].call
|
35
|
+
|
36
|
+
context "with data populated for #{klass}" do
|
37
|
+
setup { @object = klass.new(read_fixture(options[:from])[0]) }
|
38
|
+
merge_block(&block)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.value_for(method_name, options)
|
44
|
+
should "have a value for :#{method_name}" do
|
45
|
+
@object.send(method_name).should == options[:is]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module Unfuzzle
|
4
|
+
class MilestoneTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "The Milestone class" do
|
7
|
+
|
8
|
+
should "be able to find all by project ID" do
|
9
|
+
project_id = 1
|
10
|
+
|
11
|
+
response = mock_request_cycle :for => "/projects/#{project_id}/milestones", :data => 'milestones'
|
12
|
+
|
13
|
+
milestones = Array.new
|
14
|
+
|
15
|
+
response.data.each do |data|
|
16
|
+
milestone = stub()
|
17
|
+
Unfuzzle::Milestone.expects(:new).with(data).returns(milestone)
|
18
|
+
milestones << milestone
|
19
|
+
end
|
20
|
+
|
21
|
+
Milestone.find_all_by_project_id(1).should == milestones
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
context "An instance of the Milestone class" do
|
27
|
+
|
28
|
+
when_populating Milestone, :from => 'milestones' do
|
29
|
+
|
30
|
+
value_for :id, :is => 1
|
31
|
+
value_for :project_id, :is => 1
|
32
|
+
value_for :archived, :is => false
|
33
|
+
value_for :created_timestamp, :is => '2008-07-30T22:12:37Z'
|
34
|
+
value_for :name, :is => 'Milestone 1'
|
35
|
+
value_for :due_datestamp, :is => '2008-07-30'
|
36
|
+
value_for :updated_timestamp, :is => '2008-12-26T22:32:03Z'
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with a new instance" do
|
41
|
+
|
42
|
+
setup { @milestone = Milestone.new(stub()) }
|
43
|
+
|
44
|
+
should "know that it is archived" do
|
45
|
+
@milestone.stubs(:archived).with().returns(true)
|
46
|
+
@milestone.archived?.should be(true)
|
47
|
+
end
|
48
|
+
|
49
|
+
should "know that it isn't archived" do
|
50
|
+
@milestone.stubs(:archived).with().returns(false)
|
51
|
+
@milestone.archived?.should be(false)
|
52
|
+
end
|
53
|
+
|
54
|
+
should "have a create date/time" do
|
55
|
+
DateTime.expects(:parse).with('2008-07-28T16:57:10Z').returns('create_date')
|
56
|
+
|
57
|
+
@milestone.stubs(:created_timestamp).with().returns('2008-07-28T16:57:10Z')
|
58
|
+
@milestone.created_at.should == 'create_date'
|
59
|
+
end
|
60
|
+
|
61
|
+
should "have an update date/time" do
|
62
|
+
DateTime.expects(:parse).with('2009-04-28T18:48:52Z').returns('update_date')
|
63
|
+
|
64
|
+
@milestone.stubs(:updated_timestamp).with().returns('2009-04-28T18:48:52Z')
|
65
|
+
@milestone.updated_at.should == 'update_date'
|
66
|
+
end
|
67
|
+
|
68
|
+
should "have a due date" do
|
69
|
+
Date.expects(:parse).with('2008-07-30').returns('due_date')
|
70
|
+
|
71
|
+
@milestone.stubs(:due_datestamp).with().returns('2008-07-30')
|
72
|
+
@milestone.due_on.should == 'due_date'
|
73
|
+
end
|
74
|
+
|
75
|
+
should "not have a due date if there isn't one associated" do
|
76
|
+
@milestone.stubs(:due_datestamp).with().returns(nil)
|
77
|
+
@milestone.due_on.should be(nil)
|
78
|
+
end
|
79
|
+
|
80
|
+
should "have associated tickets" do
|
81
|
+
id = 1
|
82
|
+
project_id = 1
|
83
|
+
|
84
|
+
Ticket.expects(:find_all_by_project_id_and_milestone_id).with(project_id, id).returns('tickets')
|
85
|
+
|
86
|
+
@milestone.stubs(:id).with().returns(id)
|
87
|
+
@milestone.stubs(:project_id).with().returns(project_id)
|
88
|
+
|
89
|
+
@milestone.tickets.should == 'tickets'
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module Unfuzzle
|
4
|
+
class ProjectTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "The Project class" do
|
7
|
+
|
8
|
+
should "be able to return a list of all projects" do
|
9
|
+
response = mock_request_cycle :for => '/projects', :data => 'projects'
|
10
|
+
|
11
|
+
elements = Array.new
|
12
|
+
|
13
|
+
response.data.each do |data|
|
14
|
+
element = stub()
|
15
|
+
Unfuzzle::Project.expects(:new).with(data).returns(element)
|
16
|
+
elements << element
|
17
|
+
end
|
18
|
+
|
19
|
+
Project.all.should == elements
|
20
|
+
end
|
21
|
+
|
22
|
+
should "be able to find a project by its slug" do
|
23
|
+
slug = 'blip'
|
24
|
+
|
25
|
+
response = mock_request_cycle :for => "/projects/by_short_name/#{slug}", :data => 'project'
|
26
|
+
|
27
|
+
Unfuzzle::Project.expects(:new).with(response.data).returns('project')
|
28
|
+
|
29
|
+
Project.find_by_slug(slug).should == 'project'
|
30
|
+
end
|
31
|
+
|
32
|
+
should "be able to find a project by its ID" do
|
33
|
+
id = 1
|
34
|
+
|
35
|
+
response = mock_request_cycle :for => "/projects/#{id}", :data => 'project'
|
36
|
+
|
37
|
+
Unfuzzle::Project.expects(:new).with(response.data).returns('project')
|
38
|
+
|
39
|
+
Project.find_by_id(id).should == 'project'
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
context "An instance of the Project class" do
|
46
|
+
|
47
|
+
when_populating Project, :from => 'projects' do
|
48
|
+
|
49
|
+
value_for :id, :is => 1
|
50
|
+
value_for :archived, :is => false
|
51
|
+
value_for :slug, :is => 'aa'
|
52
|
+
value_for :name, :is => 'A Client'
|
53
|
+
value_for :description, :is => 'A great project'
|
54
|
+
value_for :created_timestamp, :is => '2008-07-28T16:57:10Z'
|
55
|
+
value_for :updated_timestamp, :is => '2009-04-28T18:48:52Z'
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with a new instance" do
|
60
|
+
|
61
|
+
setup { @project = Project.new(stub()) }
|
62
|
+
|
63
|
+
should "know that it's archived" do
|
64
|
+
@project.stubs(:archived).with().returns(true)
|
65
|
+
@project.archived?.should be(true)
|
66
|
+
end
|
67
|
+
|
68
|
+
should "know that it's not archived" do
|
69
|
+
@project.stubs(:archived).with().returns(false)
|
70
|
+
@project.archived?.should be(false)
|
71
|
+
end
|
72
|
+
|
73
|
+
should "have a create date" do
|
74
|
+
DateTime.expects(:parse).with('2008-07-28T16:57:10Z').returns('create_date')
|
75
|
+
|
76
|
+
@project.stubs(:created_timestamp).with().returns('2008-07-28T16:57:10Z')
|
77
|
+
@project.created_at.should == 'create_date'
|
78
|
+
end
|
79
|
+
|
80
|
+
should "have an update date" do
|
81
|
+
DateTime.expects(:parse).with('2009-04-28T18:48:52Z').returns('update_date')
|
82
|
+
|
83
|
+
@project.stubs(:updated_timestamp).with().returns('2009-04-28T18:48:52Z')
|
84
|
+
@project.updated_at.should == 'update_date'
|
85
|
+
end
|
86
|
+
|
87
|
+
should "have a list of associated milestones" do
|
88
|
+
id = 1
|
89
|
+
Milestone.expects(:find_all_by_project_id).with(id).returns('milestones')
|
90
|
+
|
91
|
+
@project.stubs(:id).with().returns(id)
|
92
|
+
@project.milestones.should == 'milestones'
|
93
|
+
end
|
94
|
+
|
95
|
+
should "have a list of associated tickets" do
|
96
|
+
id = 1
|
97
|
+
Ticket.expects(:find_all_by_project_id).with(id).returns('tickets')
|
98
|
+
|
99
|
+
@project.stubs(:id).with().returns(id)
|
100
|
+
@project.tickets.should == 'tickets'
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module Unfuzzle
|
4
|
+
class RequestTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "The Request class" do
|
7
|
+
|
8
|
+
should "be able to perform a GET request" do
|
9
|
+
request = mock() {|r| r.expects(:get).with().returns('response') }
|
10
|
+
Unfuzzle::Request.expects(:new).with('/projects').returns(request)
|
11
|
+
|
12
|
+
Unfuzzle::Request.get('/projects').should == 'response'
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
context "An instance of the Request class" do
|
18
|
+
|
19
|
+
should "have an endpoint URI" do
|
20
|
+
Unfuzzle.stubs(:subdomain).with().returns('viget')
|
21
|
+
|
22
|
+
request = Unfuzzle::Request.new('/projects')
|
23
|
+
request.endpoint_uri.should == URI.parse('http://viget.unfuddle.com/api/v1/projects.json')
|
24
|
+
end
|
25
|
+
|
26
|
+
should "have a client" do
|
27
|
+
client = stub()
|
28
|
+
|
29
|
+
request = Unfuzzle::Request.new('/projects')
|
30
|
+
request.stubs(:endpoint_uri).with().returns(URI.parse('http://example.com'))
|
31
|
+
|
32
|
+
Net::HTTP.expects(:new).with('example.com').returns(client)
|
33
|
+
|
34
|
+
request.client.should == client
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be able to perform a GET request" do
|
38
|
+
Unfuzzle.stubs(:username).with().returns('username')
|
39
|
+
Unfuzzle.stubs(:password).with().returns('password')
|
40
|
+
|
41
|
+
request = Unfuzzle::Request.new('/projects')
|
42
|
+
request.stubs(:endpoint_uri).returns(URI.parse('http://example.com/projects'))
|
43
|
+
|
44
|
+
get_request = mock() do |g|
|
45
|
+
g.expects(:basic_auth).with('username', 'password')
|
46
|
+
end
|
47
|
+
|
48
|
+
client = mock() {|c| c.expects(:request).with(get_request).returns('response') }
|
49
|
+
|
50
|
+
response = stub()
|
51
|
+
Unfuzzle::Response.expects(:new).with('response').returns(response)
|
52
|
+
|
53
|
+
Net::HTTP::Get.expects(:new).with('/projects').returns(get_request)
|
54
|
+
|
55
|
+
request.stubs(:client).with().returns(client)
|
56
|
+
|
57
|
+
request.get.should == response
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module Unfuzzle
|
4
|
+
class ResponseTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the Response class" do
|
7
|
+
|
8
|
+
should "delegate to the HTTP response to determine the body" do
|
9
|
+
http_response = mock() {|r| r.expects(:body).with().returns('check mah boday') }
|
10
|
+
|
11
|
+
response = Unfuzzle::Response.new(http_response)
|
12
|
+
|
13
|
+
response.body.should == 'check mah boday'
|
14
|
+
end
|
15
|
+
|
16
|
+
should "know that there are no errors" do
|
17
|
+
http_response = mock() do |r|
|
18
|
+
r.expects(:is_a?).with(Net::HTTPSuccess).returns(true)
|
19
|
+
end
|
20
|
+
|
21
|
+
response = Unfuzzle::Response.new(http_response)
|
22
|
+
response.error?.should be(false)
|
23
|
+
end
|
24
|
+
|
25
|
+
should "know if there are errors" do
|
26
|
+
http_response = mock() do |r|
|
27
|
+
r.expects(:is_a?).with(Net::HTTPSuccess).returns(false)
|
28
|
+
end
|
29
|
+
|
30
|
+
response = Unfuzzle::Response.new(http_response)
|
31
|
+
response.error?.should be(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
should "be able to parse the response" do
|
35
|
+
response = Unfuzzle::Response.new(stub())
|
36
|
+
response.expects(:body).with().returns('json')
|
37
|
+
response.stubs(:error?).with().returns(false)
|
38
|
+
|
39
|
+
JSON.expects(:parse).with('json').returns('data')
|
40
|
+
|
41
|
+
response.data.should == 'data'
|
42
|
+
end
|
43
|
+
|
44
|
+
should "cache the parsed data from the response" do
|
45
|
+
response = Unfuzzle::Response.new(stub())
|
46
|
+
response.stubs(:body).with().returns('json')
|
47
|
+
response.stubs(:error?).with().returns(false)
|
48
|
+
|
49
|
+
JSON.stubs(:parse).with('json').once.returns('data')
|
50
|
+
|
51
|
+
2.times { response.data }
|
52
|
+
end
|
53
|
+
|
54
|
+
should "return nil when parsing data if there are errors in the response" do
|
55
|
+
response = Unfuzzle::Response.new(stub())
|
56
|
+
response.expects(:error?).with().returns(true)
|
57
|
+
|
58
|
+
response.data.should be(nil)
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module Unfuzzle
|
4
|
+
class TicketTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "The Ticket class" do
|
7
|
+
|
8
|
+
should "be able to return a list of tickets for a project" do
|
9
|
+
project_id = 1
|
10
|
+
|
11
|
+
response = mock_request_cycle :for => "/projects/#{project_id}/tickets", :data => 'tickets'
|
12
|
+
|
13
|
+
tickets = []
|
14
|
+
|
15
|
+
response.data.each do |data|
|
16
|
+
ticket = stub()
|
17
|
+
Ticket.expects(:new).with(data).returns(ticket)
|
18
|
+
tickets << ticket
|
19
|
+
end
|
20
|
+
|
21
|
+
Ticket.find_all_by_project_id(project_id).should == tickets
|
22
|
+
end
|
23
|
+
|
24
|
+
should "be able to return a list of tickets for a milestone" do
|
25
|
+
milestone_id = 1
|
26
|
+
project_id = 1
|
27
|
+
|
28
|
+
response = mock_request_cycle :for => "/projects/#{project_id}/milestones/#{milestone_id}/tickets", :data => 'tickets'
|
29
|
+
|
30
|
+
tickets = []
|
31
|
+
|
32
|
+
response.data.each do |data|
|
33
|
+
ticket = stub()
|
34
|
+
Ticket.expects(:new).with(data).returns(ticket)
|
35
|
+
tickets << ticket
|
36
|
+
end
|
37
|
+
|
38
|
+
Ticket.find_all_by_project_id_and_milestone_id(project_id, milestone_id).should == tickets
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
context "An instance of the Ticket class" do
|
44
|
+
|
45
|
+
when_populating Ticket, :from => 'tickets' do
|
46
|
+
|
47
|
+
value_for :id, :is => 1
|
48
|
+
value_for :created_timestamp, :is => '2008-11-25T14:00:19Z'
|
49
|
+
value_for :updated_timestamp, :is => '2008-12-31T15:51:41Z'
|
50
|
+
value_for :number, :is => 1
|
51
|
+
value_for :title, :is => 'Ticket #1'
|
52
|
+
value_for :description, :is => 'Do something important'
|
53
|
+
value_for :due_datestamp, :is => nil
|
54
|
+
value_for :status, :is => 'closed'
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with a new instance" do
|
59
|
+
setup { @ticket = Ticket.new(stub()) }
|
60
|
+
|
61
|
+
should "have a create date/time" do
|
62
|
+
DateTime.expects(:parse).with('2008-07-28T16:57:10Z').returns('create_date')
|
63
|
+
|
64
|
+
@ticket.stubs(:created_timestamp).with().returns('2008-07-28T16:57:10Z')
|
65
|
+
@ticket.created_at.should == 'create_date'
|
66
|
+
end
|
67
|
+
|
68
|
+
should "have an update date/time" do
|
69
|
+
DateTime.expects(:parse).with('2009-04-28T18:48:52Z').returns('update_date')
|
70
|
+
|
71
|
+
@ticket.stubs(:updated_timestamp).with().returns('2009-04-28T18:48:52Z')
|
72
|
+
@ticket.updated_at.should == 'update_date'
|
73
|
+
end
|
74
|
+
|
75
|
+
should "have a due date" do
|
76
|
+
Date.expects(:parse).with('2008-07-30').returns('due_date')
|
77
|
+
|
78
|
+
@ticket.stubs(:due_datestamp).with().returns('2008-07-30')
|
79
|
+
@ticket.due_on.should == 'due_date'
|
80
|
+
end
|
81
|
+
|
82
|
+
should "not have a due date if there isn't one associated" do
|
83
|
+
@ticket.stubs(:due_datestamp).with().returns(nil)
|
84
|
+
@ticket.due_on.should be(nil)
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class UnfuzzleTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "The Unfuzzle module" do
|
6
|
+
|
7
|
+
should "be able to set the subdomain" do
|
8
|
+
Unfuzzle.subdomain = 'viget'
|
9
|
+
Unfuzzle.subdomain.should == 'viget'
|
10
|
+
end
|
11
|
+
|
12
|
+
should "be able to set the username" do
|
13
|
+
Unfuzzle.username = 'username'
|
14
|
+
Unfuzzle.username.should == 'username'
|
15
|
+
end
|
16
|
+
|
17
|
+
should "be able to set the password" do
|
18
|
+
Unfuzzle.password = 'password'
|
19
|
+
Unfuzzle.password.should == 'password'
|
20
|
+
end
|
21
|
+
|
22
|
+
should "be able to retrieve a project by id" do
|
23
|
+
Unfuzzle::Project.expects(:find_by_id).with(1).returns('project')
|
24
|
+
Unfuzzle.project(1).should == 'project'
|
25
|
+
end
|
26
|
+
|
27
|
+
should "be able to retrieve a project by slug" do
|
28
|
+
Unfuzzle::Project.expects(:find_by_slug).with('slug').returns('project')
|
29
|
+
Unfuzzle.project('slug').should == 'project'
|
30
|
+
end
|
31
|
+
|
32
|
+
should "be able to retrieve a list of all projects for the current user" do
|
33
|
+
Unfuzzle::Project.expects(:all).with().returns('projects')
|
34
|
+
Unfuzzle.projects.should == 'projects'
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vigetlabs-unfuzzle
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Patrick Reagan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-24 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: json
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.1.6
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: patrick.reagan@viget.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
files:
|
34
|
+
- README.rdoc
|
35
|
+
- Rakefile
|
36
|
+
- lib/unfuzzle
|
37
|
+
- lib/unfuzzle/milestone.rb
|
38
|
+
- lib/unfuzzle/model.rb
|
39
|
+
- lib/unfuzzle/project.rb
|
40
|
+
- lib/unfuzzle/request.rb
|
41
|
+
- lib/unfuzzle/response.rb
|
42
|
+
- lib/unfuzzle/ticket.rb
|
43
|
+
- lib/unfuzzle/version.rb
|
44
|
+
- lib/unfuzzle.rb
|
45
|
+
- test/fixtures
|
46
|
+
- test/fixtures/milestones.json
|
47
|
+
- test/fixtures/project.json
|
48
|
+
- test/fixtures/projects.json
|
49
|
+
- test/fixtures/tickets.json
|
50
|
+
- test/test_helper.rb
|
51
|
+
- test/unit
|
52
|
+
- test/unit/unfuzzle
|
53
|
+
- test/unit/unfuzzle/milestone_test.rb
|
54
|
+
- test/unit/unfuzzle/project_test.rb
|
55
|
+
- test/unit/unfuzzle/request_test.rb
|
56
|
+
- test/unit/unfuzzle/response_test.rb
|
57
|
+
- test/unit/unfuzzle/ticket_test.rb
|
58
|
+
- test/unit/unfuzzle_test.rb
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: http://www.viget.com/extend
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options:
|
63
|
+
- --main
|
64
|
+
- README.rdoc
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
version:
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: "0"
|
78
|
+
version:
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.2.0
|
83
|
+
signing_key:
|
84
|
+
specification_version: 2
|
85
|
+
summary: This gem provides an interface to the Unfuddle JSON API
|
86
|
+
test_files: []
|
87
|
+
|