togglv8 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c535170f2f4008596f53dd97645d5946d62740e
4
- data.tar.gz: f007be73994ef07272e1100e4f2046dc22d69e3a
3
+ metadata.gz: bcd7cc8508f9dd6457f7899cc9be1644e1453384
4
+ data.tar.gz: 9d7640b307c1d5fe4135c22dc368815ec60e595d
5
5
  SHA512:
6
- metadata.gz: 082469da76c56138a7bee169c205874a150384959b516b65633e4672288b0962fbfbccb1909ec2ad6a176bf076516d898b6a9fe3bc3bad52ac8048c2240a8d9a
7
- data.tar.gz: 64463ae5e379fee5e870be1c84e4a76d0b30138634f002371cd0fd08898cf6aa9bc0530287a540ffe1a4380dcc0c51214810c9acf614aa0802d1aa43f976cbbb
6
+ metadata.gz: d8b71a5a7d53c4ffac2a5a9d6621d313bafe4cafbcc45ec0142654b1d2f0c5e48004eaf9513e5278e357d21bef11fac86c6f75531d01061c3109b6cc1bb06314
7
+ data.tar.gz: 055a400ba85f3b4473f7a47f9a09daa0131f672a433bd109b8c28dc223dd51b1b5e253aee561a8d83b019268111cdb848297bcca15c4f6dbe03642f27bc77883
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  # Toggl API v8
3
3
 
