freckle-api 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -0
- data/lib/freckle_api.rb +28 -14
- data/lib/freckle_api/coercions.rb +14 -12
- data/lib/freckle_api/group.rb +3 -1
- data/lib/freckle_api/import.rb +3 -1
- data/lib/freckle_api/invoice.rb +4 -2
- data/lib/freckle_api/model.rb +16 -6
- data/lib/freckle_api/project.rb +20 -14
- data/lib/freckle_api/timer.rb +42 -5
- data/lib/freckle_api/user.rb +3 -1
- data/lib/freckle_api/version.rb +1 -1
- data/spec/freckle_api/timer_spec.rb +60 -0
- data/spec/freckle_api_spec.rb +31 -22
- data/spec/spec_helper.rb +11 -4
- data/spec/support/api_helper.rb +44 -0
- data/spec/support/shared_contexts/api.rb +10 -0
- metadata +15 -25
- data/spec/support/fake_freckle.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98be6621cecd9046aa1ca6e7cadc2d18cb06d5d5
|
4
|
+
data.tar.gz: 4e4d3fd3851320e06c272ff0a2c55cb36edc6c8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa4806c1107bf017dcced798fcf4221e4b799dcb617028dba6dda176908978364fd0363b63e8f02423a2867c15d5d166ffadc1b6ac552a18972ddeb069521fea
|
7
|
+
data.tar.gz: 0e0849ca3bc1dbaafcd3c7df218fe014d15914ef7ca17d8537011580cd0777f28449f33023e21213a929692cfb36ccd568d75a9221d5c4a97ffd6217f958a731
|
data/README.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
# freckle-api
|
2
2
|
Freckle API client for v2.
|
3
3
|
|
4
|
+
[](https://badge.fury.io/rb/freckle-api)
|
5
|
+
[](https://gemnasium.com/shkm/freckle-api)
|
6
|
+
[](https://travis-ci.org/shkm/freckle-api)
|
7
|
+
[](https://codeclimate.com/github/shkm/freckle-api)
|
8
|
+
[](https://codeclimate.com/github/shkm/freckle-api/coverage)
|
9
|
+
|
4
10
|
This is still in development and not ready to use yet.
|
5
11
|
|
6
12
|
I intend to implement timing functonality only to begin with,
|
data/lib/freckle_api.rb
CHANGED
@@ -13,42 +13,56 @@ class FreckleApi
|
|
13
13
|
BASE_URI = URI('https://api.letsfreckle.com/v2').freeze
|
14
14
|
USER_AGENT = 'freckle-api' # TODO: make this flexible?
|
15
15
|
|
16
|
+
def self.uri(*path)
|
17
|
+
URI.parse [BASE_URI, *[path]].join('/')
|
18
|
+
end
|
19
|
+
|
16
20
|
def initialize(api_key)
|
17
21
|
@api_key = api_key
|
18
22
|
end
|
19
23
|
|
20
24
|
def project(id)
|
21
|
-
Project.new(request :get, uri('projects', id))
|
25
|
+
Project.new(request :get, self.class.uri('projects', id))
|
22
26
|
end
|
23
27
|
|
24
28
|
def projects
|
25
|
-
request
|
26
|
-
Project.new(project)
|
27
|
-
end
|
29
|
+
Project.list(request :get, self.class.uri('projects'))
|
28
30
|
end
|
29
31
|
|
32
|
+
# TODO: consider whether it's necessary to find a timer by ITS id,
|
33
|
+
# not that of the project.
|
30
34
|
def timer(project)
|
31
35
|
project_id = project.respond_to?(:id) ? project.id : project
|
32
36
|
|
33
|
-
Timer.new(request :get, uri('projects', project_id, 'timer'))
|
37
|
+
Timer.new(request :get, self.class.uri('projects', project_id, 'timer'))
|
34
38
|
end
|
35
39
|
|
36
|
-
|
40
|
+
def timers
|
41
|
+
Timer.list(request :get, self.class.uri('timers'))
|
42
|
+
end
|
37
43
|
|
38
|
-
def request(method, uri)
|
39
|
-
|
44
|
+
def request(method, uri, parse: true, params: {})
|
45
|
+
request = build_request(method, uri, params)
|
46
|
+
response = send_request(request, uri)
|
40
47
|
|
41
|
-
|
48
|
+
parse ? JSON.parse(response.body) : response
|
49
|
+
end
|
42
50
|
|
43
|
-
|
51
|
+
private
|
52
|
+
|
53
|
+
def build_request(method, uri, params: {})
|
54
|
+
http_class(method).new(uri.path, headers).tap do |request|
|
55
|
+
request.set_form_data(params)
|
56
|
+
end
|
44
57
|
end
|
45
58
|
|
46
|
-
def
|
47
|
-
|
59
|
+
def send_request(request, uri)
|
60
|
+
https = Net::HTTP.new(uri.host, uri.port).tap { |h| h.use_ssl = true }
|
61
|
+
https.request(request)
|
48
62
|
end
|
49
63
|
|
50
|
-
def
|
51
|
-
|
64
|
+
def http_class(method)
|
65
|
+
Object.const_get "Net::HTTP::#{method.to_s.capitalize}"
|
52
66
|
end
|
53
67
|
|
54
68
|
def headers
|
@@ -3,21 +3,23 @@
|
|
3
3
|
#
|
4
4
|
# E.g.:
|
5
5
|
# coerce_key, :the_key, name_of_method_that_returns_proc
|
6
|
-
|
7
|
-
module
|
8
|
-
def self.included(base)
|
9
|
-
base.extend(ClassMethods)
|
10
|
-
end
|
6
|
+
class FreckleApi
|
7
|
+
module Coercions
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
# TODO: beware nil values
|
15
|
-
def coerce_to_datetime
|
16
|
-
DateTime.method(:parse).to_proc
|
9
|
+
def self.included(base)
|
10
|
+
base.extend(ClassMethods)
|
17
11
|
end
|
18
12
|
|
19
|
-
|
20
|
-
|
13
|
+
module ClassMethods
|
14
|
+
# TODO: timezone based on local machine
|
15
|
+
# TODO: beware nil values
|
16
|
+
def coerce_to_datetime
|
17
|
+
DateTime.method(:parse).to_proc
|
18
|
+
end
|
19
|
+
|
20
|
+
def coerce_to_date
|
21
|
+
Date.method(:parse).to_proc
|
22
|
+
end
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
data/lib/freckle_api/group.rb
CHANGED
data/lib/freckle_api/import.rb
CHANGED
data/lib/freckle_api/invoice.rb
CHANGED
data/lib/freckle_api/model.rb
CHANGED
@@ -1,10 +1,20 @@
|
|
1
1
|
require 'hashie'
|
2
2
|
|
3
|
-
class FreckleApi
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
class FreckleApi
|
4
|
+
class Model < Hash
|
5
|
+
include Hashie::Extensions::Coercion
|
6
|
+
include Hashie::Extensions::MergeInitializer
|
7
|
+
include Hashie::Extensions::MethodAccess
|
8
|
+
include Hashie::Extensions::IndifferentAccess
|
8
9
|
|
9
|
-
|
10
|
+
include FreckleApi::Coercions
|
11
|
+
|
12
|
+
def self.list(*records)
|
13
|
+
[*records].map { |record| new(record) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def reload!(_api)
|
17
|
+
fail NotImplementedError
|
18
|
+
end
|
19
|
+
end
|
10
20
|
end
|
data/lib/freckle_api/project.rb
CHANGED
@@ -1,19 +1,25 @@
|
|
1
|
-
class FreckleApi
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
class FreckleApi
|
2
|
+
class Project < FreckleApi::Model
|
3
|
+
coerce_key :group, FreckleApi::Group
|
4
|
+
coerce_key :import, FreckleApi::Import
|
5
|
+
coerce_key :invoices, Array[FreckleApi::Invoice]
|
6
|
+
coerce_key :participants, Array[FreckleApi::User]
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
coerce_key :created_at, coerce_to_datetime
|
9
|
+
coerce_key :updated_at, coerce_to_datetime
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
# entries is a method of hash, so we're aliasing
|
12
|
+
# it for now. Hashie's MethodWithIndirectAccess
|
13
|
+
# should take care of this, but it doesn't
|
14
|
+
# seem to work in this case, so we do it manually.
|
15
|
+
alias_method :__entries, :entries
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
def entries
|
18
|
+
self[:entries]
|
19
|
+
end
|
20
|
+
|
21
|
+
def reload!(api)
|
22
|
+
update api.project(FreckleApi.uri('projects', id))
|
23
|
+
end
|
18
24
|
end
|
19
25
|
end
|
data/lib/freckle_api/timer.rb
CHANGED
@@ -1,6 +1,43 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
# TODO: actual error handling
|
2
|
+
class FreckleApi
|
3
|
+
class Timer < FreckleApi::Model
|
4
|
+
coerce_key :state, Symbol
|
5
|
+
coerce_key :date, coerce_to_date
|
6
|
+
coerce_key :user, FreckleApi::User
|
7
|
+
coerce_key :project, FreckleApi::Project
|
8
|
+
|
9
|
+
def start!(api)
|
10
|
+
update api.request(:put, timer_uri(:start))
|
11
|
+
end
|
12
|
+
|
13
|
+
def pause!(api)
|
14
|
+
update api.request(:put, timer_uri(:pause))
|
15
|
+
end
|
16
|
+
|
17
|
+
def log!(api, entry_date: nil, minutes: nil, description: nil)
|
18
|
+
response = api.request(:put, timer_uri(:log), parse: false)
|
19
|
+
|
20
|
+
response.code.to_i == 204
|
21
|
+
end
|
22
|
+
|
23
|
+
def discard!(api)
|
24
|
+
api.request(:put, timer_uri(:discard), parse: false)
|
25
|
+
|
26
|
+
response.code.to_i == 204 ? true : nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def reload!(api)
|
30
|
+
response = api.request(:get,
|
31
|
+
FreckleApi.uri('projects', project.id, 'timer'),
|
32
|
+
parse: false)
|
33
|
+
|
34
|
+
response.code.to_i == 204 ? update(response.body) : nil
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def timer_uri(action)
|
40
|
+
FreckleApi.uri('projects', project.id, 'timer', action)
|
41
|
+
end
|
42
|
+
end
|
6
43
|
end
|
data/lib/freckle_api/user.rb
CHANGED
data/lib/freckle_api/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
RSpec.describe FreckleApi::Timer do
|
2
|
+
include_context 'api'
|
3
|
+
let(:timer) { api.timer(existing_project_id) }
|
4
|
+
|
5
|
+
describe '#pause!' do
|
6
|
+
context 'when the timer is running' do
|
7
|
+
before do
|
8
|
+
stub_get_timer(existing_project_id)
|
9
|
+
stub_put_timer_event(existing_project_id, :pause)
|
10
|
+
|
11
|
+
timer.pause!(api)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'pauses the timer' do
|
15
|
+
expect(timer.state).to eq :paused
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#start!' do
|
21
|
+
context 'when the timer is paused' do
|
22
|
+
before do
|
23
|
+
stub_get_timer(existing_project_id, file: 'pause')
|
24
|
+
stub_put_timer_event(existing_project_id, :start)
|
25
|
+
|
26
|
+
timer.start!(api)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'starts the timer' do
|
30
|
+
expect(timer.state).to eq :running
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#log!' do
|
36
|
+
context 'when the timer is running' do
|
37
|
+
before do
|
38
|
+
stub_get_timer(existing_project_id)
|
39
|
+
stub_put_timer_log(existing_project_id)
|
40
|
+
end
|
41
|
+
|
42
|
+
let(:result) { timer.log!(api) }
|
43
|
+
|
44
|
+
it 'logs the timer, returning true' do
|
45
|
+
expect(result).to eq true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'no longer exists' do
|
49
|
+
result
|
50
|
+
|
51
|
+
stub_api(:get, "projects/#{existing_project_id}/timer", status: 404)
|
52
|
+
|
53
|
+
expect(timer.reload!(api)).to be_nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#discard!' do
|
59
|
+
end
|
60
|
+
end
|
data/spec/freckle_api_spec.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'freckle_api'
|
3
|
-
|
4
1
|
RSpec.describe FreckleApi do
|
5
|
-
|
6
|
-
let(:api) { FreckleApi.new('valid_api_key') }
|
2
|
+
include_context 'api'
|
7
3
|
|
8
4
|
describe '#project' do
|
9
5
|
context 'given a valid project id' do
|
10
|
-
let(:project) { api.project(
|
6
|
+
let(:project) { api.project(existing_project_id) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
stub_get_project(existing_project_id)
|
10
|
+
end
|
11
11
|
|
12
12
|
it 'returns the project' do
|
13
13
|
expect(project).to be_a FreckleApi::Project
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'contains the expected simple values' do
|
17
|
-
expect(project.id).to eq
|
17
|
+
expect(project.id).to eq existing_project_id
|
18
18
|
expect(project.name).to eq 'Gear GmbH'
|
19
19
|
expect(project.billing_increment).to eq 10
|
20
20
|
expect(project.enabled).to eq true
|
21
21
|
expect(project.billable).to eq true
|
22
22
|
expect(project.color).to eq '#ff9898'
|
23
|
-
expect(project.url).to eq "#{base_uri}/projects
|
23
|
+
expect(project.url).to eq "#{base_uri}/projects/#{existing_project_id}"
|
24
24
|
expect(project.minutes).to eq 180
|
25
25
|
expect(project.billable_minutes).to eq 120
|
26
26
|
expect(project.unbillable_minutes).to eq 60
|
@@ -28,9 +28,9 @@ RSpec.describe FreckleApi do
|
|
28
28
|
expect(project.remaining_minutes).to eq 630
|
29
29
|
expect(project.budget_minutes).to eq 750
|
30
30
|
expect(project.entries).to eq 0
|
31
|
-
expect(project.entries_url).to eq "#{base_uri}/projects/
|
31
|
+
expect(project.entries_url).to eq "#{base_uri}/projects/#{existing_project_id}/entries"
|
32
32
|
expect(project.expenses).to eq 0
|
33
|
-
expect(project.expenses_url).to eq "#{base_uri}/projects/
|
33
|
+
expect(project.expenses_url).to eq "#{base_uri}/projects/#{existing_project_id}/expenses"
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'contains the correct coerced timestamps' do
|
@@ -80,13 +80,13 @@ RSpec.describe FreckleApi do
|
|
80
80
|
participant = project.participants.last
|
81
81
|
|
82
82
|
expect(participant).to be_a FreckleApi::User
|
83
|
-
expect(participant.id).to eq
|
83
|
+
expect(participant.id).to eq existing_user_id
|
84
84
|
expect(participant.email).to eq 'john.test@test.com'
|
85
85
|
expect(participant.first_name).to eq 'John'
|
86
86
|
expect(participant.last_name).to eq 'Test'
|
87
87
|
expect(participant.profile_image_url).to eq(
|
88
88
|
'https://api.letsfreckle.com/images/avatars/0000/0001/avatar.jpg')
|
89
|
-
expect(participant.url).to eq "#{base_uri}/users
|
89
|
+
expect(participant.url).to eq "#{base_uri}/users/#{existing_user_id}"
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
@@ -96,6 +96,10 @@ RSpec.describe FreckleApi do
|
|
96
96
|
# of the individual project above.
|
97
97
|
let(:projects) { api.projects }
|
98
98
|
|
99
|
+
before do
|
100
|
+
stub_get_projects
|
101
|
+
end
|
102
|
+
|
99
103
|
it 'returns a collection of projects' do
|
100
104
|
expect(projects).to respond_to(:count)
|
101
105
|
expect(projects.count).to eq 1
|
@@ -104,7 +108,12 @@ RSpec.describe FreckleApi do
|
|
104
108
|
end
|
105
109
|
|
106
110
|
describe '#timer' do
|
107
|
-
let(:timer) { api.timer(
|
111
|
+
let(:timer) { api.timer(existing_project_id) }
|
112
|
+
|
113
|
+
before do
|
114
|
+
stub_get_project(existing_project_id)
|
115
|
+
stub_get_timer(existing_project_id)
|
116
|
+
end
|
108
117
|
|
109
118
|
it 'returns the timer' do
|
110
119
|
expect(timer).to be_a FreckleApi::Timer
|
@@ -115,10 +124,10 @@ RSpec.describe FreckleApi do
|
|
115
124
|
expect(timer.state).to eq :running
|
116
125
|
expect(timer.seconds).to eq 180
|
117
126
|
expect(timer.description).to eq 'freckle work'
|
118
|
-
expect(timer.url).to eq "#{base_uri}/projects/
|
119
|
-
expect(timer.start_url).to eq "#{base_uri}/projects/
|
120
|
-
expect(timer.pause_url).to eq "#{base_uri}/projects/
|
121
|
-
expect(timer.log_url).to eq "#{base_uri}/projects/
|
127
|
+
expect(timer.url).to eq "#{base_uri}/projects/#{existing_project_id}/timer"
|
128
|
+
expect(timer.start_url).to eq "#{base_uri}/projects/#{existing_project_id}/timer/start"
|
129
|
+
expect(timer.pause_url).to eq "#{base_uri}/projects/#{existing_project_id}/timer/pause"
|
130
|
+
expect(timer.log_url).to eq "#{base_uri}/projects/#{existing_project_id}/timer/log"
|
122
131
|
end
|
123
132
|
|
124
133
|
it 'contains the coerced date' do
|
@@ -129,30 +138,30 @@ RSpec.describe FreckleApi do
|
|
129
138
|
user = timer.user
|
130
139
|
|
131
140
|
expect(user).to be_a FreckleApi::User
|
132
|
-
expect(user.id).to eq
|
141
|
+
expect(user.id).to eq existing_user_id
|
133
142
|
expect(user.email).to eq 'john.test@test.com'
|
134
143
|
expect(user.first_name).to eq 'John'
|
135
144
|
expect(user.last_name).to eq 'Test'
|
136
145
|
expect(user.profile_image_url).to eq(
|
137
146
|
'https://api.letsfreckle.com/images/avatars/0000/0001/avatar.jpg')
|
138
|
-
expect(user.url).to eq "#{base_uri}/users
|
147
|
+
expect(user.url).to eq "#{base_uri}/users/#{existing_user_id}"
|
139
148
|
end
|
140
149
|
|
141
150
|
it 'contains the expected project' do
|
142
151
|
project = timer.project
|
143
152
|
|
144
153
|
expect(project).to be_a FreckleApi::Project
|
145
|
-
expect(project.id).to eq
|
154
|
+
expect(project.id).to eq existing_project_id
|
146
155
|
expect(project.name).to eq 'Gear GmbH'
|
147
156
|
expect(project.billing_increment).to eq 10
|
148
157
|
expect(project.enabled).to eq true
|
149
158
|
expect(project.billable).to eq true
|
150
159
|
expect(project.color).to eq '#ff9898'
|
151
|
-
expect(project.url).to eq "#{base_uri}/projects
|
160
|
+
expect(project.url).to eq "#{base_uri}/projects/#{existing_project_id}"
|
152
161
|
end
|
153
162
|
|
154
163
|
context 'when passing an actual project' do
|
155
|
-
let(:timer) { api.timer(api.project(
|
164
|
+
let(:timer) { api.timer(api.project(existing_project_id)) }
|
156
165
|
|
157
166
|
it 'returns the timer' do
|
158
167
|
expect(timer).to be_a FreckleApi::Timer
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
+
require 'codeclimate-test-reporter'
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
|
1
4
|
require 'rspec'
|
2
5
|
require 'webmock/rspec'
|
3
6
|
require 'pry'
|
4
7
|
require 'pry-byebug'
|
5
|
-
|
8
|
+
|
9
|
+
require 'freckle_api'
|
10
|
+
require 'support/shared_contexts/api.rb'
|
11
|
+
require 'support/api_helper.rb'
|
6
12
|
|
7
13
|
RSpec.configure do |config|
|
8
14
|
config.expect_with :rspec do |expectations|
|
@@ -73,8 +79,9 @@ RSpec.configure do |config|
|
|
73
79
|
# as the one that triggered the failure.
|
74
80
|
Kernel.srand config.seed
|
75
81
|
|
76
|
-
config.
|
77
|
-
|
78
|
-
|
82
|
+
config.include ApiHelper
|
83
|
+
|
84
|
+
config.after(:suite) do
|
85
|
+
WebMock.disable_net_connect!(allow: 'codeclimate.com')
|
79
86
|
end
|
80
87
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ApiHelper
|
2
|
+
def stub_api(method, remote_path, body: '', file_path: nil, status: 200)
|
3
|
+
headers = {
|
4
|
+
'User-Agent': 'freckle-api',
|
5
|
+
'X-FreckleToken': valid_api_key
|
6
|
+
}
|
7
|
+
|
8
|
+
if file_path
|
9
|
+
body = File.open("spec/fixtures/#{file_path || remote_path}.json").read
|
10
|
+
end
|
11
|
+
|
12
|
+
stub_request(method, [base_uri, remote_path].join('/'))
|
13
|
+
.with(headers: headers)
|
14
|
+
.to_return(status: status, body: body)
|
15
|
+
end
|
16
|
+
|
17
|
+
def stub_get_project(id)
|
18
|
+
stub_api(:get,
|
19
|
+
"projects/#{id}",
|
20
|
+
file_path: 'projects/show')
|
21
|
+
end
|
22
|
+
|
23
|
+
def stub_get_projects
|
24
|
+
stub_api(:get, 'projects', file_path: 'projects')
|
25
|
+
end
|
26
|
+
|
27
|
+
def stub_get_timer(project_id, file: nil)
|
28
|
+
path = 'projects/show/timer'
|
29
|
+
path = [path, file].join('/') if file
|
30
|
+
|
31
|
+
stub_api(:get,
|
32
|
+
"projects/#{project_id}/timer",
|
33
|
+
file_path: path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def stub_put_timer_event(project_id, event)
|
37
|
+
stub_api(:put, "projects/#{project_id}/timer/#{event}",
|
38
|
+
file_path: "projects/show/timer/#{event}")
|
39
|
+
end
|
40
|
+
|
41
|
+
def stub_put_timer_log(project_id)
|
42
|
+
stub_api(:put, "projects/#{project_id}/timer/log", status: 204)
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
shared_context 'api' do
|
2
|
+
let(:base_uri) { 'https://api.letsfreckle.com/v2' }
|
3
|
+
let(:valid_api_key) { 'valid_api_key' }
|
4
|
+
let(:invalid_api_key) { 'valid_api_key' }
|
5
|
+
|
6
|
+
let(:existing_project_id) { 37_396 }
|
7
|
+
let(:existing_user_id) { 5_538 }
|
8
|
+
|
9
|
+
let(:api) { FreckleApi.new(valid_api_key) }
|
10
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: freckle-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamie Schembri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -67,33 +67,19 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.3'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: codeclimate-test-reporter
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0.4'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: sinatra-contrib
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '1.4'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '1.4'
|
82
|
+
version: '0.4'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: hashie
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,9 +112,11 @@ files:
|
|
126
112
|
- lib/freckle_api/timer.rb
|
127
113
|
- lib/freckle_api/user.rb
|
128
114
|
- lib/freckle_api/version.rb
|
115
|
+
- spec/freckle_api/timer_spec.rb
|
129
116
|
- spec/freckle_api_spec.rb
|
130
117
|
- spec/spec_helper.rb
|
131
|
-
- spec/support/
|
118
|
+
- spec/support/api_helper.rb
|
119
|
+
- spec/support/shared_contexts/api.rb
|
132
120
|
homepage: http://github.com/shkm/freckle-api
|
133
121
|
licenses:
|
134
122
|
- MIT
|
@@ -139,9 +127,9 @@ require_paths:
|
|
139
127
|
- lib
|
140
128
|
required_ruby_version: !ruby/object:Gem::Requirement
|
141
129
|
requirements:
|
142
|
-
- -
|
130
|
+
- - '='
|
143
131
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
132
|
+
version: 2.3.0
|
145
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
134
|
requirements:
|
147
135
|
- - ">="
|
@@ -154,6 +142,8 @@ signing_key:
|
|
154
142
|
specification_version: 4
|
155
143
|
summary: Client for Freckle's API V2.
|
156
144
|
test_files:
|
145
|
+
- spec/freckle_api/timer_spec.rb
|
157
146
|
- spec/freckle_api_spec.rb
|
158
147
|
- spec/spec_helper.rb
|
159
|
-
- spec/support/
|
148
|
+
- spec/support/api_helper.rb
|
149
|
+
- spec/support/shared_contexts/api.rb
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'sinatra/base'
|
2
|
-
require 'sinatra/namespace'
|
3
|
-
|
4
|
-
class FakeFreckle < Sinatra::Base
|
5
|
-
register Sinatra::Namespace
|
6
|
-
|
7
|
-
set :port, 443
|
8
|
-
|
9
|
-
namespace '/v2' do
|
10
|
-
namespace '/projects' do
|
11
|
-
get do
|
12
|
-
json_response 200, 'projects'
|
13
|
-
end
|
14
|
-
|
15
|
-
namespace '/:id' do
|
16
|
-
get do
|
17
|
-
json_response 200, 'projects/37396'
|
18
|
-
end
|
19
|
-
|
20
|
-
get '/timer' do
|
21
|
-
json_response 200, 'projects/37396/timer'
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def json_response(response_code, file_name)
|
30
|
-
content_type :json
|
31
|
-
status response_code
|
32
|
-
|
33
|
-
File.open("#{File.dirname(__FILE__)}/fixtures/#{file_name}.json", 'rb').read
|
34
|
-
end
|
35
|
-
end
|