playnicely 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.textile ADDED
@@ -0,0 +1,119 @@
1
+ h1. Ruby PlayNice.ly API Client
2
+
3
+ This is the official PlayNice.ly API Ruby client library.
4
+
5
+ For full details of the API see the "documentation":http://docs.playnice.ly/api/.
6
+
7
+ h2. Installation
8
+
9
+ Details of how to install the client
10
+
11
+ (Once I get around to publishing the gem!)
12
+
13
+ @sudo gem install playnicely@
14
+
15
+ h2. Getting started
16
+
17
+ Here is a short example script to walk you through the basics of using the client library:
18
+
19
+ <pre>
20
+ require 'playnicely'
21
+
22
+ client = PlayNicely::Client.new('username', 'password')
23
+
24
+ # Get some information about the current user
25
+ me = client.current_user
26
+ my_projects = client.user_projects(me.user_id)
27
+
28
+ puts "Logged in as #{me.username}"
29
+ puts "Your projects are:"
30
+ my_projects.each do |project|
31
+ puts "#{project.name} (ID: #{project.project_id})"
32
+ end
33
+
34
+ # Get the first of your projects so that we can show some items for it
35
+ project = my_projects[0]
36
+
37
+ puts "Items in project #{project.name}"
38
+
39
+ # list all items
40
+ client.project_items(project.project_id).each do |item|
41
+ puts item.subject
42
+ end
43
+
44
+ puts "\nAll done! Now you try"
45
+ </pre>
46
+
47
+ h2. Reference
48
+
49
+ You can instantiate the client as follows:
50
+
51
+ <pre>
52
+ client = PlayNicely::Client.new('username', 'password')
53
+ </pre>
54
+
55
+ Further "authentication information":http://docs.playnice.ly/api/authentication/ can be found in the main "API Documentation":http://docs.playnice.ly/api/.
56
+
57
+ A quick overview of the available commands:
58
+
59
+ h3. Projects
60
+
61
+ *To retrieve a single project ("API Reference":http://docs.playnice.ly/api/reference/project/#show):*
62
+
63
+ @client.project(project_id)@
64
+
65
+ This will return the compact version of a project.
66
+
67
+ @client.project(project_id, "full")@
68
+
69
+ Will return the full version of a project.
70
+
71
+ h3. Milestones
72
+
73
+ *To retrieve a single milestone ("API Reference":http://docs.playnice.ly/api/reference/milestone/#show):*
74
+
75
+ @client.milestone(project_id, milestone_id)@
76
+
77
+ h3. Items
78
+
79
+ *To retrieve a single item ("API Reference":http://docs.playnice.ly/api/reference/item/#show):*
80
+
81
+ @client.item(project_id,item_id)@
82
+
83
+
84
+ h3. Users
85
+
86
+ *To retrieve a single user ("API Reference":http://docs.playnice.ly/api/reference/user/#show):*
87
+
88
+ @client.user(user_id)@
89
+
90
+ _Examples:_
91
+
92
+ <pre>
93
+ user_compact = client.user(999) # the detail parameter defaults to '"compact"'
94
+ user_full = client.user(999, detail="full")
95
+ user_id = client.user(999, detail="id") # returns an integer
96
+ </pre>
97
+
98
+ *To retrieve a list of a user's projects ("API Reference":http://docs.playnice.ly/api/reference/user/#list-projects):*
99
+
100
+ @client.user_projects(user_id)@
101
+
102
+ _Examples:_
103
+
104
+ <pre>
105
+ # How to retrieve a list of projects in each of the available detail levels
106
+ projects_compact = client.user_projects(999) # the detail parameter defaults to '"compact"'
107
+ projects_full = client.user_projects(999, "full")
108
+ projects_id = client.user_projects(999, "id") # returns an integer
109
+ </pre>
110
+
111
+ *Important note:* Only projects to which the authenticated user is also a member will be returned. If you require a complete list of all projects for a user, then you must authenticate as that user.
112
+
113
+ h2. Contributing
114
+
115
+ Please feel free to fork this repository and make any changes you feel are necessary. We will be happy to accept pull requests that we feel will benefit other users of the client.
116
+
117
+ h2. Help
118
+
119
+ If you run into problems then you can get in touch with the author ("Rob":http://twitter.com/robbiehudson/) at "support@playnice.ly":mailto:support@playnice.ly.
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'shoulda/tasks'
6
+
7
+ require 'rake/testtask'
8
+ Rake::TestTask.new(:test) do |test|
9
+ test.ruby_opts = ["-rubygems"] if defined? Gem
10
+ test.libs << "lib" << "test"
11
+ test.pattern = "test/**/*_test.rb"
12
+ end
13
+
14
+ task :default => :test
@@ -0,0 +1,113 @@
1
+ module PlayNicely
2
+ class Client
3
+ include HTTParty
4
+ format :json
5
+ base_uri "https://api.playnice.ly/v1/"
6
+
7
+ def initialize(username, password)
8
+ @username = username
9
+ @password = password
10
+
11
+ # call HTTParty
12
+ self.class.basic_auth(@username, @password)
13
+ end
14
+
15
+ def project(project_id, detail='compact')
16
+ auth_get("/project/#{project_id}/show/", {:query => {:detail => detail}})
17
+ end
18
+
19
+ def user(user_id, detail='compact')
20
+ auth_get("/user/#{user_id}/show/", {:query => {:detail => detail}})
21
+ end
22
+
23
+ def current_user(detail='compact')
24
+ auth_get('/user/current/show/', {:query => {:detail => detail}})
25
+ end
26
+
27
+ def user_projects(user_id, detail='compact')
28
+ auth_get("/user/#{user_id}/project/list/", {:query => {:detail => detail}})
29
+ end
30
+
31
+ def current_user_projects(detail='compact')
32
+ auth_get("/user/current/project/list/", {:query => {:detail => detail}})
33
+ end
34
+
35
+ def milestone(project_id, milestone_id, detail='compact')
36
+ auth_get("/project/#{project_id}/milestone/#{milestone_id}/show/", {:query => {:detail => detail}})
37
+ end
38
+
39
+ def project_milestones(project_id, detail='compact')
40
+ auth_get("/project/#{project_id}/milestone/list/", {:query => {:detail => detail}})
41
+ end
42
+
43
+ def item(project_id, item_id, detail='compact')
44
+ auth_get("/project/#{project_id}/item/#{item_id}/show/", {:query => {:detail => detail}})
45
+ end
46
+
47
+ def project_items(project_id, detail='compact')
48
+ auth_get("/project/#{project_id}/item/list/", {:query => {:detail => detail}})
49
+ end
50
+
51
+ def create_item(project_id, data)
52
+ auth_post("/project/#{project_id}/item/create/", :body => data.to_json)
53
+ end
54
+
55
+ def update_item(project_id, item_id, data)
56
+ auth_post("/project/#{project_id}/item/#{item_id}/update/", :body => data.to_json)
57
+ end
58
+
59
+ private
60
+ def auth_get path, options = {}
61
+ get(path, options)
62
+ end
63
+
64
+ def auth_post path, options = {}
65
+ post(path, options)
66
+ end
67
+
68
+ def post path, options = {}
69
+ response = self.class.post(path, options)
70
+
71
+ if response.nil?
72
+ return
73
+ end
74
+
75
+ Hashie::Mash.new(response)
76
+ end
77
+
78
+ def get path, options = {}
79
+ response = self.class.get(path, options)
80
+
81
+ if response.nil?
82
+ return
83
+ end
84
+
85
+ # do some foo to check if we have an array of hashes or just a hash
86
+
87
+ if response.is_a? Array
88
+ response.collect! { |x| x.is_a?(Hash) ? Hashie::Mash.new(x) : x }
89
+ elsif response.is_a? Integer
90
+ Integer(response)
91
+ else
92
+ Hashie::Mash.new(response)
93
+ end
94
+ end
95
+
96
+ def self.get(*args); handle_response super end
97
+ def self.post(*args); handle_response super end
98
+
99
+ def self.handle_response(response)
100
+ case response.code
101
+ when 401; raise Unauthorized.new Hashie::Mash.new(response).error_message
102
+ when 403; raise RateLimitExceeded.new Hashie::Mash.new(response).error_message
103
+ when 404; raise NotFound.new Hashie::Mash.new(response).error_message
104
+ when 400...500; raise ClientError.new Hashie::Mash.new(response).error_message
105
+ when 500...600; raise ServerError.new(Hashie::Mash.new(response).error_message)
106
+ else; response
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+
113
+
@@ -0,0 +1,3 @@
1
+ module PlayNicely
2
+ VERSION = "0.1.1".freeze unless defined?(PlayNicely::VERSION)
3
+ end
data/lib/playnicely.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'forwardable'
2
+
3
+ require 'httparty'
4
+ require 'hashie'
5
+ require 'json'
6
+
7
+ libdir = File.dirname(__FILE__)
8
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
9
+
10
+ require 'playnicely/client'
11
+
12
+ module PlayNicely
13
+ extend SingleForwardable
14
+
15
+ def self.client; Client.new end
16
+
17
+ def_delegators :client, :project
18
+ class Error < StandardError; end
19
+ class Unauthorized < Error; end
20
+ class NotFound < Error; end
21
+ class ClientError < Error; end
22
+ class ServerError < Error; end
23
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/playnicely/version', __FILE__)
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'echoe'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.add_runtime_dependency('hashie', '~> 0.4.0')
9
+ s.add_runtime_dependency('httparty', '~> 0.6.1')
10
+ s.add_runtime_dependency('json')
11
+ s.add_development_dependency('fakeweb', '~> 1.3')
12
+ s.add_development_dependency('jnunemaker-matchy', '~> 0.4')
13
+ s.add_development_dependency('mocha', '~> 0.9')
14
+ s.add_development_dependency('shoulda', '~> 2.11')
15
+ s.name = 'playnicely'
16
+ s.authors = ["Rob Hudson"]
17
+ s.description = %q{Simple wrapper for the PlayNicely API v1}
18
+ s.email = ['rob@playnice.ly']
19
+ s.homepage = 'http://github.com/playnicelyapp/playnicely-rb'
20
+ s.files = `git ls-files`.split("\n")
21
+ s.require_paths = ['lib']
22
+ s.summary = %q{Wrapper for the PlayNicely API}
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
25
+ s.platform = Gem::Platform::RUBY
26
+ s.version = PlayNicely::VERSION.dup
27
+ s.has_rdoc = false
28
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
29
+ end
30
+
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class ClientTest < Test::Unit::TestCase
4
+ context "playnicely responds with an error" do
5
+ should "raise unauthorized exception" do
6
+ stub_get("https://robbiehudson:wrong-password@api.playnice.ly/v1/project/1/show/?detail=compact", "project-compact.json", ["401", "Unauthorized"])
7
+ lambda {PlayNicely::Client.new('robbiehudson', 'wrong-password').project(1)}.should raise_error(PlayNicely::Unauthorized)
8
+ end
9
+
10
+ should "raise server error" do
11
+ stub_get("https://robbiehudson:wrong-password@api.playnice.ly/v1/project/1/show/?detail=compact", "server-error.json", ["500", "Unauthorized"])
12
+ lambda {PlayNicely::Client.new('robbiehudson', 'wrong-password').project(1)}.should raise_error(PlayNicely::ServerError)
13
+
14
+ # now try again but wrap call and check exception content -- stupid shoulda!
15
+ begin
16
+ PlayNicely::Client.new('robbiehudson', 'wrong-password').project(1)
17
+ rescue PlayNicely::ServerError => e
18
+ e.message.should == "A description of the problem"
19
+ else
20
+ assert_true false
21
+ end
22
+ end
23
+
24
+ should "raise client error" do
25
+ stub_get("https://robbiehudson:wrong-password@api.playnice.ly/v1/project/1/show/?detail=compact", "server-error.json", ["405", "Unauthorized"])
26
+ lambda {PlayNicely::Client.new('robbiehudson', 'wrong-password').project(1)}.should raise_error(PlayNicely::ClientError)
27
+ end
28
+
29
+ should "raise not found error" do
30
+ stub_get("https://robbiehudson:wrong-password@api.playnice.ly/v1/project/1/show/?detail=compact", "server-error.json", ["404", "Unauthorized"])
31
+ lambda {PlayNicely::Client.new('robbiehudson', 'wrong-password').project(1)}.should raise_error(PlayNicely::NotFound)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ {
2
+ "body" : "We really need synchronous replication so that the widget can more effectively talk to the gizmo",
3
+ "item_id" : 2,
4
+ "milestone_id" : 1,
5
+ "project_id" : 1,
6
+ "status" : "closed",
7
+ "subject" : "Slave disconnects from proxied Master / keepalive",
8
+ "type_name" : "bug"
9
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "milestone_id":2,
3
+ "project_id":1,
4
+ "name":"Second milestone",
5
+ "item_ids":[ 6, 7, 8, 9, 10 ]
6
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "name":"Second milestone",
3
+ "item_ids":[ 6, 7, 8, 9, 10 ],
4
+ "created_at":"2010-12-14T16:36:27+00:00",
5
+ "updated_at":"2010-12-14T16:36:28+00:00",
6
+ "created_by":null,
7
+ "milestone_id":2,
8
+ "project_id":1,
9
+ "updated_by":null
10
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "project_id":1,
3
+ "name":"Alan Parsons Project",
4
+ "item_ids":[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
5
+ "user_ids":[ 1, 3 ],
6
+ "milestone_ids":[ 1, 2 ]
7
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "project_id":1,
3
+ "name":"Alan Parsons Project",
4
+ "item_ids":[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
5
+ "user_ids":[ 1, 3 ],
6
+ "milestone_ids":[ 1, 2 ],
7
+ "created_at":"2010-12-14T16:03:34+00:00",
8
+ "created_by":2,
9
+ "updated_at":"2010-12-14T16:03:35+00:00",
10
+ "updated_by":2
11
+ }
@@ -0,0 +1 @@
1
+ 1
@@ -0,0 +1,20 @@
1
+ [
2
+ {
3
+ "body":"Example item body",
4
+ "status":"closed",
5
+ "project_id":1,
6
+ "item_id":1,
7
+ "milestone_id":1,
8
+ "type_name":"bug",
9
+ "subject":"Request: synchronous replication"
10
+ },
11
+ {
12
+ "body":"Example item body",
13
+ "status":"closed",
14
+ "project_id":1,
15
+ "item_id":2,
16
+ "milestone_id":1,
17
+ "type_name":"bug",
18
+ "subject":"Slave disconnects from proxied Master / keepalive"
19
+ }
20
+ ]
@@ -0,0 +1 @@
1
+ [1,2]
@@ -0,0 +1,14 @@
1
+ [
2
+ {
3
+ "milestone_id":1,
4
+ "project_id":1,
5
+ "name":"First milestone",
6
+ "item_ids":[ 1, 2, 3, 4, 5 ]
7
+ },
8
+ {
9
+ "milestone_id":2,
10
+ "project_id":1,
11
+ "name":"Second milestone",
12
+ "item_ids":[ 6, 7, 8, 9, 10 ]
13
+ }
14
+ ]
@@ -0,0 +1,22 @@
1
+ [
2
+ {
3
+ "name":"First milestone",
4
+ "item_ids":[ 1, 2, 3, 4, 5 ],
5
+ "created_at":"2010-12-18T14:19:08+00:00",
6
+ "updated_at":"2010-12-18T14:19:10+00:00",
7
+ "created_by":2,
8
+ "milestone_id":1,
9
+ "project_id":1,
10
+ "updated_by":null
11
+ },
12
+ {
13
+ "name":"Second milestone",
14
+ "item_ids":[ 6, 7, 8, 9, 10 ],
15
+ "created_at":"2010-12-18T14:19:08+00:00",
16
+ "updated_at":"2010-12-18T14:19:10+00:00",
17
+ "created_by":null,
18
+ "milestone_id":2,
19
+ "project_id":1,
20
+ "updated_by":null
21
+ }
22
+ ]
@@ -0,0 +1 @@
1
+ [1, 2]
@@ -0,0 +1,4 @@
1
+ {
2
+ "error_message": "A description of the problem",
3
+ "type": "MessageTypeError"
4
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "user_id":1,
3
+ "username":"adamcharnock",
4
+ "first_name":"Adam",
5
+ "surname":"Charnock",
6
+ "image":"http://app.playnice.ly/user/1/image/"
7
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "user_id":1,
3
+ "username":"adamcharnock",
4
+ "first_name":"Adam",
5
+ "surname":"Charnock",
6
+ "image":"http://playnicely.owdev.co.uk:8000/user/1/image/",
7
+ "project_ids":[1, 2, 3, 4],
8
+ "updated_at":"2010-12-16T14:44:28+00:00",
9
+ "created_at":"2010-12-16T14:44:28+00:00"
10
+ }
@@ -0,0 +1,16 @@
1
+ [
2
+ {
3
+ "project_id":1,
4
+ "name":"Alan Parsons Project",
5
+ "item_ids":[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
6
+ "user_ids":[ 1, 3 ],
7
+ "milestone_ids":[ 1, 2 ]
8
+ },
9
+ {
10
+ "project_id":2,
11
+ "name":"The Bacon Street Project",
12
+ "item_ids":[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
13
+ "user_ids":[ 1, 4 ],
14
+ "milestone_ids":[ 1, 2 ]
15
+ }
16
+ ]
@@ -0,0 +1,24 @@
1
+ [
2
+ {
3
+ "name":"Alan Parsons Project",
4
+ "item_ids":[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
5
+ "created_at":"2010-12-18T15:45:55+00:00",
6
+ "updated_at":"2010-12-18T15:45:55+00:00",
7
+ "created_by":2,
8
+ "user_ids":[ 1, 3 ],
9
+ "project_id":1,
10
+ "milestone_ids":[ 1, 2 ],
11
+ "updated_by":null
12
+ },
13
+ {
14
+ "name":"The Bacon Street Project",
15
+ "item_ids":[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ],
16
+ "created_at":"2010-12-18T15:45:55+00:00",
17
+ "updated_at":"2010-12-18T15:45:55+00:00",
18
+ "created_by":2,
19
+ "user_ids":[ 1, 4 ],
20
+ "project_id":2,
21
+ "milestone_ids":[ 1, 2 ],
22
+ "updated_by":null
23
+ }
24
+ ]
@@ -0,0 +1 @@
1
+ [1, 2, 3, 4]
data/test/helper.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'test/unit'
2
+ require 'pathname'
3
+
4
+ require 'shoulda'
5
+ require 'matchy'
6
+ # require 'mocha'
7
+ require 'fakeweb'
8
+
9
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
10
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
11
+ require 'playnicely'
12
+
13
+ FakeWeb.allow_net_connect = false
14
+
15
+ class Test::Unit::TestCase
16
+ end
17
+
18
+ def fixture_file(filename)
19
+ return '' if filename == ''
20
+ file_path = File.expand_path(File.dirname(__FILE__) + '/fixtures/' + filename)
21
+ File.read(file_path)
22
+ end
23
+
24
+ def playnicely_url(url)
25
+ url =~ /^https/ ? url : "https://api.playnice.ly/v1/#{url}"
26
+ end
27
+
28
+ def stub_request(method, url, filename, status=nil)
29
+ options = {:body => ""}
30
+ options.merge!({:body => status.last}) if status
31
+ options.merge!({:body => fixture_file(filename)}) if filename
32
+ options.merge!({:status => status}) if status
33
+
34
+ FakeWeb.register_uri(method, playnicely_url(url), options)
35
+ end
36
+
37
+ def stub_get(*args); stub_request(:get, *args) end
38
+ def stub_post(*args); stub_request(:post, *args) end
data/test/item_test.rb ADDED
@@ -0,0 +1,83 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class ItemTest < Test::Unit::TestCase
4
+
5
+ context "when authenticated" do
6
+ setup do
7
+ @client = PlayNicely::Client.new('robbiehudson', 'number42')
8
+ end
9
+
10
+ should "show compact item information" do
11
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/item/2/show/?detail=compact", "item-compact.json")
12
+ item = @client.item(1,2)
13
+ item.body.should == "We really need synchronous replication so that the widget can more effectively talk to the gizmo"
14
+ item.item_id.should == 2
15
+ item.milestone_id.should == 1
16
+ item.project_id.should == 1
17
+ item.status.should == "closed"
18
+ item.subject.should == "Slave disconnects from proxied Master / keepalive"
19
+ item.type_name.should == "bug"
20
+ end
21
+
22
+ should "list compact item information for project" do
23
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/item/list/?detail=compact", "project-items-compact.json")
24
+ items = @client.project_items(1)
25
+ items.length.should == 2
26
+
27
+ item1 = items[0]
28
+ item1.body.should == "Example item body"
29
+ item1.status.should == "closed"
30
+ item1.project_id.should == 1
31
+ item1.item_id.should == 1
32
+ item1.milestone_id.should == 1
33
+ item1.type_name.should == "bug"
34
+ item1.subject.should == "Request: synchronous replication"
35
+
36
+ item2 = items[1]
37
+ item2.body.should == "Example item body"
38
+ item2.status.should == "closed"
39
+ item2.project_id.should == 1
40
+ item2.item_id.should == 2
41
+ item2.milestone_id.should == 1
42
+ item2.type_name.should == "bug"
43
+ item2.subject.should == "Slave disconnects from proxied Master / keepalive"
44
+ end
45
+
46
+ should "list item ids for project" do
47
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/item/list/?detail=id", "project-items-id.json")
48
+ items = @client.project_items(1, "id")
49
+ items.length.should == 2
50
+ items[0].should == 1
51
+ items[1].should == 2
52
+ end
53
+
54
+ should "create item in project" do
55
+ stub_post("https://robbiehudson:number42@api.playnice.ly/v1/project/1/item/create/", "item-compact.json")
56
+ item = @client.create_item(1, {:body => "We really need synchronous replication so that the widget can more effectively talk to the gizmo",
57
+ :item_id => 2,
58
+ :milestone_id => 1,
59
+ :project_id => 1,
60
+ :involved => [2],
61
+ :responsible => 2,
62
+ :status => "closed",
63
+ :subject => "Slave disconnects from proxied Master / keepalive",
64
+ :type_name => "bug"})
65
+
66
+ item.body.should == "We really need synchronous replication so that the widget can more effectively talk to the gizmo"
67
+ item.item_id.should == 2
68
+ item.milestone_id.should == 1
69
+ item.project_id.should == 1
70
+ item.status.should == "closed"
71
+ item.subject.should == "Slave disconnects from proxied Master / keepalive"
72
+ item.type_name.should == "bug"
73
+ end
74
+
75
+ should "update item in project" do
76
+ stub_post("https://robbiehudson:number42@api.playnice.ly/v1/project/1/item/2/update/", nil)
77
+ @client.update_item(1, 2, {:body => "We really need synchronous replication so that the widget can more effectively talk to the gizmo",
78
+ :status => "closed",
79
+ :subject => "Slave disconnects from proxied Master / keepalive",
80
+ :type_name => "bug"})
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,78 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class MilestoneTest < Test::Unit::TestCase
4
+
5
+ context "when authenticated" do
6
+ setup do
7
+ @client = PlayNicely::Client.new('robbiehudson', 'number42')
8
+ end
9
+
10
+ should "show compact milestone information" do
11
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/milestone/2/show/?detail=compact", "milestone-compact.json")
12
+ milestone = @client.milestone(1, 2)
13
+ milestone.milestone_id.should == 2
14
+ milestone.project_id.should == 1
15
+ milestone.name.should == "Second milestone"
16
+ milestone.item_ids.should == [ 6, 7, 8, 9, 10 ]
17
+ end
18
+
19
+ should "show full milestone information" do
20
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/milestone/2/show/?detail=full", "milestone-full.json")
21
+ milestone = @client.milestone(1, 2, 'full')
22
+ milestone.milestone_id.should == 2
23
+ milestone.project_id.should == 1
24
+ milestone.name.should == "Second milestone"
25
+ milestone.item_ids.should == [ 6, 7, 8, 9, 10 ]
26
+
27
+ milestone.created_at.should == Time.utc(2010,12,14,16,36,27)
28
+ milestone.updated_at.should == Time.utc(2010,12,14,16,36,28)
29
+ milestone.created_by.should == nil
30
+ milestone.updated_by.should == nil
31
+ end
32
+
33
+ should "show milestone ids for project" do
34
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/milestone/list/?detail=id", "project-milestones-id.json")
35
+ milestones = @client.project_milestones(1, 'id')
36
+ milestones.should == [1, 2]
37
+ end
38
+
39
+ should "show compact milestones for project" do
40
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/milestone/list/?detail=compact", "project-milestones-compact.json")
41
+ milestones = @client.project_milestones(1)
42
+ milestones.length.should == 2
43
+
44
+ milestone1 = milestones[0]
45
+ milestone1.milestone_id.should == 1
46
+ milestone1.project_id.should == 1
47
+ milestone1.name.should == "First milestone"
48
+ milestone1.item_ids.should == [ 1, 2, 3, 4, 5 ]
49
+
50
+ milestone2 = milestones[1]
51
+ milestone2.milestone_id.should == 2
52
+ milestone2.project_id.should == 1
53
+ milestone2.name.should == "Second milestone"
54
+ milestone2.item_ids.should == [ 6, 7, 8, 9, 10 ]
55
+ end
56
+
57
+ should "show full milestones for project" do
58
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/milestone/list/?detail=full", "project-milestones-full.json")
59
+ milestones = @client.project_milestones(1, 'full')
60
+ milestones.length.should == 2
61
+
62
+ milestone1 = milestones[0]
63
+ milestone1.created_at.should == Time.utc(2010,12,18, 14, 19, 8)
64
+ milestone1.updated_at.should == Time.utc(2010,12,18, 14, 19, 10)
65
+ milestone1.created_by.should == 2
66
+ milestone1.updated_by.should == nil
67
+
68
+ milestone2 = milestones[1]
69
+ milestone2.created_at.should == Time.utc(2010,12,18, 14, 19, 8)
70
+ milestone2.updated_at.should == Time.utc(2010,12,18, 14, 19, 10)
71
+ milestone2.created_by.should == nil
72
+ milestone2.updated_by.should == nil
73
+
74
+ end
75
+
76
+
77
+ end
78
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class ProjectTest < Test::Unit::TestCase
4
+
5
+ context "when authenticated" do
6
+ setup do
7
+ @client = PlayNicely::Client.new('robbiehudson', 'number42')
8
+ end
9
+
10
+ should "return compact project info" do
11
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/show/?detail=compact", "project-compact.json")
12
+ project = @client.project(1)
13
+ project.project_id.should == 1
14
+ project.item_ids.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
15
+ project.user_ids == [ 1, 3 ]
16
+ project.milestone_ids == [1,2]
17
+ project.name.should == "Alan Parsons Project"
18
+ end
19
+
20
+ should "return id for project" do
21
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/show/?detail=id", "project-id.json")
22
+ project = @client.project(1, "id")
23
+ project.should == 1
24
+ end
25
+
26
+ should "return full project info" do
27
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/project/1/show/?detail=full", "project-full.json")
28
+ project = @client.project(1,"full")
29
+ project.project_id.should == 1
30
+ project.created_at.should == Time.utc(2010, 12, 14, 16, 3, 34)
31
+ project.updated_at.should == Time.utc(2010, 12, 14, 16, 3, 35)
32
+ project.created_by.should == 2
33
+ project.updated_by.should == 2
34
+ end
35
+ end
36
+ end
data/test/user_test.rb ADDED
@@ -0,0 +1,102 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class UserTest < Test::Unit::TestCase
4
+
5
+ context "when authenticated" do
6
+ setup do
7
+ @client = PlayNicely::Client.new('robbiehudson', 'number42')
8
+ end
9
+
10
+ should "return compact user info" do
11
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/user/1/show/?detail=compact", "user-compact.json")
12
+ user = @client.user(1)
13
+ user.user_id.should == 1
14
+ user.username.should == 'adamcharnock'
15
+ user.first_name.should == 'Adam'
16
+ user.surname.should == 'Charnock'
17
+ user.image.should == 'http://app.playnice.ly/user/1/image/'
18
+ end
19
+
20
+ should "return full user info" do
21
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/user/1/show/?detail=compact", "user-full.json")
22
+ user = @client.user(1)
23
+ user.user_id.should == 1
24
+ user.created_at.should == Time.utc(2010, 12, 16, 14, 44, 28)
25
+ user.updated_at.should == Time.utc(2010, 12, 16, 14, 44, 28)
26
+ end
27
+
28
+ should "return compact current user info" do
29
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/user/current/show/?detail=compact", "user-compact.json")
30
+ user = @client.current_user()
31
+ user.user_id.should == 1
32
+ user.username.should == 'adamcharnock'
33
+ user.first_name.should == 'Adam'
34
+ user.surname.should == 'Charnock'
35
+ user.image.should == 'http://app.playnice.ly/user/1/image/'
36
+ end
37
+
38
+ should "return full current user info" do
39
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/user/current/show/?detail=full", "user-full.json")
40
+ user = @client.current_user("full")
41
+ user.user_id.should == 1
42
+ user.created_at.should == Time.utc(2010, 12, 16, 14, 44, 28)
43
+ user.updated_at.should == Time.utc(2010, 12, 16, 14, 44, 28)
44
+ end
45
+
46
+ should "return compact list of projects for user" do
47
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/user/1/project/list/?detail=compact", "user-projects-compact.json")
48
+ projects = @client.user_projects(1)
49
+
50
+ project1 = projects[0]
51
+ project1.project_id.should == 1
52
+ project1.name.should == "Alan Parsons Project"
53
+ project1.item_ids.should == [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
54
+ project1.user_ids.should == [ 1, 3 ]
55
+ project1.milestone_ids.should == [ 1, 2 ]
56
+
57
+ project2 = projects[1]
58
+ project2.project_id.should == 2
59
+ project2.name.should == "The Bacon Street Project"
60
+ project2.item_ids.should == [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
61
+ project2.user_ids.should == [ 1, 4 ]
62
+ project2.milestone_ids.should == [ 1, 2 ]
63
+
64
+ end
65
+
66
+ should "return full list of projects for user" do
67
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/user/1/project/list/?detail=full", "user-projects-full.json")
68
+ projects = @client.user_projects(1,'full')
69
+
70
+ project1 = projects[0]
71
+ project1.project_id.should == 1
72
+
73
+ project2 = projects[1]
74
+ project2.project_id.should == 2
75
+ end
76
+
77
+ should "return id list of projects for user" do
78
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/user/1/project/list/?detail=id", "user-projects-id.json")
79
+ projects = @client.user_projects(1, 'id')
80
+ projects.should == [1, 2, 3, 4]
81
+ end
82
+
83
+ should "return compact list of projects for current user" do
84
+ stub_get("https://robbiehudson:number42@api.playnice.ly/v1/user/current/project/list/?detail=compact", "user-projects-compact.json")
85
+ projects = @client.current_user_projects()
86
+
87
+ project1 = projects[0]
88
+ project1.project_id.should == 1
89
+ project1.name.should == "Alan Parsons Project"
90
+ project1.item_ids.should == [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
91
+ project1.user_ids.should == [ 1, 3 ]
92
+ project1.milestone_ids.should == [ 1, 2 ]
93
+
94
+ project2 = projects[1]
95
+ project2.project_id.should == 2
96
+ project2.name.should == "The Bacon Street Project"
97
+ project2.item_ids.should == [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
98
+ project2.user_ids.should == [ 1, 4 ]
99
+ project2.milestone_ids.should == [ 1, 2 ]
100
+ end
101
+ end
102
+ end
metadata ADDED
@@ -0,0 +1,204 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: playnicely
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Rob Hudson
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-19 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: hashie
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 15
30
+ segments:
31
+ - 0
32
+ - 4
33
+ - 0
34
+ version: 0.4.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: httparty
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 5
46
+ segments:
47
+ - 0
48
+ - 6
49
+ - 1
50
+ version: 0.6.1
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: json
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ type: :runtime
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: fakeweb
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ hash: 9
76
+ segments:
77
+ - 1
78
+ - 3
79
+ version: "1.3"
80
+ type: :development
81
+ version_requirements: *id004
82
+ - !ruby/object:Gem::Dependency
83
+ name: jnunemaker-matchy
84
+ prerelease: false
85
+ requirement: &id005 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ - 4
94
+ version: "0.4"
95
+ type: :development
96
+ version_requirements: *id005
97
+ - !ruby/object:Gem::Dependency
98
+ name: mocha
99
+ prerelease: false
100
+ requirement: &id006 !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ~>
104
+ - !ruby/object:Gem::Version
105
+ hash: 25
106
+ segments:
107
+ - 0
108
+ - 9
109
+ version: "0.9"
110
+ type: :development
111
+ version_requirements: *id006
112
+ - !ruby/object:Gem::Dependency
113
+ name: shoulda
114
+ prerelease: false
115
+ requirement: &id007 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ~>
119
+ - !ruby/object:Gem::Version
120
+ hash: 21
121
+ segments:
122
+ - 2
123
+ - 11
124
+ version: "2.11"
125
+ type: :development
126
+ version_requirements: *id007
127
+ description: Simple wrapper for the PlayNicely API v1
128
+ email:
129
+ - rob@playnice.ly
130
+ executables: []
131
+
132
+ extensions: []
133
+
134
+ extra_rdoc_files: []
135
+
136
+ files:
137
+ - Gemfile
138
+ - README.textile
139
+ - Rakefile
140
+ - lib/playnicely.rb
141
+ - lib/playnicely/client.rb
142
+ - lib/playnicely/version.rb
143
+ - playnicely.gemspec
144
+ - test/client_test.rb
145
+ - test/fixtures/item-compact.json
146
+ - test/fixtures/milestone-compact.json
147
+ - test/fixtures/milestone-full.json
148
+ - test/fixtures/project-compact.json
149
+ - test/fixtures/project-full.json
150
+ - test/fixtures/project-id.json
151
+ - test/fixtures/project-items-compact.json
152
+ - test/fixtures/project-items-id.json
153
+ - test/fixtures/project-milestones-compact.json
154
+ - test/fixtures/project-milestones-full.json
155
+ - test/fixtures/project-milestones-id.json
156
+ - test/fixtures/server-error.json
157
+ - test/fixtures/user-compact.json
158
+ - test/fixtures/user-full.json
159
+ - test/fixtures/user-projects-compact.json
160
+ - test/fixtures/user-projects-full.json
161
+ - test/fixtures/user-projects-id.json
162
+ - test/helper.rb
163
+ - test/item_test.rb
164
+ - test/milestone_test.rb
165
+ - test/project_test.rb
166
+ - test/user_test.rb
167
+ has_rdoc: true
168
+ homepage: http://github.com/playnicelyapp/playnicely-rb
169
+ licenses: []
170
+
171
+ post_install_message:
172
+ rdoc_options: []
173
+
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ hash: 3
182
+ segments:
183
+ - 0
184
+ version: "0"
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ none: false
187
+ requirements:
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ hash: 23
191
+ segments:
192
+ - 1
193
+ - 3
194
+ - 6
195
+ version: 1.3.6
196
+ requirements: []
197
+
198
+ rubyforge_project:
199
+ rubygems_version: 1.4.1
200
+ signing_key:
201
+ specification_version: 3
202
+ summary: Wrapper for the PlayNicely API
203
+ test_files: []
204
+