freckle-api 0.1.0 → 0.1.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: 62d0200c8b4beb472d2099eb324cae42d8f4396f
4
- data.tar.gz: be9601b09316bc7c84605b974ad1edcffd2493fa
3
+ metadata.gz: 98be6621cecd9046aa1ca6e7cadc2d18cb06d5d5
4
+ data.tar.gz: 4e4d3fd3851320e06c272ff0a2c55cb36edc6c8c
5
5
  SHA512:
6
- metadata.gz: 41425bebaca7754292b57479ca4a99799f7f4f2ffb5742fccad9acae04a92ce5bc2f11dd9e9a550b22b983859c92a9d14515ffd88b39a73d7f51d658d31dbf2f
7
- data.tar.gz: 9c330b1c4bca4160723ff36bf28b9f5200417062e9f334cb5de485e6ab330dda3717a2ceb83cd74a519a7b2a76d738053796f067fc5dc97d14e0dc9c243523a2
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
+ [![Gem Version](https://badge.fury.io/rb/freckle-api.svg)](https://badge.fury.io/rb/freckle-api)
5
+ [![Dependency Status](https://gemnasium.com/shkm/freckle-api.svg)](https://gemnasium.com/shkm/freckle-api)
6
+ [![Build Status](https://travis-ci.org/shkm/freckle-api.svg)](https://travis-ci.org/shkm/freckle-api)
7
+ [![Code Climate](https://codeclimate.com/github/shkm/freckle-api/badges/gpa.svg)](https://codeclimate.com/github/shkm/freckle-api)
8
+ [![Test Coverage](https://codeclimate.com/github/shkm/freckle-api/badges/coverage.svg)](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,
@@ -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(:get, uri('projects')).map do |project|
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
- private
40
+ def timers
41
+ Timer.list(request :get, self.class.uri('timers'))
42
+ end
37
43
 
38
- def request(method, uri)
39
- https = Net::HTTP.new(uri.host, uri.port).tap { |h| h.use_ssl = true }
44
+ def request(method, uri, parse: true, params: {})
45
+ request = build_request(method, uri, params)
46
+ response = send_request(request, uri)
40
47
 
41
- response = https.request(http_class(method).new(uri.path, headers))
48
+ parse ? JSON.parse(response.body) : response
49
+ end
42
50
 
43
- JSON.parse(response.body)
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 http_class(method)
47
- "Net::HTTP::#{method.to_s.capitalize}".constantize
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 uri(*path)
51
- URI.parse [BASE_URI, *path].join('/')
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 FreckleApi::Coercions
8
- def self.included(base)
9
- base.extend(ClassMethods)
10
- end
6
+ class FreckleApi
7
+ module Coercions
11
8
 
12
- module ClassMethods
13
- # TODO: timezone based on local machine
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
- def coerce_to_date
20
- Date.method(:parse).to_proc
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
@@ -1,2 +1,4 @@
1
- class FreckleApi::Group < FreckleApi::Model
1
+ class FreckleApi
2
+ class Group < FreckleApi::Model
3
+ end
2
4
  end
@@ -1,2 +1,4 @@
1
- class FreckleApi::Import < FreckleApi::Model
1
+ class FreckleApi
2
+ class Import < FreckleApi::Model
3
+ end
2
4
  end
@@ -1,3 +1,5 @@
1
- class FreckleApi::Invoice < FreckleApi::Model
2
- coerce_key :invoice_date, coerce_to_date
1
+ class FreckleApi
2
+ class Invoice < FreckleApi::Model
3
+ coerce_key :invoice_date, coerce_to_date
4
+ end
3
5
  end
@@ -1,10 +1,20 @@
1
1
  require 'hashie'
2
2
 
3
- class FreckleApi::Model < Hash
4
- include Hashie::Extensions::Coercion
5
- include Hashie::Extensions::MergeInitializer
6
- include Hashie::Extensions::MethodAccess
7
- include Hashie::Extensions::IndifferentAccess
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
- include FreckleApi::Coercions
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
@@ -1,19 +1,25 @@
1
- class FreckleApi::Project < FreckleApi::Model
2
- coerce_key :group, FreckleApi::Group
3
- coerce_key :import, FreckleApi::Import
4
- coerce_key :invoices, Array[FreckleApi::Invoice]
5
- coerce_key :participants, Array[FreckleApi::User]
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
- coerce_key :created_at, coerce_to_datetime
8
- coerce_key :updated_at, coerce_to_datetime
8
+ coerce_key :created_at, coerce_to_datetime
9
+ coerce_key :updated_at, coerce_to_datetime
9
10
 
10
- # entries is a method of hash, so we're aliasing
11
- # it for now. Hashie's MethodWithIndirectAccess
12
- # should take care of this, but it doesn't
13
- # seem to work in this case, so we do it manually.
14
- alias_method :__entries, :entries
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
- def entries
17
- self[:entries]
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
@@ -1,6 +1,43 @@
1
- class FreckleApi::Timer < FreckleApi::Model
2
- coerce_key :state, Symbol
3
- coerce_key :date, coerce_to_date
4
- coerce_key :user, FreckleApi::User
5
- coerce_key :project, FreckleApi::Project
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
@@ -1,2 +1,4 @@
1
- class FreckleApi::User < FreckleApi::Model
1
+ class FreckleApi
2
+ class User < FreckleApi::Model
3
+ end
2
4
  end
@@ -1,3 +1,3 @@
1
1
  class FreckleApi
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -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
@@ -1,26 +1,26 @@
1
- require 'spec_helper'
2
- require 'freckle_api'
3
-
4
1
  RSpec.describe FreckleApi do
5
- let(:base_uri) { 'https://api.letsfreckle.com/v2' }
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(37_396) }
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 37_396
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/37396"
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/37396/entries"
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/37396/expenses"
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 5538
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/5538"
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(37_396) }
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/37396/timer"
119
- expect(timer.start_url).to eq "#{base_uri}/projects/37396/timer/start"
120
- expect(timer.pause_url).to eq "#{base_uri}/projects/37396/timer/pause"
121
- expect(timer.log_url).to eq "#{base_uri}/projects/37396/timer/log"
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 5_538
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/5538"
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 37_396
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/37396"
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(37_396)) }
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
@@ -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
- require 'support/fake_freckle.rb'
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.before(:each) do
77
- # Thanks https://robots.thoughtbot.com/how-to-stub-external-services-in-tests
78
- stub_request(:any, %r{api.letsfreckle.com:443/v2}).to_rack(FakeFreckle)
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.0
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-22 00:00:00.000000000 Z
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: sinatra
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: '1.4'
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: '1.4'
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/fake_freckle.rb
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: '0'
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/fake_freckle.rb
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