teamwork_api 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +11 -1
  4. data/.travis.yml +14 -1
  5. data/CHANGELOG.md +14 -0
  6. data/Gemfile +4 -2
  7. data/Gemfile.lock +65 -10
  8. data/Guardfile +12 -0
  9. data/README.md +5 -5
  10. data/Rakefile +2 -0
  11. data/lib/teamwork_api.rb +3 -0
  12. data/lib/teamwork_api/api/companies.rb +4 -0
  13. data/lib/teamwork_api/api/params.rb +18 -11
  14. data/lib/teamwork_api/api/people.rb +52 -29
  15. data/lib/teamwork_api/api/project_owner.rb +6 -1
  16. data/lib/teamwork_api/api/projects.rb +70 -47
  17. data/lib/teamwork_api/api/task_lists.rb +8 -4
  18. data/lib/teamwork_api/client.rb +24 -20
  19. data/lib/teamwork_api/error.rb +7 -1
  20. data/lib/teamwork_api/version.rb +3 -1
  21. data/spec/fixtures/companies.json +64 -0
  22. data/spec/fixtures/company.json +32 -0
  23. data/spec/fixtures/create_project.json +4 -0
  24. data/spec/fixtures/create_task_list.json +4 -0
  25. data/spec/fixtures/delete.json +3 -0
  26. data/spec/fixtures/people.json +80 -0
  27. data/spec/fixtures/person.json +77 -0
  28. data/spec/fixtures/project.json +68 -0
  29. data/spec/fixtures/project_owner.json +91 -0
  30. data/spec/fixtures/projects.json +135 -0
  31. data/spec/fixtures/task_list.json +18 -0
  32. data/spec/fixtures/task_lists.json +22 -0
  33. data/spec/fixtures/update.json +3 -0
  34. data/spec/spec_helper.rb +60 -7
  35. data/spec/teamwork_api/api/companies_spec.rb +69 -0
  36. data/spec/teamwork_api/api/people_spec.rb +78 -0
  37. data/spec/teamwork_api/api/project_owner_spec.rb +35 -0
  38. data/spec/teamwork_api/api/projects_spec.rb +117 -0
  39. data/spec/teamwork_api/api/task_lists_spec.rb +98 -0
  40. data/spec/teamwork_api/client_spec.rb +202 -0
  41. data/teamwork_api.gemspec +10 -2
  42. metadata +116 -8
  43. data/spec/teamwork_api_spec.rb +0 -9
@@ -1,71 +1,94 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TeamworkApi
2
4
  module API
5
+ # Client methods for Projects
6
+ # https://developer.teamwork.com/projects/projects
3
7
  module Projects
8
+ OPTIONAL_GET_ATTRIBUTES = [
9
+ :status,
10
+ :updated_after_date,
11
+ :order_by,
12
+ :created_after_date,
13
+ :created_after_time,
14
+ :cat_id,
15
+ :include_people,
16
+ :include_project_owner,
17
+ :page,
18
+ :page_size,
19
+ :order_mode,
20
+ :only_starred_projects,
21
+ :company_id,
22
+ :project_owner_ids,
23
+ :search_term,
24
+ :get_deleted,
25
+ :include_tags,
26
+ :user_id,
27
+ :updated_after_date_time
28
+ ].freeze
29
+ OPTIONAL_CREATE_ATTRIBUTES = [
30
+ :description,
31
+ :start_date,
32
+ :end_date,
33
+ :company_id,
34
+ :new_company,
35
+ :'harvest-timers-enabled',
36
+ :tags,
37
+ :reply_by_email_enabled,
38
+ :privacy_enabled
39
+ ].freeze
40
+ OPTIONAL_UPDATE_ATTRIBUTES = [
41
+ :name,
42
+ :description,
43
+ :start_date,
44
+ :end_date,
45
+ :company_id,
46
+ :new_company,
47
+ :status,
48
+ :'category-id',
49
+ :'harvest-timers-enabled',
50
+ :tags,
51
+ :reply_by_email_enabled,
52
+ :privacy_enabled,
53
+ :'use-tasks',
54
+ :'use-messages',
55
+ :'use-time',
56
+ :'use-risk-register',
57
+ :'use-billing',
58
+ :'use-milestones',
59
+ :'use-files',
60
+ :'use-notebook',
61
+ :'use-links',
62
+ :default_privacy
63
+ ].freeze
64
+
4
65
  def create_project(args)