4
- [![Build Status](https://api.travis-ci.org/kanet77/togglv8.svg "Build Status")](https://travis-ci.org/kanet77/togglv8) [![Coverage Status](https://coveralls.io/repos/kanet77/togglv8/badge.svg?branch=master&service=github)](https://coveralls.io/github/kanet77/togglv8?branch=master)
4
+ [![Gem Version](https://badge.fury.io/rb/togglv8.svg)](https://badge.fury.io/rb/togglv8) [![Build Status](https://api.travis-ci.org/kanet77/togglv8.svg "Build Status")](https://travis-ci.org/kanet77/togglv8) [![Coverage Status](https://coveralls.io/repos/kanet77/togglv8/badge.svg?branch=master&service=github)](https://coveralls.io/github/kanet77/togglv8?branch=master)
5
5
 
6
6
  [Toggl](http://www.toggl.com) is a time tracking tool.
7
7
 
@@ -38,7 +38,7 @@ TogglV8::API communicates with [Toggl API v8](https://github.com/toggl/toggl_api
38
38
  ```ruby
39
39
  TogglV8::API.new # reads API token from file ~/.toggl
40
40
  TogglV8::API.new(api_token) # explicit API token
41
- TogglV8::API.new(username, password) # username & password
41
+ TogglV8::API.new(email, password) # email & password
42
42
  ```
43
43
 
44
44
  ### TogglV8::ReportsV2
data/Rakefile CHANGED
@@ -1,8 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
- require 'fileutils'
2
+ require 'rake/clean'
3
3
 
4
- task :clean do
5
- FileUtils.remove_dir('coverage', force=true)
6
- FileUtils.remove_dir('doc', force=true)
7
- FileUtils.remove_dir('pkg', force=true)
8
- end
4
+ CLEAN.add 'coverage'
5
+ CLEAN.add 'doc'
6
+ CLEAN.include 'tmp-*'
@@ -1,3 +1,4 @@
1
+ # :nocov:
1
2
  require 'logger'
2
3
  require 'awesome_print' # for debug output
3
4
 
@@ -33,4 +34,5 @@ module Logging
33
34
  logger.level = Logger::WARN
34
35
  end
35
36
  end
36
- end
37
+ end
38
+ # :nocov:
@@ -13,18 +13,20 @@ module TogglV8
13
13
  def initialize(opts={})
14
14
  debug(false)
15
15
 
16
- @user_agent = 'togglv8'
16
+ @user_agent = TogglV8::NAME
17
17
 
18
18
  username = opts[:api_token]
19
19
  if username.nil?
20
20
  toggl_api_file = opts[:toggl_api_file] || File.join(Dir.home, TOGGL_FILE)
21
- if FileTest.exist?(toggl_api_file) then
21
+ if File.exist?(toggl_api_file) then
22
22
  username = IO.read(toggl_api_file)
23
23
  else
24
- raise "Expecting\n" +
24
+ raise "Expecting one of:\n" +
25
25
  " 1) api_token in file #{toggl_api_file}, or\n" +
26
- " 2) parameter: (api_token), or\n" +
27
- "\n\tSee https://github.com/toggl/toggl_api_docs/blob/master/reports.md#authentication"
26
+ " 2) parameter: (toggl_api_file), or\n" +
27
+ " 3) parameter: (api_token), or\n" +
28
+ "\n\tSee https://github.com/kanet77/togglv8#togglv8reportsv2" +
29
+ "\n\tand https://github.com/toggl/toggl_api_docs/blob/master/reports.md#authentication"
28
30
  end
29
31
  end
30
32
 
@@ -33,7 +35,7 @@ module TogglV8
33
35
 
34
36
  ##
35
37
  # ---------
36
- # :section: Reports
38
+ # :section: Report
37
39
  #
38
40
  # The following parameters and filters can be used in all of the reports
39
41
  #
@@ -70,26 +72,30 @@ module TogglV8
70
72
  # NB! Maximum date span (until - since) is one year.
71
73
 
72
74
  # extension can be one of ['.pdf', '.csv', '.xls']. Possibly others?
73
- def report(type, extension, opts)
75
+ def report(type, extension, params)
74
76
  raise "workspace_id is required" if @workspace_id.nil?
75
77
  get "#{type}#{extension}", {
76
78
  'user_agent': @user_agent,
77
79
  'workspace_id': @workspace_id,
78
- }.merge(opts)
80
+ }.merge(params)
79
81
  end
80
82
 
81
- def weekly(extension='', opts={})
82
- report('weekly', extension, opts)
83
+ def weekly(extension='', params={})
84
+ report('weekly', extension, params)
83
85
  end
84
86
 
85
- def details(extension='', opts={})
86
- report('details', extension, opts)
87
+ def details(extension='', params={})
88
+ report('details', extension, params)
87
89
  end
88
90
 
89
- def summary(extension='', opts={})
90
- report('summary', extension, opts)
91
+ def summary(extension='', params={})
92
+ report('summary', extension, params)
91
93
  end
92
94
 
95
+ ##
96
+ # ---------
97
+ # :section: Write report to file
98
+ #
93
99
  def write_report(filename)
94
100
  extension = File.extname(filename)
95
101
  report = yield(extension)
@@ -98,24 +104,29 @@ module TogglV8
98
104
  end
99
105
  end
100
106
 
101
- def write_weekly(filename, opts={})
107
+ def write_weekly(filename, params={})
102
108
  write_report(filename) do |extension|
103
- weekly(extension, opts)
109
+ weekly(extension, params)
104
110
  end
105
111
  end
106
112
 
107
- def write_details(filename, opts={})
113
+ def write_details(filename, params={})
108
114
  write_report(filename) do |extension|
109
- details(extension, opts)
115
+ details(extension, params)
110
116
  end
111
117
  end
112
118
 
113
- def write_summary(filename, opts={})
119
+ def write_summary(filename, params={})
114
120
  write_report(filename) do |extension|
115
- summary(extension, opts)
121
+ summary(extension, params)
116
122
  end
117
123
  end
118
124
 
125
+
126
+ ##
127
+ # ---------
128
+ # :section: Miscellaneous information
129
+ #
119
130
  def revision
120
131
  get "revision"
121
132
  end
@@ -124,25 +135,43 @@ module TogglV8
124
135
  get "index"
125
136
  end
126
137
 
127
- def project(opts={})
138
+ def env
139
+ get "env"
140
+ end
141
+
142
+ ##
143
+ # ---------
144
+ # :section: Project Dashboard
145
+ #
146
+ # Project dashboard returns at-a-glance information for a single project.
147
+ # This feature is only available with Toggl pro.
148
+ #
149
+ # user_agent : email, or other way to contact client application developer
150
+ # (string, *required*)
151
+ # workspace_id : The workspace whose data you want to access
152
+ # (integer, *required*)
153
+ # project_id : The project whose data you want to access
154
+ # (integer, *required*)
155
+ # page : number of 'tasks_page' you want to fetch
156
+ # (integer, optional)
157
+ # order_field string : name/assignee/duration/billable_amount/estimated_seconds
158
+ # order_desc string : on/off, on for descending and off for ascending order
159
+ def project(project_id, params={})
128
160
  raise "workspace_id is required" if @workspace_id.nil?
129
161
  get "project", {
130
162
  'user_agent': @user_agent,
131
163
  'workspace_id': @workspace_id,
132
- }.merge(opts)
133
- end
134
-
135
- def env
136
- get "env"
164
+ 'project_id': project_id,
165
+ }.merge(params)
137
166
  end
138
167
 
168
+ ##
169
+ # ---------
170
+ # :section: Error (for testing)
171
+ #
172
+ # excludes endpoints 'error500' and 'division_by_zero_error'
139
173
  def error400
140
174
  get "error400"
141
175
  end
142
-
143
- def error500
144
- get "error500"
145
- end
146
-
147
176
  end
148
177
  end
@@ -7,3 +7,7 @@ require_relative 'reportsv2'
7
7
 
8
8
  # :mode => :compat will convert symbols to strings
9
9
  Oj.default_options = { :mode => :compat }
10
+
11
+ module TogglV8
12
+ NAME = "TogglV8 v#{TogglV8::VERSION}"
13
+ end
@@ -13,26 +13,7 @@ module TogglV8
13
13
  API_TOKEN = 'api_token'
14
14
  TOGGL_FILE = '.toggl'
15
15
 
16
- def self.qualify(username, password)
17
- if username.nil? && password == API_TOKEN
18
- toggl_api_file = File.join(Dir.home, TOGGL_FILE)
19
-
20
- # logger.debug("toggl_api_file = #{toggl_api_file}")
21
- if FileTest.exist?(toggl_api_file) then
22
- username = IO.read(toggl_api_file)
23
- else
24
- raise "Expecting\n" +
25
- " 1) api_token in file #{toggl_api_file}, or\n" +
26
- " 2) parameter: (api_token), or\n" +
27
- " 3) parameters: (username, password).\n" +
28
- "\n\tSee https://github.com/toggl/toggl_api_docs/blob/master/chapters/authentication.md"
29
- end
30
- end
31
- return username, password
32
- end
33
-
34
16
  def self.open(username=nil, password=API_TOKEN, url=nil, opts={})
35
- username, password = qualify(username, password)
36
17
  raise 'Missing URL' if url.nil?
37
18
 
38
19
  Faraday.new(:url => url, :ssl => {:verify => true}) do |faraday|
@@ -25,7 +25,7 @@ module TogglV8
25
25
  # at : timestamp that is sent in the response, indicates the time item was last updated
26
26
 
27
27
  def create_time_entry(params)
28
- params['created_with'] = 'TogglV8' unless params.has_key?('created_with')
28
+ params['created_with'] = TogglV8::NAME unless params.has_key?('created_with')
29
29
  requireParams(params, ['start', 'duration', 'created_with'])
30
30
  if !params.has_key?('wid') and !params.has_key?('pid') and !params.has_key?('tid') then
31
31
  raise ArgumentError, "one of params['wid'], params['pid'], params['tid'] is required"
@@ -34,7 +34,7 @@ module TogglV8
34
34
  end
35
35
 
36
36
  def start_time_entry(params)
37
- params['created_with'] = 'TogglV8' unless params.has_key?('created_with')
37
+ params['created_with'] = TogglV8::NAME unless params.has_key?('created_with')
38
38
  if !params.has_key?('wid') and !params.has_key?('pid') and !params.has_key?('tid') then
39
39
  raise ArgumentError, "one of params['wid'], params['pid'], params['tid'] is required"
40
40
  end
@@ -21,6 +21,21 @@ module TogglV8
21
21
 
22
22
  def initialize(username=nil, password=API_TOKEN, opts={})
23
23
  debug(false)
24
+ if username.nil? && password == API_TOKEN
25
+ toggl_api_file = File.join(Dir.home, TOGGL_FILE)
26
+ # logger.debug("toggl_api_file = #{toggl_api_file}")
27
+ if File.exist?(toggl_api_file) then
28
+ username = IO.read(toggl_api_file)
29
+ else
30
+ raise "Expecting one of:\n" +
31
+ " 1) api_token in file #{toggl_api_file}, or\n" +
32
+ " 2) parameter: (api_token), or\n" +
33
+ " 3) parameters: (username, password).\n" +
34
+ "\n\tSee https://github.com/kanet77/togglv8#togglv8api" +
35
+ "\n\tand https://github.com/toggl/toggl_api_docs/blob/master/chapters/authentication.md"
36
+ end
37
+ end
38
+
24
39
  @conn = TogglV8::Connection.open(username, password,
25
40
  TOGGL_API_V8_URL, opts)
26
41
  end
@@ -66,7 +66,7 @@ module TogglV8
66
66
  end
67
67
 
68
68
  def create_user(params)
69
- params['created_with'] = 'TogglV8' unless params.has_key?('created_with')
69
+ params['created_with'] = TogglV8::NAME unless params.has_key?('created_with')
70
70
  requireParams(params, ['email', 'password', 'timezone', 'created_with'])
71
71
  post "signups", { 'user' => params }
72
72
  end
@@ -1,4 +1,4 @@
1
1
  module TogglV8
2
2
  # :section:
3
- VERSION = "1.2.0"
3
+ VERSION = "1.2.1"
4
4
  end
@@ -15,20 +15,18 @@ describe 'ReportsV2' do
15
15
 
16
16
  context '.toggl file' do
17
17
  before :each do
18
- @home = File.join(Dir.pwd, "tmp")
19
- Dir.mkdir(@home)
20
-
18
+ @tmp_home = mktemp_dir
21
19
  @original_home = Dir.home
22
- ENV['HOME'] = @home
20
+ ENV['HOME'] = @tmp_home
23
21
  end
24
22
 
25
23
  after :each do
26
- FileUtils.rm_rf(@home)
24
+ FileUtils.rm_rf(@tmp_home)
27
25
  ENV['HOME'] = @original_home
28
26
  end
29
27
 
30
28
  it 'initializes with .toggl file' do
31
- toggl_file = File.join(@home, '.toggl')
29
+ toggl_file = File.join(@tmp_home, '.toggl')
32
30
  File.open(toggl_file, 'w') { |file| file.write(Testing::API_TOKEN) }
33
31
 
34
32
  reports = TogglV8::ReportsV2.new
@@ -38,10 +36,10 @@ describe 'ReportsV2' do
38
36
  end
39
37
 
40
38
  it 'initializes with custom toggl file' do
41
- toggl_file = File.join(@home, 'my_toggl')
39
+ toggl_file = File.join(@tmp_home, 'my_toggl')
42
40
  File.open(toggl_file, 'w') { |file| file.write(Testing::API_TOKEN) }
43
41
 
44
- reports = TogglV8::ReportsV2.new({toggl_api_file: toggl_file})
42
+ reports = TogglV8::ReportsV2.new(toggl_api_file: toggl_file)
45
43
  env = reports.env
46
44
  expect(env).to_not be nil
47
45
  expect(env['user']['api_token']).to eq Testing::API_TOKEN
@@ -58,7 +56,7 @@ describe 'ReportsV2' do
58
56
  @reports.workspace_id = @workspace_id
59
57
  end
60
58
 
61
- it 'surfaces a Warning HTTP header in case of error' do
59
+ it 'surfaces a Warning HTTP header in case of 400 error' do
62
60
  # https://github.com/toggl/toggl_api_docs/blob/master/reports.md#failed-requests
63
61
  expect { @reports.error400 }.to raise_error(RuntimeError,
64
62
  "This URL is intended only for testing")
@@ -78,81 +76,76 @@ describe 'ReportsV2' do
78
76
  end
79
77
  end
80
78
 
81
- context 'revision' do
82
- it 'has not changed' do
79
+ context 'miscellaneous' do
80
+ it 'env returns environment' do
83
81
  reports = TogglV8::ReportsV2.new(api_token: Testing::API_TOKEN)
84
82
  reports.workspace_id = @workspace_id
85
- expect(reports.revision).to eq("0.0.38\n-8a007ca")
83
+ env = reports.env
84
+ expect(env['workspace']).to_not be nil
85
+ expect(env['user']).to_not be nil
86
+ expect(env['user']['id']).to eq Testing::USER_ID
87
+ end
88
+
89
+ it 'index returns endpoints' do
90
+ reports = TogglV8::ReportsV2.new(api_token: Testing::API_TOKEN)
91
+ reports.workspace_id = @workspace_id
92
+ index = reports.index
93
+ expect(index['Welcome to reports api V2. VALID requests are:']).to_not be nil
94
+ end
95
+
96
+ it 'revision has not changed' do
97
+ reports = TogglV8::ReportsV2.new(api_token: Testing::API_TOKEN)
98
+ reports.workspace_id = @workspace_id
99
+ expect(reports.revision).to eq "0.0.38\n-8a007ca"
86
100
  end
87
101
  end
88
102
 
89
- context 'blank reports' do
103
+ context 'project', :pro_account do
90
104
  before :all do
91
105
  @toggl = TogglV8::API.new(Testing::API_TOKEN)
92
- @workspaces = @toggl.workspaces
93
- @workspace_id = @workspaces.first['id']
94
- @reports = TogglV8::ReportsV2.new(api_token: Testing::API_TOKEN)
95
- @reports.workspace_id = @workspace_id
106
+ @project_name = "Project #{Time.now.iso8601}"
107
+ @project = @toggl.create_project({
108
+ 'name' => @project_name,
109
+ 'wid' => @workspace_id
110
+ })
96
111
  end
97
112
 
98
- it 'summary' do
99
- expect(@reports.summary).to eq []
113
+ after :all do
114
+ @toggl.delete_project(@project['id'])
100
115
  end
101
116
 
102
- it 'weekly' do
103
- expect(@reports.weekly).to eq []
104
- end
117
+ it 'dashboard' do
118
+ reports = TogglV8::ReportsV2.new(api_token: Testing::API_TOKEN)
119
+ reports.workspace_id = @toggl.workspaces.first['id']
120
+ project_dashboard = reports.project(@project['id'])
105
121
 
106
- it 'details' do
107
- expect(@reports.details).to eq []
122
+ expect(project_dashboard['name']).to eq @project_name
108
123
  end
109
124
  end
110
125
 
111
- context 'reports' do
126
+ context 'blank reports' do
112
127
  before :all do
113
128
  @toggl = TogglV8::API.new(Testing::API_TOKEN)
114
129
  @workspaces = @toggl.workspaces
115
130
  @workspace_id = @workspaces.first['id']
116
- time_entry_info = {
117
- 'wid' => @workspace_id,
118
- 'start' => @toggl.iso8601(DateTime.now),
119
- 'duration' => 77
120
- }
121
-
122
- @time_entry = @toggl.create_time_entry(time_entry_info)
123
-
124
131
  @reports = TogglV8::ReportsV2.new(api_token: Testing::API_TOKEN)
125
132
  @reports.workspace_id = @workspace_id
126
133
  end
127
134
 
128
- after :all do
129
- @toggl.delete_time_entry(@time_entry['id'])
130
- end
131
-
132
135
  it 'summary' do
133
- summary = @reports.summary
134
- expect(summary.length).to eq 1
135
- expect(summary.first['time']).to eq 77000
136
- expect(summary.first['items'].length).to eq 1
137
- expect(summary.first['items'].first['time']).to eq 77000
136
+ expect(@reports.summary).to eq []
138
137
  end
139
138
 
140
139
  it 'weekly' do
141
- weekly = @reports.weekly
142
- expect(weekly.length).to eq 1
143
- expect(weekly.first['details'].first['title']['user']).to eq 'togglv8'
144
- expect(weekly.first['totals'][7]).to eq 77000
140
+ expect(@reports.weekly).to eq []
145
141
  end
146
142
 
147
143
  it 'details' do
148
- details = @reports.details
149
- expect(details.length).to eq 1
150
- expect(details.first['user']).to eq 'togglv8'
151
- expect(details.first['dur']).to eq 77000
144
+ expect(@reports.details).to eq []
152
145
  end
153
146
  end
154
147
 
155
- context 'CSV reports' do
148
+ context 'reports' do
156
149
  before :all do
157
150
  @toggl = TogglV8::API.new(Testing::API_TOKEN)
158
151
  @workspaces = @toggl.workspaces
@@ -167,32 +160,95 @@ describe 'ReportsV2' do
167
160
 
168
161
  @reports = TogglV8::ReportsV2.new(api_token: Testing::API_TOKEN)
169
162
  @reports.workspace_id = @workspace_id
163
+
164
+ @tmp_home = mktemp_dir
165
+ @original_home = Dir.home
166
+ ENV['HOME'] = @tmp_home
170
167
  end
171
168
 
172
169
  after :all do
173
170
  @toggl.delete_time_entry(@time_entry['id'])
174
- end
175
171
 
176
- it 'summary' do
177
- summary = @reports.summary
178
- expect(summary.length).to eq 1
179
- expect(summary.first['time']).to eq 77000
180
- expect(summary.first['items'].length).to eq 1
181
- expect(summary.first['items'].first['time']).to eq 77000
182
- end
183
-
184
- it 'weekly' do
185
- weekly = @reports.weekly
186
- expect(weekly.length).to eq 1
187
- expect(weekly.first['details'].first['title']['user']).to eq 'togglv8'
188
- expect(weekly.first['totals'][7]).to eq 77000
172
+ FileUtils.rm_rf(@tmp_home)
173
+ ENV['HOME'] = @original_home
189
174
  end
190
175
 
191
- it 'details' do
192
- details = @reports.details
193
- expect(details.length).to eq 1
194
- expect(details.first['user']).to eq 'togglv8'
195
- expect(details.first['dur']).to eq 77000
176
+ context 'JSON reports' do
177
+ it 'summary' do
178
+ summary = @reports.summary
179
+ expect(summary.length).to eq 1
180
+ expect(summary.first['time']).to eq 77000
181
+ expect(summary.first['items'].length).to eq 1
182
+ expect(summary.first['items'].first['time']).to eq 77000
183
+ end
184
+
185
+ it 'weekly' do
186
+ weekly = @reports.weekly
187
+ expect(weekly.length).to eq 1
188
+ expect(weekly.first['details'].first['title']['user']).to eq Testing::USERNAME
189
+ expect(weekly.first['totals'][7]).to eq 77000
190
+ end
191
+
192
+ it 'details' do
193
+ details = @reports.details
194
+ expect(details.length).to eq 1
195
+ expect(details.first['user']).to eq Testing::USERNAME
196
+ expect(details.first['dur']).to eq 77000
197
+ end
198
+ end
199
+
200
+ context 'CSV reports' do
201
+ it 'summary' do
202
+ filename = File.join(@tmp_home, 'summary.csv')
203
+ summary = @reports.write_summary(filename)
204
+ expect(file_contains(filename, /00:01:17/))
205
+ end
206
+
207
+ it 'weekly' do
208
+ filename = File.join(@tmp_home, 'weekly.csv')
209
+ weekly = @reports.write_weekly(filename)
210
+ expect(file_contains(filename, /00:01:17/))
211
+ end
212
+
213
+ it 'details' do
214
+ filename = File.join(@tmp_home, 'details.csv')
215
+ details = @reports.write_details(filename)
216
+ expect(file_contains(filename, /00:01:17/))
217
+ end
218
+ end
219
+
220
+ context 'PDF reports' do
221
+ it 'summary' do
222
+ filename = File.join(@tmp_home, 'summary.pdf')
223
+ summary = @reports.write_summary(filename)
224
+ expect(file_is_pdf(filename))
225
+ end
226
+
227
+ it 'weekly' do
228
+ filename = File.join(@tmp_home, 'weekly.pdf')
229
+ weekly = @reports.write_weekly(filename)
230
+ expect(file_is_pdf(filename))
231
+ end
232
+
233
+ it 'details' do
234
+ filename = File.join(@tmp_home, 'details.pdf')
235
+ details = @reports.write_details(filename)
236
+ expect(file_is_pdf(filename))
237
+ end
238
+ end
239
+
240
+ context 'XLS reports' do
241
+ it 'summary' do
242
+ filename = File.join(@tmp_home, 'summary.xls')
243
+ summary = @reports.write_summary(filename)
244
+ expect(file_is_xls(filename))
245
+ end
246
+
247
+ it 'details' do
248
+ filename = File.join(@tmp_home, 'details.xls')
249
+ details = @reports.write_details(filename)
250
+ expect(file_is_xls(filename))
251
+ end
196
252
  end
197
253
  end
198
254
  end
@@ -127,6 +127,7 @@ describe 'Clients' do
127
127
  expect(client).to include(new_values)
128
128
  end
129
129
 
130
+ # :nocov:
130
131
  # It appears hourly rate is no longer tied to a client despite the docs:
131
132
  # https://github.com/toggl/toggl_api_docs/blob/master/chapters/clients.md#clients
132
133
  xit 'updates Pro client data', :pro_account do
@@ -139,5 +140,6 @@ describe 'Clients' do
139
140
  client = @toggl.get_client(@client['id'])
140
141
  expect(client).to include(new_values)
141
142
  end
143
+ # :nocov:
142
144
  end
143
145
  end
@@ -46,6 +46,13 @@ describe 'Projects' do
46
46
  expect(project['auto_estimates']).to eq @project['auto_estimates']
47
47
  expect(project['at']).to_not be nil
48
48
  end
49
+
50
+ it 'gets project users' do
51
+ users = @toggl.get_project_users(@project['id'])
52
+ expect(users.length).to eq 1
53
+ expect(users.first['uid']).to eq Testing::USER_ID
54
+ expect(users.first['manager']).to eq true
55
+ end
49
56
  end
50
57
 
51
58
  context 'updated project' do
@@ -9,7 +9,7 @@ describe 'Users' do
9
9
  it 'returns /me' do
10
10
  expect(@user).to_not be_nil
11
11
  expect(@user['id']).to eq Testing::USER_ID
12
- # expect(@user['fullname']).to eq 'togglv8'
12
+ expect(@user['fullname']).to eq Testing::USERNAME
13
13
  # expect(@user['image_url']).to eq 'https://assets.toggl.com/avatars/a5d106126b6bed8df283e708af0828ee.png'
14
14
  # expect(@user['timezone']).to eq 'Etc/UTC'
15
15
  # expect(@user['workspaces'].length).to eq 1
@@ -0,0 +1,40 @@
1
+ describe 'Workspaces' do
2
+ before :all do
3
+ @toggl = TogglV8::API.new(Testing::API_TOKEN)
4
+ @user = @toggl.me(all=true)
5
+ @workspaces = @toggl.workspaces
6
+ @workspace_id = @workspaces.first['id']
7
+ @project = @toggl.create_project({ 'name' => 'project with a task', 'wid' => @workspace_id })
8
+ end
9
+
10
+ after :all do
11
+ @toggl.delete_project(@project['id'])
12
+ end
13
+
14
+ it 'shows users' do
15
+ users = @toggl.users(@workspace_id)
16
+ expect(users.length).to eq 1
17
+ expect(users.first['id']).to eq Testing::USER_ID
18
+ expect(users.first['email']).to eq Testing::EMAIL
19
+ expect(users.first['fullname']).to eq Testing::USERNAME
20
+ expect(users.first['default_wid']).to eq @workspace_id
21
+ end
22
+
23
+ context 'tasks', :pro_account do
24
+ before :each do
25
+ @task = @toggl.create_task('name' => 'workspace task', 'pid' => @project['id'])
26
+ end
27
+
28
+ after :each do
29
+ @toggl.delete_task(@task['id'])
30
+ end
31
+
32
+ it 'shows tasks' do
33
+ tasks = @toggl.tasks(@workspace_id)
34
+ expect(tasks.length).to eq 1
35
+ expect(tasks.first['name']).to eq 'workspace task'
36
+ expect(tasks.first['pid']).to eq @project['id']
37
+ expect(tasks.first['wid']).to eq @workspace_id
38
+ end
39
+ end
40
+ end
@@ -6,15 +6,15 @@ describe 'TogglV8' do
6
6
  me = toggl.me
7
7
  expect(me).to_not be nil
8
8
  expect(me['api_token']).to eq Testing::API_TOKEN
9
- expect(me['email']).to eq Testing::USERNAME
9
+ expect(me['email']).to eq Testing::EMAIL
10
10
  end
11
11
 
12
12
  it 'initializes with username and password' do
13
- toggl = TogglV8::API.new(Testing::USERNAME, Testing::PASSWORD)
13
+ toggl = TogglV8::API.new(Testing::EMAIL, Testing::PASSWORD)
14
14
  me = toggl.me
15
15
  expect(me).to_not be nil
16
16
  expect(me['api_token']).to eq Testing::API_TOKEN
17
- expect(me['email']).to eq Testing::USERNAME
17
+ expect(me['email']).to eq Testing::EMAIL
18
18
  end
19
19
 
20
20
  it 'does not initialize with bogus api_token' do
@@ -24,27 +24,25 @@ describe 'TogglV8' do
24
24
 
25
25
  context '.toggl file' do
26
26
  before :each do
27
- @home = File.join(Dir.pwd, "tmp")
28
- Dir.mkdir(@home)
29
-
27
+ @tmp_home = mktemp_dir
30
28
  @original_home = Dir.home
31
- ENV['HOME'] = @home
29
+ ENV['HOME'] = @tmp_home
32
30
  end
33
31
 
34
32
  after :each do
35
- FileUtils.rm_rf(@home)
33
+ FileUtils.rm_rf(@tmp_home)
36
34
  ENV['HOME'] = @original_home
37
35
  end
38
36
 
39
37
  it 'initializes with .toggl file' do
40
- toggl_file = File.join(@home, '.toggl')
38
+ toggl_file = File.join(@tmp_home, '.toggl')
41
39
  File.open(toggl_file, 'w') { |file| file.write(Testing::API_TOKEN) }
42
40
 
43
41
  toggl = TogglV8::API.new
44
42
  me = toggl.me
45
43
  expect(me).to_not be nil
46
44
  expect(me['api_token']).to eq Testing::API_TOKEN
47
- expect(me['email']).to eq Testing::USERNAME
45
+ expect(me['email']).to eq Testing::EMAIL
48
46
  end
49
47
 
50
48
  it 'raises error if .toggl file is missing' do
@@ -52,9 +52,34 @@ class MockResponse
52
52
  end
53
53
  end
54
54
 
55
+ def mktemp_dir
56
+ dir = File.join(Dir.pwd, "tmp-#{Time.now.to_f}")
57
+ Dir.mkdir(dir)
58
+ dir
59
+ end
60
+
61
+ def file_contains(filename, pattern, maxlen=1000)
62
+ expect(File.exist?(filename))
63
+ contents = File.new(filename).sysread(maxlen)
64
+ expect(contents).to match pattern
65
+ end
66
+
67
+ def file_is_pdf(filename)
68
+ expect(File.exist?(filename))
69
+ first_line = File.foreach(filename).first
70
+ expect(first_line).to eq "%PDF-1.3\n"
71
+ end
72
+
73
+ def file_is_xls(filename)
74
+ expect(File.exist?(filename))
75
+ header = File.new(filename).sysread(8)
76
+ expect(header).to eq ['D0CF11E0A1B11AE1'].pack("H*")
77
+ end
78
+
55
79
  class Testing
56
80
  API_TOKEN = ENV['API_TOKEN'] || '4880adbe1bee9a241fa08070d33bd49f'
57
- USERNAME = ENV['USERNAME'] || 'togglv8@mailinator.com'
81
+ EMAIL = ENV['EMAIL'] || 'togglv8@mailinator.com'
82
+ USERNAME = ENV['USERNAME'] || 'togglv8'
58
83
  PASSWORD = ENV['PASSWORD'] || 'togglv8'
59
84
  USER_ID = (ENV['USER_ID'] || 1820939).to_i
60
85
  end
@@ -1,3 +1,4 @@
1
+ # :nocov:
1
2
  require_relative '../lib/togglv8'
2
3
 
3
4
  class TogglV8SpecHelper
@@ -70,4 +71,5 @@ class TogglV8SpecHelper
70
71
  end
71
72
  end
72
73
  end
73
- end
74
+ end
75
+ # :nocov:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: togglv8
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Kane
@@ -204,6 +204,7 @@ files:
204
204
  - spec/lib/togglv8/tasks_spec.rb
205
205
  - spec/lib/togglv8/time_entries_spec.rb
206
206
  - spec/lib/togglv8/users_spec.rb
207
+ - spec/lib/togglv8/workspaces_spec.rb
207
208
  - spec/lib/togglv8_spec.rb
208
209
  - spec/spec_helper.rb
209
210
  - spec/togglv8_spec_helper.rb
@@ -242,6 +243,7 @@ test_files:
242
243
  - spec/lib/togglv8/tasks_spec.rb
243
244
  - spec/lib/togglv8/time_entries_spec.rb
244
245
  - spec/lib/togglv8/users_spec.rb
246
+ - spec/lib/togglv8/workspaces_spec.rb
245
247
  - spec/lib/togglv8_spec.rb
246
248
  - spec/spec_helper.rb
247
249
  - spec/togglv8_spec_helper.rb