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