5
66
  args =
6
67
  API.params(args)
7
68
  .required(:name)
8
69
  .default('category-id': '0')
9
- .optional(
10
- :description,
11
- :start_date,
12
- :end_date,
13
- :company_id,
14
- :new_company,
15
- :'harvest-timers-enabled',
16
- :tags,
17
- :reply_by_email_enabled,
18
- :privacy_enabled
19
- ).to_h
70
+ .optional(*OPTIONAL_CREATE_ATTRIBUTES)
71
+ .to_h
20
72
 
21
73
  response = post 'projects.json', project: args
22
- response['id']
74
+ response['id']&.to_i
23
75
  end
24
76
 
25
77
  def update_project(project_id, args)
26
- args =
27
- API.params(args)
28
- .optional(
29
- :name,
30
- :description,
31
- :start_date,
32
- :end_date,
33
- :company_id,
34
- :new_company,
35
- :status,
36
- :'category-id',
37
- :'harvest-timers-enabled',
38
- :tags,
39
- :reply_by_email_enabled,
40
- :privacy_enabled,
41
- :'use-tasks',
42
- :'use-messages',
43
- :'use-time',
44
- :'use-risk-register',
45
- :'use-billing',
46
- :'use-milestones',
47
- :'use-files',
48
- :'use-notebook',
49
- :'use-links',
50
- :default_privacy
51
- ).to_h
78
+ args = API.params(args).optional(*OPTIONAL_UPDATE_ATTRIBUTES).to_h
52
79
 
53
- response = put "projects/#{project_id}.json", project: args
54
- response['id']
80
+ put "projects/#{project_id}.json", project: args
55
81
  end
56
82
 
57
83
  def project(project_id, args = {})
58
- if args.present?
59
- args = { project: args }
60
- else
61
- args = {}
62
- end
84
+ args = { project: args } unless args.empty?
63
85
  response = get "/projects/#{project_id}.json", args
64
86
  response.body['project']
65
87
  end
66
88
 
67
- def projects
68
- response = get '/projects.json'
89
+ def projects(args = {})
90
+ args = API.params(args).optional(*OPTIONAL_GET_ATTRIBUTES).to_h
91
+ response = get '/projects.json', args
69
92
  response.body['projects']
70
93
  end
71
94
 
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TeamworkApi
2
4
  module API
5
+ # Client methods for TaskLists
6
+ # https://developer.teamwork.com/projects/task-lists
3
7
  module TaskLists
4
8
  def create_task_list(project_id, args)
5
9
  args =
@@ -17,15 +21,15 @@ module TeamworkApi
17
21
  ).to_h
18
22
 
19
23
  response = post "projects/#{project_id}/tasklists.json", tasklist: args
20
- response['TASKLISTID']
24
+ response['TASKLISTID']&.to_i
21
25
  end
22
26
 
23
- def update_task_list(task_list_id, args)
24
- end
27
+ # def update_task_list(task_list_id, args)
28
+ # end
25
29
 
26
30
  def task_list(task_list_id)
27
31
  response = get "/tasklists/#{task_list_id}.json"
28
- response.body['tasklist']
32
+ response.body['todo-list']
29
33
  end
30
34
 
31
35
  def task_lists
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
2
4
  require 'faraday_middleware'
3
5
  require 'json'
@@ -10,6 +12,7 @@ require 'teamwork_api/api/project_owner'
10
12
  require 'teamwork_api/api/task_lists'
11
13
 
12
14
  module TeamworkApi
15
+ # The main Teamwork client object
13
16
  class Client
14
17
  attr_accessor :api_key
15
18
  attr_reader :host
@@ -91,14 +94,10 @@ module TeamworkApi
91
94
  end
92
95
 
93
96
  def request(method, path, params = {})
