noko 1.5.0 → 1.6.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f94cee93501cafa4e6da7bd8ef0999756bddc5522c75c80e14011ec51148c549
4
- data.tar.gz: a01355b30b080a1a426d4ebfbeafe52e589dee5a3abb25549c45908327443e4b
3
+ metadata.gz: 1ff0fcc7691e060653275c30cdfb02fd4e19da5ee2f4e1468c6935f26d0c3454
4
+ data.tar.gz: 622da78be984693f095e5f931c32a52606d1a1cd8f440e53025251c20ebe3f4b
5
5
  SHA512:
6
- metadata.gz: 28a0a6f65984f9ed798c53ca41c0c284241cac772f8f79890fe3bb7460f7b88dc44ec1f286b73eb3cd95c6a25eb647fee268adccc8e783d197f1e7edb53d6faa
7
- data.tar.gz: e987e8941de9b126f5a097fe4799f896c291182fa086e923195d3af0a0d13610ad6c2989a6fbacdbfa19532f6fbbffbe975e0efe0ad921cb91c1ea79b37317c2
6
+ metadata.gz: 63232176cc36783f3891245dcc44a0ee800312038ae904216cc7f219533d2ce4df9382acc80b5b2f1b8bfc722aa29f924e8efda411e8281c912ca78f32cebbcf
7
+ data.tar.gz: bcb26ccd331dbc71c88193aba038c5f1c06272c0c93590d11486229bf77fdfb795010aa05d18d93b3bd8cdceff51b922bc4b52ad69cd5f6cf8c7c7a9e83d0701
@@ -0,0 +1,47 @@
1
+ # 1.6.0
2
+
3
+ * Added Noko::NotFound for 404 responses
4
+
5
+ * Added Noko::ClientError for 4xx responses
6
+
7
+ * Added Noko::ServerError for 5xx responses
8
+
9
+ # 1.5.0
10
+
11
+ * Added methods for marking entries invoiced (thanks @lcx)
12
+
13
+ * Added methods for marking entries approved
14
+
15
+ * Added methods for marking entries unapproved
16
+
17
+ # 1.4.0
18
+
19
+ * **(breaking change)** Renamed gem from freckles to noko. Steps to upgrade:
20
+
21
+ - rename the gem in your Gemfile from `gem 'freckles'` to `gem 'noko'`
22
+ - rename any requires from `require 'freckle'` to `require 'noko'`
23
+ - rename any module references from `Freckle` to `Noko`
24
+
25
+ # 1.3.0
26
+
27
+ * Updated to use nokotime.com hostnames (thanks @madrobby)
28
+
29
+ * Updated to use X-NokoToken header
30
+
31
+ # 1.2.0
32
+
33
+ * Added methods for project group resources
34
+
35
+ * Changed default user agent header to include version numbers
36
+
37
+ * Removed deprecated #next_page attribute
38
+
39
+ # 1.1.0
40
+
41
+ * Added methods for returning Link header pagination urls
42
+
43
+ * Deprecated #next_page attribute
44
+
45
+ # 1.0.0
46
+
47
+ * First version!
@@ -1,4 +1,4 @@
1
- Copyright (c) 2015-2019 TIMCRAFT
1
+ Copyright (c) 2015-2020 TIMCRAFT
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
data/README.md CHANGED
@@ -1,38 +1,29 @@
1
1
  # noko
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/noko.svg)](https://badge.fury.io/rb/noko) [![Build Status](https://api.travis-ci.org/timcraft/noko.svg?branch=master)](https://travis-ci.org/timcraft/noko)
3
+ [![Gem Version](https://badge.fury.io/rb/noko.svg)](https://badge.fury.io/rb/noko)
4
+ ![Build Status](https://github.com/timcraft/noko/workflows/Test/badge.svg)
4
5
 
5
6
 
6
- Ruby client for [Version 2 of the Noko/Freckle API](https://developer.nokotime.com/v2/).
7
+ Ruby client for the [Noko API](https://developer.nokotime.com/v2/).
7
8
 
8
9
 
9
10
  ## Install
10
11
 
11
- Install using RubyGems:
12
+ Using Bundler:
12
13
 
13
- ```
14
- $ gem install noko
15
- ```
16
-
17
- Add it to your Gemfile and install using Bundler:
18
-
19
- ```ruby
20
- gem 'noko'
21
- ```
14
+ $ bundle add noko
22
15
 
23
- Clone the repository:
16
+ Using RubyGems:
24
17
 
25
- ```
26
- git clone git@github.com:timcraft/noko.git
27
- ```
18
+ $ gem install noko
28
19
 
29
20
 
30
- ## Quick start
21
+ ## Getting started
31
22
 
32
23
  ```ruby
33
24
  require 'noko'
34
25
 
35
- noko = Noko::Client.new(token: 'YOUR PERSONAL ACCESS TOKEN')
26
+ noko = Noko::Client.new(token: ENV.fetch('NOKO_TOKEN'))
36
27
 
37
28
  noko.get_projects.each do |project|
38
29
  puts project.name
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  require 'noko/version'
2
3
  require 'noko/errors'
3
4
  require 'noko/link_header'
4
5
  require 'noko/params'
5
6
  require 'noko/record'
7
+ require 'noko/response'
6
8
  require 'net/http'
7
9
  require 'json'
8
10
 
@@ -51,32 +53,12 @@ module Noko
51
53
  http_request.body = JSON.generate(body_object)
52
54
  end
53
55
 
54
- parse(@http.request(http_request))
55
- end
56
-
57
- def parse(http_response)
58
- case http_response
59
- when Net::HTTPNoContent
60
- :no_content
61
- when Net::HTTPSuccess
62
- if http_response['Content-Type'] && http_response['Content-Type'].split(';').first == 'application/json'
63
- JSON.parse(http_response.body, symbolize_names: true, object_class: Record).tap do |object|
64
- if http_response['Link']
65
- object.singleton_class.module_eval { attr_accessor :link }
66
- object.link = LinkHeader.parse(http_response['Link'])
67
- end
68
- end
69
- else
70
- http_response.body
71
- end
72
- when Net::HTTPBadRequest
73
- object = JSON.parse(http_response.body, symbolize_names: true)
56
+ response = @http.request(http_request)
74
57
 
75
- raise Error, object.fetch(:message)
76
- when Net::HTTPUnauthorized
77
- raise AuthenticationError
58
+ if response.is_a?(Net::HTTPSuccess)
59
+ Response.parse(response)
78
60
  else
79
- raise Error, "unexpected #{http_response.code} response from #{@host}"
61
+ raise Response.error(response)
80
62
  end
81
63
  end
82
64
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_account
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_current_user
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_entries(params = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_expenses(params = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_invoices(params = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_project_groups(params = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_projects(params = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_tags(params = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_timers(params = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Noko
2
4
  class Client
3
5
  def get_users(params = nil)
@@ -1,5 +1,11 @@
1
1
  module Noko
2
- class Error < StandardError; end
2
+ Error = Class.new(StandardError)
3
3
 
4
- class AuthenticationError < Error; end
4
+ ClientError = Class.new(Error)
5
+
6
+ ServerError = Class.new(Error)
7
+
8
+ AuthenticationError = Class.new(ClientError)
9
+
10
+ NotFound = Class.new(ClientError)
5
11
  end
@@ -2,7 +2,7 @@ require 'noko/record'
2
2
  require 'uri'
3
3
 
4
4
  module Noko
5
- module LinkHeader # :nodoc:
5
+ module LinkHeader
6
6
  extend self
7
7
 
8
8
  REGEXP = /<([^>]+)>; rel="(\w+)"/
@@ -13,4 +13,6 @@ module Noko
13
13
  end
14
14
  end
15
15
  end
16
+
17
+ private_constant :LinkHeader
16
18
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  require 'cgi'
2
3
 
3
4
  module Noko
4
- module Params # :nodoc:
5
+ module Params
5
6
  extend self
6
7
 
7
8
  def join(path, params = nil)
@@ -24,4 +25,6 @@ module Noko
24
25
  CGI.escape(component.to_s)
25
26
  end
26
27
  end
28
+
29
+ private_constant :Params
27
30
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ module Noko
6
+ module Response
7
+ extend self
8
+
9
+ def parse(response)
10
+ if response.is_a?(Net::HTTPNoContent)
11
+ return :no_content
12
+ end
13
+
14
+ if response.content_type == 'application/json'
15
+ object = JSON.parse(response.body, symbolize_names: true, object_class: Record)
16
+
17
+ if response['Link']
18
+ object.singleton_class.module_eval { attr_accessor :link }
19
+ object.link = LinkHeader.parse(response['Link'])
20
+ end
21
+
22
+ return object
23
+ end
24
+
25
+ response.body
26
+ end
27
+
28
+ def error(response)
29
+ if response.content_type == 'application/json'
30
+ body = JSON.parse(response.body)
31
+
32
+ error_class(response).new(body['message'])
33
+ else
34
+ error_class(response)
35
+ end
36
+ end
37
+
38
+ def error_class(object)
39
+ case object
40
+ when Net::HTTPBadRequest then Noko::ClientError
41
+ when Net::HTTPUnauthorized then Noko::AuthenticationError
42
+ when Net::HTTPNotFound then Noko::NotFound
43
+ when Net::HTTPClientError then Noko::ClientError
44
+ when Net::HTTPServerError then Noko::ServerError
45
+ else
46
+ Noko::Error
47
+ end
48
+ end
49
+ end
50
+
51
+ private_constant :Response
52
+ end
@@ -1,3 +1,3 @@
1
1
  module Noko
2
- VERSION = '1.5.0'
2
+ VERSION = '1.6.0'
3
3
  end
@@ -1,17 +1,20 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'noko'
3
- s.version = '1.5.0'
3
+ s.version = '1.6.0'
4
4
  s.license = 'MIT'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ['Tim Craft']
7
7
  s.email = ['mail@timcraft.com']
8
8
  s.homepage = 'https://github.com/timcraft/noko'
9
- s.description = 'Ruby client for Version 2 of the Noko/Freckle API'
10
- s.summary = 'Ruby client for Version 2 of the Noko/Freckle API'
11
- s.files = Dir.glob('{lib,test}/**/*') + %w(LICENSE.txt README.md noko.gemspec)
9
+ s.description = 'Ruby client for the Noko API'
10
+ s.summary = 'See description'
11
+ s.files = Dir.glob('lib/**/*.rb') + %w(CHANGES.md LICENSE.txt README.md noko.gemspec)
12
12
  s.required_ruby_version = '>= 1.9.3'
13
- s.add_development_dependency('rake', '~> 12')
14
- s.add_development_dependency('webmock', '~> 3.0')
15
- s.add_development_dependency('minitest', '~> 5.0')
16
13
  s.require_path = 'lib'
14
+ s.metadata = {
15
+ 'homepage' => 'https://github.com/timcraft/noko',
16
+ 'source_code_uri' => 'https://github.com/timcraft/noko',
17
+ 'bug_tracker_uri' => 'https://github.com/timcraft/noko/issues',
18
+ 'changelog_uri' => 'https://github.com/timcraft/noko/blob/master/CHANGES.md'
19
+ }
17
20
  end
metadata CHANGED
@@ -1,64 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: noko
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Craft
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-04 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rake
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '12'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '12'
27
- - !ruby/object:Gem::Dependency
28
- name: webmock
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '3.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '3.0'
41
- - !ruby/object:Gem::Dependency
42
- name: minitest
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '5.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '5.0'
55
- description: Ruby client for Version 2 of the Noko/Freckle API
11
+ date: 2020-05-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby client for the Noko API
56
14
  email:
57
15
  - mail@timcraft.com
58
16
  executables: []
59
17
  extensions: []
60
18
  extra_rdoc_files: []
61
19
  files:
20
+ - CHANGES.md
62
21
  - LICENSE.txt
63
22
  - README.md
64
23
  - lib/noko.rb
@@ -77,27 +36,17 @@ files:
77
36
  - lib/noko/link_header.rb
78
37
  - lib/noko/params.rb
79
38
  - lib/noko/record.rb
39
+ - lib/noko/response.rb
80
40
  - lib/noko/version.rb
81
41
  - noko.gemspec
82
- - test/noko/client/account_test.rb
83
- - test/noko/client/current_user_test.rb
84
- - test/noko/client/entries_test.rb
85
- - test/noko/client/errors_test.rb
86
- - test/noko/client/expenses_test.rb
87
- - test/noko/client/invoices_test.rb
88
- - test/noko/client/options_test.rb
89
- - test/noko/client/project_groups_test.rb
90
- - test/noko/client/projects_test.rb
91
- - test/noko/client/response_test.rb
92
- - test/noko/client/tags_test.rb
93
- - test/noko/client/timers_test.rb
94
- - test/noko/client/users_test.rb
95
- - test/noko/client_test.rb
96
- - test/noko/record_test.rb
97
42
  homepage: https://github.com/timcraft/noko
98
43
  licenses:
99
44
  - MIT
100
- metadata: {}
45
+ metadata:
46
+ homepage: https://github.com/timcraft/noko
47
+ source_code_uri: https://github.com/timcraft/noko
48
+ bug_tracker_uri: https://github.com/timcraft/noko/issues
49
+ changelog_uri: https://github.com/timcraft/noko/blob/master/CHANGES.md
101
50
  post_install_message:
102
51
  rdoc_options: []
103
52
  require_paths:
@@ -113,8 +62,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
62
  - !ruby/object:Gem::Version
114
63
  version: '0'
115
64
  requirements: []
116
- rubygems_version: 3.0.3
65
+ rubygems_version: 3.1.2
117
66
  signing_key:
118
67
  specification_version: 4
119
- summary: Ruby client for Version 2 of the Noko/Freckle API
68
+ summary: See description
120
69
  test_files: []
@@ -1,9 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientAccountTest < ClientTest
4
- def test_get_account
5
- expect_request(:get, "#{base_url}/account").with(auth_header).to_return(json_response)
6
-
7
- assert_instance_of Noko::Record, client.get_account
8
- end
9
- end
@@ -1,39 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientCurrentUserTest < ClientTest
4
- def test_get_current_user
5
- expect_request(:get, "#{base_url}/current_user").with(auth_header).to_return(json_response)
6
-
7
- assert_instance_of Noko::Record, client.get_current_user
8
- end
9
-
10
- def test_get_current_user_entries
11
- expect_request(:get, "#{base_url}/current_user/entries").with(auth_header).to_return(json_array_response)
12
-
13
- assert_equal [], client.get_current_user_entries
14
- end
15
-
16
- def test_get_current_user_entries_encodes_params
17
- expect_request(:get, "#{base_url}/current_user/entries?billable=true")
18
-
19
- client.get_current_user_entries(billable: true)
20
- end
21
-
22
- def test_get_current_user_expenses
23
- expect_request(:get, "#{base_url}/current_user/expenses").with(auth_header).to_return(json_array_response)
24
-
25
- assert_equal [], client.get_current_user_expenses
26
- end
27
-
28
- def test_get_current_user_expenses_encodes_params
29
- expect_request(:get, "#{base_url}/current_user/expenses?invoiced=true")
30
-
31
- client.get_current_user_expenses(invoiced: true)
32
- end
33
-
34
- def test_update_current_user
35
- expect_request(:put, "#{base_url}/current_user").with(json_request).to_return(json_response)
36
-
37
- assert_instance_of Noko::Record, client.update_current_user(week_start: 'monday')
38
- end
39
- end
@@ -1,91 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientEntriesTest < ClientTest
4
- def time
5
- Time.now.utc
6
- end
7
-
8
- def date
9
- Date.parse('2019-03-04')
10
- end
11
-
12
- def test_get_entries
13
- expect_request(:get, "#{base_url}/entries").with(auth_header).to_return(json_array_response)
14
-
15
- assert_equal [], client.get_entries
16
- end
17
-
18
- def test_get_entries_encodes_params
19
- expect_request(:get, "#{base_url}/entries?billable=true")
20
-
21
- client.get_entries(billable: true)
22
- end
23
-
24
- def test_get_entries_encodes_project_ids
25
- expect_request(:get, "#{base_url}/entries?project_ids=123,456,789")
26
-
27
- client.get_entries(project_ids: ids)
28
- end
29
-
30
- def test_get_entry
31
- expect_request(:get, "#{base_url}/entries/#{id}").with(auth_header).to_return(json_response)
32
-
33
- assert_instance_of Noko::Record, client.get_entry(id)
34
- end
35
-
36
- def test_create_entry
37
- expect_request(:post, "#{base_url}/entries").with(json_request).to_return(json_response.merge(status: 201))
38
-
39
- assert_instance_of Noko::Record, client.create_entry(date: Date.today, minutes: 60)
40
- end
41
-
42
- def test_update_entry
43
- expect_request(:put, "#{base_url}/entries/#{id}").with(json_request).to_return(json_response)
44
-
45
- assert_instance_of Noko::Record, client.update_entry(id, minutes: 120)
46
- end
47
-
48
- def test_delete_entry
49
- expect_request(:delete, "#{base_url}/entries/#{id}").with(auth_header).to_return(status: 204)
50
-
51
- assert_equal :no_content, client.delete_entry(id)
52
- end
53
-
54
- def test_mark_entry_invoiced
55
- expect_request(:put, "#{base_url}/entries/#{id}/marked_as_invoiced").with(json_request).to_return(status: 204)
56
-
57
- assert_equal :no_content, client.mark_entry_invoiced(id, date: date)
58
- end
59
-
60
- def test_mark_entries_invoiced
61
- expect_request(:put, "#{base_url}/entries/marked_as_invoiced").with(json_request).to_return(status: 204)
62
-
63
- assert_equal :no_content, client.mark_entries_invoiced(entry_ids: ids, date: date)
64
- end
65
-
66
- def test_mark_entry_approved
67
- body = /\A{"approved_at":"\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}Z"}\z/
68
-
69
- expect_request(:put, "#{base_url}/entries/#{id}/approved").with(json_request(body)).to_return(status: 204)
70
-
71
- assert_equal :no_content, client.mark_entry_approved(id, approved_at: time.iso8601)
72
- end
73
-
74
- def test_mark_entries_approved
75
- expect_request(:put, "#{base_url}/entries/approved").with(json_request).to_return(status: 204)
76
-
77
- assert_equal :no_content, client.mark_entries_approved(entry_ids: ids, approved_at: time)
78
- end
79
-
80
- def test_mark_entry_unapproved
81
- expect_request(:put, "#{base_url}/entries/#{id}/unapproved").with(headers: {'X-NokoToken' => token}).to_return(status: 204)
82
-
83
- assert_equal :no_content, client.mark_entry_unapproved(id)
84
- end
85
-
86
- def test_mark_entries_unapproved
87
- expect_request(:put, "#{base_url}/entries/unapproved").with(json_request).to_return(status: 204)
88
-
89
- assert_equal :no_content, client.mark_entries_unapproved(entry_ids: ids)
90
- end
91
- end
@@ -1,27 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientErrorsTest < ClientTest
4
- def test_bad_request_errors
5
- message = 'The Project cannot be deleted because it has entries, expenses, or invoices.'
6
-
7
- response = json_response.merge(status: 400, body: %({"message":"#{message}"}))
8
-
9
- stub_request(:delete, "#{base_url}/projects/#{id}").to_return(response)
10
-
11
- exception = assert_raises(Noko::Error) do
12
- client.delete_project(id)
13
- end
14
-
15
- assert_includes exception.message, message
16
- end
17
-
18
- def test_authentication_errors
19
- response = json_response.merge(status: 401)
20
-
21
- stub_request(:get, "#{base_url}/entries").to_return(response)
22
-
23
- assert_raises(Noko::AuthenticationError) do
24
- client.get_entries
25
- end
26
- end
27
- end
@@ -1,45 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientExpensesTest < ClientTest
4
- def test_get_expenses
5
- expect_request(:get, "#{base_url}/expenses").with(auth_header).to_return(json_array_response)
6
-
7
- assert_equal [], client.get_expenses
8
- end
9
-
10
- def test_get_expenses_encodes_params
11
- expect_request(:get, "#{base_url}/expenses?invoiced=true")
12
-
13
- client.get_expenses(invoiced: true)
14
- end
15
-
16
- def test_get_expenses_encodes_ids
17
- expect_request(:get, "#{base_url}/expenses?project_ids=123,456,789")
18
-
19
- client.get_expenses(project_ids: ids)
20
- end
21
-
22
- def test_get_expense
23
- expect_request(:get, "#{base_url}/expenses/#{id}").with(auth_header).to_return(json_response)
24
-
25
- assert_instance_of Noko::Record, client.get_expense(id)
26
- end
27
-
28
- def test_create_expense
29
- expect_request(:post, "#{base_url}/expenses").with(json_request).to_return(json_response.merge(status: 201))
30
-
31
- assert_instance_of Noko::Record, client.create_expense(date: Date.today, project_id: id, price: '14.55')
32
- end
33
-
34
- def test_update_expense
35
- expect_request(:put, "#{base_url}/expenses/#{id}").with(json_request).to_return(json_response)
36
-
37
- assert_instance_of Noko::Record, client.update_expense(id, price: '19.99')
38
- end
39
-
40
- def test_delete_expense
41
- expect_request(:delete, "#{base_url}/expenses/#{id}").with(auth_header).to_return(status: 204)
42
-
43
- assert_equal :no_content, client.delete_expense(id)
44
- end
45
- end
@@ -1,75 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientInvoicesTest < ClientTest
4
- def test_get_invoices
5
- expect_request(:get, "#{base_url}/invoices").with(auth_header).to_return(json_array_response)
6
-
7
- assert_equal [], client.get_invoices
8
- end
9
-
10
- def test_get_invoices_encodes_params
11
- expect_request(:get, "#{base_url}/invoices?state=unpaid")
12
-
13
- client.get_invoices(state: :unpaid)
14
- end
15
-
16
- def test_get_invoice
17
- expect_request(:get, "#{base_url}/invoices/#{id}").with(auth_header).to_return(json_response)
18
-
19
- assert_instance_of Noko::Record, client.get_invoice(id)
20
- end
21
-
22
- def test_create_invoice
23
- expect_request(:post, "#{base_url}/invoices").with(json_request).to_return(json_response.merge(status: 201))
24
-
25
- assert_instance_of Noko::Record, client.create_invoice(invoice_date: Date.today)
26
- end
27
-
28
- def test_update_invoice
29
- expect_request(:put, "#{base_url}/invoices/#{id}").with(json_request).to_return(json_response)
30
-
31
- assert_instance_of Noko::Record, client.update_invoice(id, reference: 'AB 0001')
32
- end
33
-
34
- def test_mark_invoice_paid
35
- expect_request(:put, "#{base_url}/invoices/#{id}/paid").with(auth_header).to_return(status: 204)
36
-
37
- assert_equal :no_content, client.mark_invoice_paid(id)
38
- end
39
-
40
- def test_mark_invoice_unpaid
41
- expect_request(:put, "#{base_url}/invoices/#{id}/unpaid").with(auth_header).to_return(status: 204)
42
-
43
- assert_equal :no_content, client.mark_invoice_unpaid(id)
44
- end
45
-
46
- def test_get_invoice_entries
47
- expect_request(:get, "#{base_url}/invoices/#{id}/entries").with(auth_header).to_return(json_array_response)
48
-
49
- assert_equal [], client.get_invoice_entries(id)
50
- end
51
-
52
- def test_get_invoice_entries_encodes_params
53
- expect_request(:get, "#{base_url}/invoices/#{id}/entries?billable=true")
54
-
55
- client.get_invoice_entries(id, billable: true)
56
- end
57
-
58
- def test_get_invoice_expenses
59
- expect_request(:get, "#{base_url}/invoices/#{id}/expenses").with(auth_header).to_return(json_array_response)
60
-
61
- assert_equal [], client.get_invoice_expenses(id)
62
- end
63
-
64
- def test_get_invoice_expenses_encodes_params
65
- expect_request(:get, "#{base_url}/invoices/#{id}/expenses?invoiced=false")
66
-
67
- client.get_invoice_expenses(id, invoiced: false)
68
- end
69
-
70
- def test_delete_invoice
71
- expect_request(:delete, "#{base_url}/invoices/#{id}").with(auth_header).to_return(status: 204)
72
-
73
- assert_equal :no_content, client.delete_invoice(id)
74
- end
75
- end
@@ -1,27 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientOptionsTest < ClientTest
4
- def user_agent
5
- 'account.nokotime.com'
6
- end
7
-
8
- def access_token
9
- 'oauth2-access-token'
10
- end
11
-
12
- def test_user_agent_option
13
- client = Noko::Client.new(token: token, user_agent: user_agent)
14
-
15
- expect_request(:get, "#{base_url}/entries").with(headers: {'User-Agent' => user_agent})
16
-
17
- client.get_entries
18
- end
19
-
20
- def test_access_token_option
21
- client = Noko::Client.new(access_token: access_token)
22
-
23
- expect_request(:get, "#{base_url}/entries").with(headers: {'Authorization' => 'token oauth2-access-token'})
24
-
25
- client.get_entries
26
- end
27
- end
@@ -1,63 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientProjectGroupsTest < ClientTest
4
- def test_get_project_groups
5
- expect_request(:get, "#{base_url}/project_groups").with(auth_header).to_return(json_array_response)
6
-
7
- assert_equal [], client.get_project_groups
8
- end
9
-
10
- def test_get_project_groups_encodes_params
11
- expect_request(:get, "#{base_url}/project_groups?name=Sprockets")
12
-
13
- client.get_project_groups(name: 'Sprockets')
14
- end
15
-
16
- def test_get_project_group
17
- expect_request(:get, "#{base_url}/project_groups/#{id}").with(auth_header).to_return(json_response)
18
-
19
- assert_instance_of Noko::Record, client.get_project_group(id)
20
- end
21
-
22
- def test_create_project_group
23
- expect_request(:post, "#{base_url}/project_groups").with(json_request).to_return(json_response.merge(status: 201))
24
-
25
- assert_instance_of Noko::Record, client.create_project_group(name: 'Sprockets, Inc.')
26
- end
27
-
28
- def test_get_project_group_entries
29
- expect_request(:get, "#{base_url}/project_groups/#{id}/entries").with(auth_header).to_return(json_array_response)
30
-
31
- assert_equal [], client.get_project_group_entries(id)
32
- end
33
-
34
- def test_get_project_group_entries_encodes_params
35
- expect_request(:get, "#{base_url}/project_groups/#{id}/entries?billable=true")
36
-
37
- client.get_project_group_entries(id, billable: true)
38
- end
39
-
40
- def test_get_project_group_projects
41
- expect_request(:get, "#{base_url}/project_groups/#{id}/projects").with(auth_header).to_return(json_array_response)
42
-
43
- assert_equal [], client.get_project_group_projects(id)
44
- end
45
-
46
- def test_get_project_group_projects_encodes_params
47
- expect_request(:get, "#{base_url}/project_groups/#{id}/projects?billable=true")
48
-
49
- client.get_project_group_projects(id, billable: true)
50
- end
51
-
52
- def test_update_project_group
53
- expect_request(:put, "#{base_url}/project_groups/#{id}").with(json_request).to_return(json_response)
54
-
55
- assert_instance_of Noko::Record, client.update_project_group(id, name: 'Sprockets, Inc.')
56
- end
57
-
58
- def test_delete_project_group
59
- expect_request(:delete, "#{base_url}/project_groups/#{id}").with(auth_header).to_return(status: 204)
60
-
61
- assert_equal :no_content, client.delete_project_group(id)
62
- end
63
- end
@@ -1,99 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientProjectsTest < ClientTest
4
- def test_get_projects
5
- expect_request(:get, "#{base_url}/projects").with(auth_header).to_return(json_array_response)
6
-
7
- assert_equal [], client.get_projects
8
- end
9
-
10
- def test_get_projects_encodes_params
11
- expect_request(:get, "#{base_url}/projects?billable=true")
12
-
13
- client.get_projects(billable: true)
14
- end
15
-
16
- def test_get_project
17
- expect_request(:get, "#{base_url}/projects/#{id}").with(auth_header).to_return(json_response)
18
-
19
- assert_instance_of Noko::Record, client.get_project(id)
20
- end
21
-
22
- def test_create_project
23
- expect_request(:post, "#{base_url}/projects").with(json_request).to_return(json_response.merge(status: 201))
24
-
25
- assert_instance_of Noko::Record, client.create_project(name: 'Gear GmbH')
26
- end
27
-
28
- def test_get_project_entries
29
- expect_request(:get, "#{base_url}/projects/#{id}/entries").with(auth_header).to_return(json_array_response)
30
-
31
- assert_equal [], client.get_project_entries(id)
32
- end
33
-
34
- def test_get_project_entries_encodes_params
35
- expect_request(:get, "#{base_url}/projects/#{id}/entries?billable=true")
36
-
37
- client.get_project_entries(id, billable: true)
38
- end
39
-
40
- def test_get_project_expenses
41
- expect_request(:get, "#{base_url}/projects/#{id}/expenses").with(auth_header).to_return(json_array_response)
42
-
43
- assert_equal [], client.get_project_expenses(id)
44
- end
45
-
46
- def test_get_project_expenses_encodes_params
47
- expect_request(:get, "#{base_url}/projects/#{id}/expenses?invoiced=true")
48
-
49
- client.get_project_expenses(id, invoiced: true)
50
- end
51
-
52
- def test_update_project
53
- expect_request(:put, "#{base_url}/projects/#{id}").with(json_request).to_return(json_response)
54
-
55
- assert_instance_of Noko::Record, client.update_project(id, color: '#ff9898')
56
- end
57
-
58
- def test_merge_projects
59
- expect_request(:put, "#{base_url}/projects/#{id}/merge").with(json_request.merge(body: '{"project_id":5678}')).to_return(status: 204)
60
-
61
- assert_equal :no_content, client.merge_projects(id, 5678)
62
- end
63
-
64
- def test_delete_project
65
- expect_request(:delete, "#{base_url}/projects/#{id}").with(auth_header).to_return(status: 204)
66
-
67
- assert_equal :no_content, client.delete_project(id)
68
- end
69
-
70
- def test_archive_project
71
- expect_request(:put, "#{base_url}/projects/#{id}/archive").with(auth_header).to_return(status: 204)
72
-
73
- assert_equal :no_content, client.archive_project(id)
74
- end
75
-
76
- def test_unarchive_project
77
- expect_request(:put, "#{base_url}/projects/#{id}/unarchive").with(auth_header).to_return(status: 204)
78
-
79
- assert_equal :no_content, client.unarchive_project(id)
80
- end
81
-
82
- def test_archive_projects
83
- expect_request(:put, "#{base_url}/projects/archive").with(json_request.merge(body: '{"project_ids":[123]}')).to_return(status: 204)
84
-
85
- assert_equal :no_content, client.archive_projects([id])
86
- end
87
-
88
- def test_unarchive_projects
89
- expect_request(:put, "#{base_url}/projects/unarchive").with(json_request.merge(body: '{"project_ids":[123]}')).to_return(status: 204)
90
-
91
- assert_equal :no_content, client.unarchive_projects([id])
92
- end
93
-
94
- def test_delete_projects
95
- expect_request(:put, "#{base_url}/projects/delete").with(json_request.merge(body: '{"project_ids":[123]}')).to_return(status: 204)
96
-
97
- assert_equal :no_content, client.delete_projects([id])
98
- end
99
- end
@@ -1,39 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientResponseTest < ClientTest
4
- def response(headers)
5
- {headers: json_response_headers.merge(headers), body: '[]'}
6
- end
7
-
8
- def test_rel_next_link
9
- link = '<https://api.nokotime.com/v2/entries?page=3>; rel="next"'
10
-
11
- expect_request(:get, "#{base_url}/entries").to_return(response('Link' => link))
12
-
13
- assert_equal '/v2/entries?page=3', client.get_entries.link.next
14
- end
15
-
16
- def test_rel_prev_link
17
- link = '<https://api.nokotime.com/v2/entries?page=2>; rel="prev"'
18
-
19
- expect_request(:get, "#{base_url}/entries").to_return(response('Link' => link))
20
-
21
- assert_equal '/v2/entries?page=2', client.get_entries.link.prev
22
- end
23
-
24
- def test_rel_last_link
25
- link = '<https://api.nokotime.com/v2/entries?page=50>; rel="last"'
26
-
27
- expect_request(:get, "#{base_url}/entries").to_return(response('Link' => link))
28
-
29
- assert_equal '/v2/entries?page=50', client.get_entries.link.last
30
- end
31
-
32
- def test_rel_first_link
33
- link = '<https://api.nokotime.com/v2/entries?page=1>; rel="first"'
34
-
35
- expect_request(:get, "#{base_url}/entries").to_return(response('Link' => link))
36
-
37
- assert_equal '/v2/entries?page=1', client.get_entries.link.first
38
- end
39
- end
@@ -1,63 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientTagsTest < ClientTest
4
- def test_get_tags
5
- expect_request(:get, "#{base_url}/tags").with(auth_header).to_return(json_array_response)
6
-
7
- assert_equal [], client.get_tags
8
- end
9
-
10
- def test_get_tags_encodes_params
11
- expect_request(:get, "#{base_url}/tags?billable=true")
12
-
13
- client.get_tags(billable: true)
14
- end
15
-
16
- def test_create_tags
17
- expect_request(:post, "#{base_url}/tags").with(json_request).to_return(json_array_response.merge(status: 201))
18
-
19
- assert_equal [], client.create_tags(%w[freckle])
20
- end
21
-
22
- def test_get_tag
23
- expect_request(:get, "#{base_url}/tags/#{id}").with(auth_header).to_return(json_response)
24
-
25
- assert_instance_of Noko::Record, client.get_tag(id)
26
- end
27
-
28
- def test_get_tag_entries
29
- expect_request(:get, "#{base_url}/tags/#{id}/entries").with(auth_header).to_return(json_array_response)
30
-
31
- assert_equal [], client.get_tag_entries(id)
32
- end
33
-
34
- def test_get_tag_entries_encodes_params
35
- expect_request(:get, "#{base_url}/tags/#{id}/entries?billable=true")
36
-
37
- client.get_tag_entries(id, billable: true)
38
- end
39
-
40
- def test_update_tag
41
- expect_request(:put, "#{base_url}/tags/#{id}").with(json_request).to_return(json_response)
42
-
43
- assert_instance_of Noko::Record, client.update_tag(id, name: 'freckle')
44
- end
45
-
46
- def test_merge_tags
47
- expect_request(:put, "#{base_url}/tags/#{id}/merge").with(json_request.merge(body: '{"tag_id":5678}')).to_return(status: 204)
48
-
49
- assert_equal :no_content, client.merge_tags(id, 5678)
50
- end
51
-
52
- def test_delete_tag
53
- expect_request(:delete, "#{base_url}/tags/#{id}").with(auth_header).to_return(status: 204)
54
-
55
- assert_equal :no_content, client.delete_tag(id)
56
- end
57
-
58
- def test_delete_tags
59
- expect_request(:put, "#{base_url}/tags/delete").with(json_request.merge(body: '{"tag_ids":[123]}')).to_return(status: 204)
60
-
61
- assert_equal :no_content, client.delete_tags([id])
62
- end
63
- end
@@ -1,57 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientTimersTest < ClientTest
4
- def test_get_timers
5
- expect_request(:get, "#{base_url}/timers").with(auth_header).to_return(json_array_response)
6
-
7
- assert_equal [], client.get_timers
8
- end
9
-
10
- def test_get_timers_encodes_params
11
- expect_request(:get, "#{base_url}/timers?billable=true")
12
-
13
- client.get_timers(billable: true)
14
- end
15
-
16
- def test_get_timers_encodes_ids
17
- expect_request(:get, "#{base_url}/timers?projects=123,456,789")
18
-
19
- client.get_timers(projects: ids)
20
- end
21
-
22
- def test_get_timer
23
- expect_request(:get, "#{base_url}/projects/#{id}/timer").with(auth_header).to_return(json_response)
24
-
25
- assert_instance_of Noko::Record, client.get_timer(id)
26
- end
27
-
28
- def test_update_timer
29
- expect_request(:put, "#{base_url}/projects/#{id}/timer").with(json_request).to_return(json_response)
30
-
31
- assert_instance_of Noko::Record, client.update_timer(id, description: 'Notes go here')
32
- end
33
-
34
- def test_start_timer
35
- expect_request(:put, "#{base_url}/projects/#{id}/timer/start").with(auth_header).to_return(json_response)
36
-
37
- assert_instance_of Noko::Record, client.start_timer(id)
38
- end
39
-
40
- def test_pause_timer
41
- expect_request(:put, "#{base_url}/projects/#{id}/timer/pause").with(auth_header).to_return(json_response)
42
-
43
- assert_instance_of Noko::Record, client.pause_timer(id)
44
- end
45
-
46
- def test_log_timer
47
- expect_request(:put, "#{base_url}/projects/#{id}/timer/log").with(auth_header).to_return(status: 204)
48
-
49
- assert_equal :no_content, client.log_timer(id, description: 'Serious #development work')
50
- end
51
-
52
- def test_discard_timer
53
- expect_request(:delete, "#{base_url}/projects/#{id}/timer").with(auth_header).to_return(status: 204)
54
-
55
- assert_equal :no_content, client.discard_timer(id)
56
- end
57
- end
@@ -1,75 +0,0 @@
1
- require_relative '../client_test'
2
-
3
- class ClientUsersTest < ClientTest
4
- def test_get_users
5
- expect_request(:get, "#{base_url}/users").with(auth_header).to_return(json_array_response)
6
-
7
- assert_equal [], client.get_users
8
- end
9
-
10
- def test_get_users_encodes_params
11
- expect_request(:get, "#{base_url}/users?name=John")
12
-
13
- client.get_users(name: 'John')
14
- end
15
-
16
- def test_get_user
17
- expect_request(:get, "#{base_url}/users/#{id}").with(auth_header).to_return(json_response)
18
-
19
- assert_instance_of Noko::Record, client.get_user(id)
20
- end
21
-
22
- def test_get_user_entries
23
- expect_request(:get, "#{base_url}/users/#{id}/entries").with(auth_header).to_return(json_array_response)
24
-
25
- assert_equal [], client.get_user_entries(id)
26
- end
27
-
28
- def test_get_user_entries_encodes_params
29
- expect_request(:get, "#{base_url}/users/#{id}/entries?billable=true")
30
-
31
- client.get_user_entries(id, billable: true)
32
- end
33
-
34
- def test_get_user_expenses
35
- expect_request(:get, "#{base_url}/users/#{id}/expenses").with(auth_header).to_return(json_array_response)
36
-
37
- assert_equal [], client.get_user_expenses(id)
38
- end
39
-
40
- def test_get_user_expenses_encodes_params
41
- expect_request(:get, "#{base_url}/users/#{id}/expenses?invoiced=true")
42
-
43
- client.get_user_expenses(id, invoiced: true)
44
- end
45
-
46
- def test_create_user
47
- expect_request(:post, "#{base_url}/users").with(json_request).to_return(json_response.merge(status: 201))
48
-
49
- assert_instance_of Noko::Record, client.create_user(email: 'alice@example.com')
50
- end
51
-
52
- def test_update_user
53
- expect_request(:put, "#{base_url}/users/#{id}").with(json_request).to_return(json_response)
54
-
55
- assert_instance_of Noko::Record, client.update_user(id, role: 'leader')
56
- end
57
-
58
- def test_delete_user
59
- expect_request(:delete, "#{base_url}/users/#{id}").with(auth_header).to_return(status: 204)
60
-
61
- assert_equal :no_content, client.delete_user(id)
62
- end
63
-
64
- def test_reactivate_user
65
- expect_request(:put, "#{base_url}/users/#{id}/activate").with(auth_header).to_return(status: 204)
66
-
67
- assert_equal :no_content, client.reactivate_user(id)
68
- end
69
-
70
- def test_deactivate_user
71
- expect_request(:put, "#{base_url}/users/#{id}/deactivate").with(auth_header).to_return(status: 204)
72
-
73
- assert_equal :no_content, client.deactivate_user(id)
74
- end
75
- end
@@ -1,59 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'webmock/minitest'
3
- require 'noko'
4
-
5
- class ClientTest < Minitest::Test
6
- def token
7
- 'token-xxx'
8
- end
9
-
10
- def id
11
- 123
12
- end
13
-
14
- def ids
15
- %w[123 456 789]
16
- end
17
-
18
- def base_url
19
- 'https://api.nokotime.com/v2'
20
- end
21
-
22
- def auth_header
23
- {headers: {'X-NokoToken' => token}}
24
- end
25
-
26
- def json_request(body=/\A{.+}\z/)
27
- {headers: {'X-NokoToken' => token, 'Content-Type' => 'application/json'}, body: body}
28
- end
29
-
30
- def json_response_headers
31
- {'Content-Type' => 'application/json;charset=utf-8'}
32
- end
33
-
34
- def json_response
35
- {headers: json_response_headers, body: '{}'}
36
- end
37
-
38
- def json_array_response
39
- {headers: json_response_headers, body: '[]'}
40
- end
41
-
42
- attr_accessor :client
43
- attr_accessor :request
44
-
45
- def setup
46
- WebMock.reset!
47
-
48
- self.client = Noko::Client.new(token: token)
49
- self.request = nil
50
- end
51
-
52
- def teardown
53
- assert_requested(request) if request
54
- end
55
-
56
- def expect_request(*args)
57
- self.request = stub_request(*args)
58
- end
59
- end
@@ -1,28 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'noko'
3
-
4
- class RecordTest < Minitest::Test
5
- def id
6
- 123
7
- end
8
-
9
- attr_accessor :record
10
-
11
- def setup
12
- self.record = Noko::Record.new(project_id: id)
13
- end
14
-
15
- def test_square_brackets_returns_attribute_values
16
- assert_equal id, record[:project_id]
17
- end
18
-
19
- def test_method_missing_returns_attribute_values
20
- assert_equal id, record.project_id
21
- end
22
-
23
- def test_to_h_returns_attributes_hash
24
- attributes = {project_id: id}
25
-
26
- assert_equal attributes, record.to_h
27
- end
28
- end