agilezen 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +60 -0
- data/LICENSE +20 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/agilezen.gemspec +29 -0
- data/lib/agilezen.rb +11 -0
- data/lib/agilezen/client.rb +55 -0
- data/lib/agilezen/projects.rb +29 -0
- data/lib/agilezen/stories.rb +36 -0
- data/lib/agilezen/version.rb +4 -0
- data/spec/client_spec.rb +86 -0
- data/spec/fixtures/garbage.txt +27 -0
- data/spec/fixtures/project.json +9 -0
- data/spec/fixtures/project/15404-with-enrichments.json +86 -0
- data/spec/fixtures/projects-with-filtering.json +18 -0
- data/spec/fixtures/projects.json +26 -0
- data/spec/fixtures/spots.json +557 -0
- data/spec/fixtures/stories-page1.json +71 -0
- data/spec/fixtures/stories-page2.json +71 -0
- data/spec/fixtures/stories.json +52 -0
- data/spec/fixtures/story.json +22 -0
- data/spec/fixtures/story/2-with-enrichments.json +40 -0
- data/spec/fixtures/story/2-with-filtering.json +35 -0
- data/spec/projects_spec.rb +66 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/stories_spec.rb +84 -0
- data/spec/support/fakeweb_helper.rb +11 -0
- data/spec/support/matchers.rb +13 -0
- metadata +245 -0
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
agilezen (0.1.0)
|
5
|
+
faraday (~> 0.5.4)
|
6
|
+
faraday_middleware (~> 0.3.0)
|
7
|
+
hashie (~> 0.4.0)
|
8
|
+
multi_json (~> 0.0.5)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
addressable (2.2.2)
|
14
|
+
builder (2.1.2)
|
15
|
+
cucumber (0.10.0)
|
16
|
+
builder (>= 2.1.2)
|
17
|
+
diff-lcs (~> 1.1.2)
|
18
|
+
gherkin (~> 2.3.2)
|
19
|
+
json (~> 1.4.6)
|
20
|
+
term-ansicolor (~> 1.0.5)
|
21
|
+
diff-lcs (1.1.2)
|
22
|
+
fakeweb (1.3.0)
|
23
|
+
faraday (0.5.4)
|
24
|
+
addressable (~> 2.2.2)
|
25
|
+
multipart-post (~> 1.1.0)
|
26
|
+
rack (>= 1.1.0, < 2)
|
27
|
+
faraday_middleware (0.3.1)
|
28
|
+
faraday (~> 0.5.3)
|
29
|
+
gherkin (2.3.3)
|
30
|
+
json (~> 1.4.6)
|
31
|
+
hashie (0.4.0)
|
32
|
+
json (1.4.6)
|
33
|
+
multi_json (0.0.5)
|
34
|
+
multipart-post (1.1.0)
|
35
|
+
rack (1.2.1)
|
36
|
+
rake (0.8.7)
|
37
|
+
rspec (2.4.0)
|
38
|
+
rspec-core (~> 2.4.0)
|
39
|
+
rspec-expectations (~> 2.4.0)
|
40
|
+
rspec-mocks (~> 2.4.0)
|
41
|
+
rspec-core (2.4.0)
|
42
|
+
rspec-expectations (2.4.0)
|
43
|
+
diff-lcs (~> 1.1.2)
|
44
|
+
rspec-mocks (2.4.0)
|
45
|
+
term-ansicolor (1.0.5)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
agilezen!
|
52
|
+
bundler (~> 1.0)
|
53
|
+
cucumber (~> 0.10.0)
|
54
|
+
fakeweb (~> 1.3.0)
|
55
|
+
faraday (~> 0.5.4)
|
56
|
+
faraday_middleware (~> 0.3.0)
|
57
|
+
hashie (~> 0.4.0)
|
58
|
+
multi_json (~> 0.0.5)
|
59
|
+
rake (~> 0.8)
|
60
|
+
rspec (~> 2.4)
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Adam McDonald
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# AgileZen - A Ruby wrapper for the AgileZen API (v1.0)
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
gem install agilezen
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
When setting up the client, just specify your api key. Methods that are designed to take options in the API are designed that way in the wrapper also, as you'd expect. For more details, read the AgileZen API [documentation](https://agilezen.tenderapp.com/kb/api/overview).
|
10
|
+
|
11
|
+
require 'agilezen'
|
12
|
+
|
13
|
+
# Setup the client
|
14
|
+
client = AgileZen::Client.new(:api_key => 'yourapikey')
|
15
|
+
|
16
|
+
# Returns info for all your projects
|
17
|
+
projects = @client.projects
|
18
|
+
|
19
|
+
# Returns info for the specified project
|
20
|
+
project = @client.project(123)
|
21
|
+
|
22
|
+
# Returns info for all stories for the specified project
|
23
|
+
stories = @client.projects_stories(123)
|
24
|
+
|
25
|
+
# Returns info for a specific story within a project
|
26
|
+
story = @client.project_story(123, 5)
|
27
|
+
|
28
|
+
# Collection resources support pagination
|
29
|
+
stories = @client.projects_stories(123, :page => 2, :pageSize => 50)
|
30
|
+
|
31
|
+
# Enrichments are supported for additional details
|
32
|
+
stories = @client.projects_stories(123, :with => 'details,tags')
|
33
|
+
|
34
|
+
# Filters are supported to limit your queries
|
35
|
+
stories = @client.projects_stories(123, :where => 'tag:authentication')
|
36
|
+
|
37
|
+
## Documentation
|
38
|
+
|
39
|
+
For additional details, checkout the latest generated [documentation](http://raid5.github.com/agilezen).
|
data/Rakefile
ADDED
data/agilezen.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path("../lib/agilezen/version", __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'agilezen'
|
5
|
+
s.version = AgileZen::VERSION
|
6
|
+
s.authors = ['Adam McDonald']
|
7
|
+
s.email = ['mcdonald.adam@gmail.com']
|
8
|
+
s.homepage = 'http://github.com/raid5/agilezen'
|
9
|
+
s.summary = 'Ruby wrapper for the AgileZen API'
|
10
|
+
s.description = s.summary
|
11
|
+
|
12
|
+
s.add_development_dependency 'bundler', '~> 1.0'
|
13
|
+
s.add_development_dependency 'rake', '~> 0.8'
|
14
|
+
s.add_development_dependency 'rspec', '~> 2.4'
|
15
|
+
s.add_development_dependency 'cucumber', '~> 0.10.0'
|
16
|
+
s.add_development_dependency 'fakeweb', '~> 1.3.0'
|
17
|
+
|
18
|
+
s.add_runtime_dependency 'faraday', '~> 0.5.4'
|
19
|
+
s.add_runtime_dependency 'faraday_middleware', '~> 0.3.0'
|
20
|
+
s.add_runtime_dependency 'multi_json', '~> 0.0.5'
|
21
|
+
s.add_runtime_dependency 'hashie', '~> 0.4.0'
|
22
|
+
|
23
|
+
s.required_rubygems_version = '>= 1.3.6'
|
24
|
+
s.platform = Gem::Platform::RUBY
|
25
|
+
s.rubyforge_project = "agilezen"
|
26
|
+
s.require_path = 'lib'
|
27
|
+
s.files = `git ls-files`.split("\n")
|
28
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
29
|
+
end
|
data/lib/agilezen.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module AgileZen
|
2
|
+
# AgileZen::Client class.
|
3
|
+
class Client
|
4
|
+
|
5
|
+
include Projects
|
6
|
+
include Stories
|
7
|
+
|
8
|
+
attr_accessor :api_key
|
9
|
+
attr_accessor :ssl
|
10
|
+
|
11
|
+
# Initializer for client.
|
12
|
+
def initialize(options ={})
|
13
|
+
@api_key = options[:api_key]
|
14
|
+
@ssl = options[:ssl]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Whether the client has the require auth to make API requests.
|
18
|
+
def has_required_authentication?
|
19
|
+
!@api_key.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
# Whether to use SSL or not.
|
23
|
+
def has_ssl?
|
24
|
+
@ssl
|
25
|
+
end
|
26
|
+
|
27
|
+
# Set the Faraday::Connection
|
28
|
+
def connection=(conn)
|
29
|
+
@connection = conn
|
30
|
+
end
|
31
|
+
|
32
|
+
# Builds and returns the Faraday::Connection based on set options.
|
33
|
+
def connection
|
34
|
+
@connection ||= Faraday::Connection.new(:url => connection_url, :headers => connection_headers) do |builder|
|
35
|
+
builder.adapter Faraday.default_adapter
|
36
|
+
#builder.use Faraday::Response::Yajl
|
37
|
+
builder.use Faraday::Response::ParseJson
|
38
|
+
builder.use Faraday::Response::Mashify
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Helper method for determining the correct URL.
|
43
|
+
def connection_url
|
44
|
+
has_ssl? ? 'https://agilezen.com' : 'http://agilezen.com'
|
45
|
+
end
|
46
|
+
|
47
|
+
# Helper method for defining globally required headers.
|
48
|
+
def connection_headers
|
49
|
+
headers = {
|
50
|
+
:accept => 'application/json',
|
51
|
+
'X-Zen-ApiKey' => @api_key
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module AgileZen
|
2
|
+
# AgileZen::Projects module.
|
3
|
+
module Projects
|
4
|
+
|
5
|
+
# Retrieve information for all projects.
|
6
|
+
def projects(options={})
|
7
|
+
response = connection.get do |req|
|
8
|
+
req.url "/api/v1/projects", options
|
9
|
+
end
|
10
|
+
response.body
|
11
|
+
end
|
12
|
+
|
13
|
+
# Retrieve information for an individual project.
|
14
|
+
def project(project_id, options={})
|
15
|
+
response_body = nil
|
16
|
+
begin
|
17
|
+
response = connection.get do |req|
|
18
|
+
req.url "/api/v1/project/#{project_id}", options
|
19
|
+
end
|
20
|
+
response_body = response.body
|
21
|
+
rescue MultiJson::DecodeError => e
|
22
|
+
#p 'Unable to parse JSON.'
|
23
|
+
end
|
24
|
+
|
25
|
+
response_body
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module AgileZen
|
2
|
+
# AgileZen::Stories module.
|
3
|
+
module Stories
|
4
|
+
|
5
|
+
# Retrieve information for all stories of a given project.
|
6
|
+
def project_stories(project_id, options={})
|
7
|
+
response_body = nil
|
8
|
+
begin
|
9
|
+
response = connection.get do |req|
|
10
|
+
req.url "/api/v1/project/#{project_id}/stories", options
|
11
|
+
end
|
12
|
+
response_body = response.body
|
13
|
+
rescue MultiJson::DecodeError => e
|
14
|
+
#p 'Unable to parse JSON.'
|
15
|
+
end
|
16
|
+
|
17
|
+
response_body
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieve information for an individual story of a given project.
|
21
|
+
def project_story(project_id, story_id, options={})
|
22
|
+
response_body = nil
|
23
|
+
begin
|
24
|
+
response = connection.get do |req|
|
25
|
+
req.url "/api/v1/project/#{project_id}/story/#{story_id}", options
|
26
|
+
end
|
27
|
+
response_body = response.body
|
28
|
+
rescue MultiJson::DecodeError => e
|
29
|
+
#p 'Unable to parse JSON.'
|
30
|
+
end
|
31
|
+
|
32
|
+
response_body
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe AgileZen::Client do
|
4
|
+
|
5
|
+
describe "#initialize" do
|
6
|
+
it "stores the api key" do
|
7
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
8
|
+
client.api_key.should_not be_nil
|
9
|
+
end
|
10
|
+
|
11
|
+
it "ensures the ssl flag is false if not supplied" do
|
12
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
13
|
+
client.ssl.should be_false
|
14
|
+
end
|
15
|
+
|
16
|
+
it "stores the ssl flag if supplied" do
|
17
|
+
client = AgileZen::Client.new(:api_key => 'testapikey', :ssl => true)
|
18
|
+
client.ssl.should be_true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#has_ssl?" do
|
23
|
+
it "checks that ssl is supported" do
|
24
|
+
client = AgileZen::Client.new(:api_key => 'testapikey', :ssl => true)
|
25
|
+
client.should have_ssl
|
26
|
+
end
|
27
|
+
|
28
|
+
it "checks that ssl isn't supported" do
|
29
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
30
|
+
client.should_not have_ssl
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#has_required_authentication?" do
|
35
|
+
it "checks that the api key exists" do
|
36
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
37
|
+
client.should have_required_authentication
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#connection" do
|
42
|
+
context "building the Faraday::Connection" do
|
43
|
+
it "instantiates a Faraday::Connection" do
|
44
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
45
|
+
client.connection.should be_a(Faraday::Connection)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "configures the url" do
|
49
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
50
|
+
client.connection.host.should_not be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it "configures any default headers" do
|
54
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
55
|
+
client.connection.headers.should_not be_empty
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#connection_url" do
|
61
|
+
it "doesn't use ssl" do
|
62
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
63
|
+
client.connection_url.should eq('http://agilezen.com')
|
64
|
+
end
|
65
|
+
|
66
|
+
it "uses ssl" do
|
67
|
+
client = AgileZen::Client.new(:api_key => 'testapikey', :ssl => true)
|
68
|
+
client.connection_url.should eq('https://agilezen.com')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#connection_headers" do
|
73
|
+
it "sets the Accept header to JSON" do
|
74
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
75
|
+
client.connection_headers.should have_key(:accept)
|
76
|
+
client.connection_headers.should have_value('application/json')
|
77
|
+
end
|
78
|
+
|
79
|
+
it "sets the X-Zen-ApiKey header" do
|
80
|
+
client = AgileZen::Client.new(:api_key => 'testapikey')
|
81
|
+
client.connection_headers.should have_key('X-Zen-ApiKey')
|
82
|
+
client.connection_headers.should have_value(client.api_key)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<head>
|
3
|
+
<meta charset="utf-8">
|
4
|
+
|
5
|
+
<title></title>
|
6
|
+
<meta name="description" content="">
|
7
|
+
<meta name="author" content="">
|
8
|
+
|
9
|
+
</head>
|
10
|
+
|
11
|
+
<body lang="en">
|
12
|
+
|
13
|
+
<div id="container">
|
14
|
+
<header>
|
15
|
+
|
16
|
+
</header>
|
17
|
+
|
18
|
+
<div id="main" role="main">
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<footer>
|
22
|
+
|
23
|
+
</footer>
|
24
|
+
</div>
|
25
|
+
|
26
|
+
</body>
|
27
|
+
</html>
|
@@ -0,0 +1,86 @@
|
|
1
|
+
{
|
2
|
+
"id": 15404,
|
3
|
+
"name": "Difference",
|
4
|
+
"description": "This is the project that makes a difference.",
|
5
|
+
"details": "Scope\n====\nThe scope of the project will include: 1, 2, 3, and 4. Yep, that is about it for now.",
|
6
|
+
"createTime": "/Date(1289217113000-0600)/",
|
7
|
+
"owner": {
|
8
|
+
"id": 19059,
|
9
|
+
"name": "Adam"
|
10
|
+
},
|
11
|
+
"members": [
|
12
|
+
{
|
13
|
+
"id": 19059,
|
14
|
+
"name": "Adam"
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"invites": [
|
18
|
+
|
19
|
+
],
|
20
|
+
"roles": [
|
21
|
+
{
|
22
|
+
"id": 32829,
|
23
|
+
"name": "Administrators",
|
24
|
+
"members": [
|
25
|
+
{
|
26
|
+
"id": 19059,
|
27
|
+
"name": "Adam"
|
28
|
+
}
|
29
|
+
]
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"id": 32830,
|
33
|
+
"name": "Members",
|
34
|
+
"members": [
|
35
|
+
|
36
|
+
]
|
37
|
+
}
|
38
|
+
],
|
39
|
+
"phases": [
|
40
|
+
{
|
41
|
+
"id": 87565,
|
42
|
+
"name": "Backlog",
|
43
|
+
"description": "Stories that will be worked on someday",
|
44
|
+
"index": 0
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"id": 87566,
|
48
|
+
"name": "Ready",
|
49
|
+
"description": "Stories that are ready to be worked on",
|
50
|
+
"index": 1
|
51
|
+
},
|
52
|
+
{
|
53
|
+
"id": 87567,
|
54
|
+
"name": "Development",
|
55
|
+
"description": "Stories that are currently being developed",
|
56
|
+
"index": 2
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"id": 87570,
|
60
|
+
"name": "Design",
|
61
|
+
"description": "Stories that are currently being designed",
|
62
|
+
"index": 3
|
63
|
+
},
|
64
|
+
{
|
65
|
+
"id": 87568,
|
66
|
+
"name": "Complete",
|
67
|
+
"description": "Stories that have been completed",
|
68
|
+
"index": 4
|
69
|
+
},
|
70
|
+
{
|
71
|
+
"id": 87569,
|
72
|
+
"name": "Archive",
|
73
|
+
"description": "Stories that are history",
|
74
|
+
"index": 5
|
75
|
+
}
|
76
|
+
],
|
77
|
+
"metrics": {
|
78
|
+
"throughput": 0,
|
79
|
+
"leadTime": 0.0,
|
80
|
+
"cycleTime": 0.0,
|
81
|
+
"workTime": 0.0,
|
82
|
+
"waitTime": 0.0,
|
83
|
+
"blockedTime": 0.0,
|
84
|
+
"efficiency": 0.0
|
85
|
+
}
|
86
|
+
}
|