94
- unless Hash === params
95
- params = params.to_h if params.respond_to? :to_h
96
- end
97
- path = @use_relative ? path.sub(/^\//, '') : path
98
-
99
97
  connection.headers[:cache_control] = 'no-cache'
100
98
  connection.basic_auth(api_key, '')
101
- response = connection.send(method.to_sym, path, params)
99
+ response =
100
+ connection.send(method.to_sym, request_path(path), params_hash(params))
102
101
  handle_error(response)
103
102
  response.env
104
103
  rescue Faraday::Error::ClientError, JSON::ParserError
@@ -106,31 +105,36 @@ module TeamworkApi
106
105
  end
107
106
 
108
107
  def handle_error(response)
108
+ body = response.env[:body]
109
+ env = response.env
110
+
109
111
  case response.status
110
112
  when 403
111
- raise TeamworkApi::UnauthenticatedError.new(
112
- response.env[:body],
113
- response.env
114
- )
113
+ raise TeamworkApi::UnauthenticatedError.new(body, env)
115
114
  when 404, 410
116
- raise TeamworkApi::NotFoundError.new(response.env[:body], response.env)
115
+ raise TeamworkApi::NotFoundError.new(body, env)
117
116
  when 422
118
- raise TeamworkApi::UnprocessableEntity.new(
119
- response.env[:body],
120
- response.env
121
- )
117
+ raise TeamworkApi::UnprocessableEntity.new(body, env)
122
118
  when 429
123
- raise TeamworkApi::TooManyRequests.new(
124
- response.env[:body],
125
- response.env
126
- )
119
+ raise TeamworkApi::TooManyRequests.new(body, env)
127
120
  when 500...600
128
- raise TeamworkApi::Error.new(response.env[:body])
121
+ raise TeamworkApi::Error, body
129
122
  end
130
123
  end
131
124
 
132
125
  def check_subdirectory(host)
133
126
  URI(host).request_uri != '/'
134
127
  end
128
+
129
+ def request_path(path)
130
+ @use_relative ? path.sub(%r{^\/}, '') : path
131
+ end
132
+
133
+ def params_hash(params)
134
+ unless params.is_a?(Hash)
135
+ params = params.to_h if params.respond_to? :to_h
136
+ end
137
+ params
138
+ end
135
139
  end
136
140
  end
@@ -1,4 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+
1
5
  module TeamworkApi
6
+ # baser error
2
7
  class TeamworkError < StandardError
3
8
  attr_reader :response
4
9
 
@@ -8,6 +13,7 @@ module TeamworkApi
8
13
  end
9
14
  end
10
15
 
16
+ # specific errors
11
17
  class Error < TeamworkError
12
18
  attr_reader :wrapped_exception
13
19
 
@@ -15,7 +21,7 @@ module TeamworkApi
15
21
  #
16
22
  # @param exception [Exception, String]
17
23
  # @return [TeamworkApi::Error]
18
- def initialize(exception = $!)
24
+ def initialize(exception = $ERROR_INFO)
19
25
  @wrapped_exception = exception
20
26
  if exception.respond_to?(:message)
21
27
  super(exception.message)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TeamworkApi
2
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
3
5
  end
@@ -0,0 +1,64 @@
1
+ {
2
+ "companies": [
3
+ {
4
+ "state": "California",
5
+ "email_one": "",
6
+ "email_three": "",
7
+ "contacts": "0",
8
+ "website": "https://www.company-one.com/",
9
+ "logo-URL": "https://s3.amazonaws.com/TWFiles/000/companyLogo/l.png",
10
+ "email_two": "",
11
+ "cid": "",
12
+ "phone": "",
13
+ "created-on": "",
14
+ "accounts": "15",
15
+ "company_name_url": "000-company-one",
16
+ "can_see_private": true,
17
+ "tags": [],
18
+ "zip": "90021",
19
+ "industryId": "",
20
+ "id": "000",
21
+ "last-changed-on": "2018-12-11T20:18:08Z",
22
+ "fax": "",
23
+ "address_two": "",
24
+ "name": "Company One",
25
+ "country": "United States",
26
+ "isowner": "1",
27
+ "industry": "",
28
+ "address_one": "1 First Avenue",
29
+ "countrycode": "US",
30
+ "collaborators": "2",
31
+ "city": "Los Angeles"
32
+ },
33
+ {
34
+ "state": "",
35
+ "email_one": "",
36
+ "email_three": "",
37
+ "contacts": "0",
38
+ "website": "",
39
+ "logo-URL": "",
40
+ "email_two": "",
41
+ "cid": "",
42
+ "phone": "",
43
+ "created-on": "2019-03-14T22:51:24Z",
44
+ "accounts": "0",
45
+ "company_name_url": "001-company-two",
46
+ "can_see_private": false,
47
+ "tags": [],
48
+ "zip": "",
49
+ "industryId": "",
50
+ "id": "001",
51
+ "last-changed-on": "2019-03-14T22:51:24Z",
52
+ "fax": "",
53
+ "address_two": "",
54
+ "name": "Company Two",
55
+ "country": "",
56
+ "isowner": "0",
57
+ "industry": "",
58
+ "address_one": "",
59
+ "countrycode": "",
60
+ "collaborators": "0",
61
+ "city": ""
62
+ }
63
+ ]
64
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "company": {
3
+ "state": "California",
4
+ "email_one": "",
5
+ "email_three": "",
6
+ "contacts": "0",
7
+ "website": "https://www.company-one.com/",
8
+ "logo-URL": "https://s3.amazonaws.com/TWFiles/999/companyLogo/l.png",
9
+ "email_two": "",
10
+ "cid": "",
11
+ "phone": "",
12
+ "created-on": "",
13
+ "accounts": "15",
14
+ "company_name_url": "000-company-one",
15
+ "can_see_private": true,
16
+ "tags": [],
17
+ "zip": "90021",
18
+ "industryId": "",
19
+ "id": "999",
20
+ "last-changed-on": "2018-12-11T20:18:08Z",
21
+ "fax": "",
22
+ "address_two": "",
23
+ "name": "Company One",
24
+ "country": "United States",
25
+ "isowner": "1",
26
+ "industry": "",
27
+ "address_one": "1 First Avenue",
28
+ "countrycode": "US",
29
+ "collaborators": "2",
30
+ "city": "Los Angeles"
31
+ }
32
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "id": "323605",
3
+ "STATUS": "OK"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "TASKLISTID": "1234",
3
+ "STATUS": "OK"
4
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "STATUS": "OK"
3
+ }
@@ -0,0 +1,80 @@
1
+ {
2
+ "STATUS": "OK",
3
+ "people": [
4
+ {
5
+ "permissions": {
6
+ "can-access-templates": false,
7
+ "can-add-projects": false,
8
+ "canManagePortfolio": false,
9
+ "can-manage-people": false,
10
+ "canAccessPortfolio": false
11
+ },
12
+ "avatar-url": "",
13
+ "last-changed-on": "2018-08-09T14:21:19Z",
14
+ "email-address": "",
15
+ "last-login": "",
16
+ "address-country": "",
17
+ "textFormat": "HTML",
18
+ "user-name": "",
19
+ "id": "",
20
+ "phone-number-fax": "",
21
+ "site-owner": false,
22
+ "address-city": "",
23
+ "company-name": "MCG Company",
24
+ "user-invited-date": "",
25
+ "user-type": "collaborator",
26
+ "phone-number-mobile": "",
27
+ "useShorthandDurations": false,
28
+ "address-zip": "",
29
+ "openId": "",
30
+ "address": {
31
+ "city": "",
32
+ "country": "",
33
+ "countrycode": "",
34
+ "zipcode": "",
35
+ "state": "",
36
+ "line1": "",
37
+ "line2": ""
38
+ },
39
+ "phone-number-office": "",
40
+ "im-handle": "",
41
+ "twoFactorAuthEnabled": false,
42
+ "tags": [],
43
+ "has-access-to-new-projects": false,
44
+ "last-active": "",
45
+ "im-service": "",
46
+ "deleted": false,
47
+ "notes": "",
48
+ "in-owner-company": true,
49
+ "user-invited-status": "PENDING",
50
+ "profile": "",
51
+ "userUUID": "",
52
+ "user-invited": "2",
53
+ "created-at": "2018-06-14T14:07:29Z",
54
+ "companyId": "",
55
+ "phone-number-home": "",
56
+ "profile-text": "",
57
+ "company-id": "",
58
+ "pid": "",
59
+ "phone-number-mobile-parts": {
60
+ "countryCode": "",
61
+ "prefix": "",
62
+ "phone": ""
63
+ },
64
+ "address-line-2": "",
65
+ "address-state": "",
66
+ "login-count": "0",
67
+ "address-line-1": "",
68
+ "administrator": false,
69
+ "email-alt-1": "",
70
+ "email-alt-2": "",
71
+ "email-alt-3": "",
72
+ "last-name": "User",
73
+ "title": "",
74
+ "first-name": "Demo 2",
75
+ "phone-number-office-ext": "",
76
+ "twitter": "",
77
+ "lengthOfDay": "8.0"
78
+ }
79
+ ]
80
+ }