cobot_client 3.1.0 → 5.0.0

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
- SHA1:
3
- metadata.gz: 1e33543f24073fe4a3c349c97874dd846533bea1
4
- data.tar.gz: 3c9818a5755292537b3fb8fbf0fa566c780dc382
2
+ SHA256:
3
+ metadata.gz: de6d346613c7908a049ea953b3c5eb0eef38ae647246ad9d1bb41d863f7cc104
4
+ data.tar.gz: aaa52ccc3005e510d3a63ce9cf736a60ed21ba889c42c7ecaee1e3854a32bb3a
5
5
  SHA512:
6
- metadata.gz: afc679f1b10dd8a731a46cb43e97f0858a3e8827c87b6293308597ec2edaa8af6883917e90464e8056533094ee4141c77098667137ed787c7224b2d3860ab0c9
7
- data.tar.gz: 7923351ded252310bed7277ba5d93a65021f261cb9bcc0c3f8710d1bd909697360bd596e0a423ded6d1b62097087eef2691a951eb34812050048c658ad417170
6
+ metadata.gz: 14c6d70b7fef964d12e23f28745bcf33dd4932c6381d2293475e77783f78338357430cc7e0ca98d70f726f826b941f9e4193b107900677f3bca444f24150321c
7
+ data.tar.gz: 611a43d02024876126f81d171ec86cc9426ba858767eb2385e435774bab2bbb4fdb5f8328dbc8bd4dace0451054d3f3bc48ad241188b66b31cf2ec584fb74a44
data/CHANGELOG.md CHANGED
@@ -1,8 +1,15 @@
1
+ # 5.0.0
2
+
3
+ Bump oauth2 dependency to ~>2.0.
4
+
5
+ # 4.0.0
6
+
7
+ - changed navigation link service to add missing links and return all if there are links already (before it would do nothing if there were any links already)
1
8
 
2
9
  # 3.1.0
3
10
 
4
- * adds user_edtiable attribute to navigation links
11
+ - adds user_edtiable attribute to navigation links
5
12
 
6
13
  # 3.0.0
7
14
 
8
- * bumps rest-client to ~2.0.1, which results in CobotClient::ResourceNotFound to be renamed to CobotClient::NotFound (FrauBienenstich)
15
+ - bumps rest-client to ~2.0.1, which results in CobotClient::ResourceNotFound to be renamed to CobotClient::NotFound (FrauBienenstich)
data/README.md CHANGED
@@ -24,9 +24,11 @@ Or install it yourself as:
24
24
 
25
25
  You can install links to your app into the navigation on Cobot. When users click the link an iframe pointing to the given `iframe_url` will be shown.
26
26
 
27
- client = CobotClient::ApiClient.new <access token>
28
- CobotClient::NavigationLinkService.new(client, 'co-up').install_links [
29
- CobotClient::NavigationLink.new(section: 'admin/manage', label: 'My App', iframe_url: 'http://example.com')]
27
+ ```ruby
28
+ client = CobotClient::ApiClient.new '<access token>'
29
+ CobotClient::NavigationLinkService.new(client, 'co-up').install_links [
30
+ CobotClient::NavigationLink.new(section: 'admin/manage', label: 'My App', iframe_url: 'http://example.com')]
31
+ ```
30
32
 
31
33
  ### Setting up automatic iframe resizing
32
34
 
@@ -48,25 +50,61 @@ When you display layers in the iframe that are positioned relative to the window
48
50
 
49
51
  There is a module `CobotClient::UrlHelper`. After you include it you can call `cobot_url`. Examples:
50
52
 
51
- cobot_url('co-up') # => 'https://co-up.cobot.me/'
52
- cobot_url('co-up', '/api/user') # => 'https://co-up.cobot.me/api/user'
53
- cobot_url('co-up', '/api/user', params: {x: 'y'}) # => 'https://co-up.cobot.me/api/user?x=y'
53
+ ```ruby
54
+ cobot_url('co-up') # => 'https://co-up.cobot.me/'
55
+ cobot_url('co-up', '/api/user') # => 'https://co-up.cobot.me/api/user'
56
+ cobot_url('co-up', '/api/user', params: {x: 'y'}) # => 'https://co-up.cobot.me/api/user?x=y'
57
+ ```
54
58
 
55
59
  ### Calling the API
56
60
 
57
61
  At the moment there are only a few high-level methods. For more details see the specs.
58
62
 
59
- client = CobotClient::ApiClient.new('<access token>')
60
- client.list_resources('<subdomain>')
63
+ ```ruby
64
+ client = CobotClient::ApiClient.new('<access token>')
65
+ client.list_resources('<subdomain>')
66
+ ```
61
67
 
62
68
  For everything else you can use the low-level get/post/put/delete metods:
63
69
 
64
- client.get 'www', '/user'
65
- client.post 'my-subdomain', '/users', {"email": "joe@doe.com"}
70
+ ```ruby
71
+ client.get 'www', '/user'
72
+ client.post 'my-subdomain', '/users', {"email": "joe@doe.com"}
73
+ ```
66
74
 
67
75
  You can also pass a URL instead of subdomain/path:
68
76
 
69
- client.get 'https://www/cobot.me/user'
77
+ ```ruby
78
+ client.get 'https://www/cobot.me/user'
79
+ ```
80
+
81
+ ### Error handling
82
+
83
+ In case of Cobot returning a 4xx or 5xx status code, the `ApiClient` throws an exception that is a subclass of `CobotClient::Exception`.
84
+
85
+ The most common exceptions encountered are `CobotClient::NotFound` (404), `CobotClient::Forbidden` (403), `CobotClient::UnprocesseableEntity` (422) and `CobotClient::TooManyRequests` (429).
86
+
87
+ To access the error message contained in the response, rescue the exception and `http_body` on it:
88
+
89
+ ```ruby
90
+ begin
91
+ client = CobotClient::ApiClient.new('<access token>')
92
+ client.get('www', '/user')
93
+ rescue CobotClient::Exception => e
94
+ puts JSON.parse(e.http_body)
95
+ end
96
+ ```
97
+
98
+ To access response headers, for example the `Retry-After` header of a rate-limited request:
99
+
100
+ ```ruby
101
+ begin
102
+ client = CobotClient::ApiClient.new('<access token>')
103
+ client.get('www', '/user')
104
+ rescue CobotClient::TooManyRequests => e
105
+ puts e.response.headers[:retry_after].to_i
106
+ end
107
+ ```
70
108
 
71
109
  ## Contributing
72
110
 
data/cobot_client.gemspec CHANGED
@@ -1,25 +1,26 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/cobot_client/version', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('lib/cobot_client/version', __dir__)
3
4
 
4
5
  Gem::Specification.new do |gem|
5
- gem.authors = ["Alexander Lang"]
6
- gem.email = ["alex@cobot.me"]
7
- gem.description = %q{Client for the Cobot API plus helpers}
8
- gem.summary = %q{Client for the Cobot API plus helpers}
9
- gem.homepage = "http://github.com/cobot/cobot_client"
6
+ gem.authors = ['Alexander Lang']
7
+ gem.email = ['alex@cobot.me']
8
+ gem.description = 'Client for the Cobot API plus helpers'
9
+ gem.summary = 'Client for the Cobot API plus helpers'
10
+ gem.homepage = 'http://github.com/cobot/cobot_client'
10
11
  gem.license = 'MIT'
11
12
 
12
- gem.files = `git ls-files`.split($\)
13
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
14
15
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
- gem.name = "cobot_client"
16
- gem.require_paths = ["lib"]
16
+ gem.name = 'cobot_client'
17
+ gem.require_paths = ['lib']
17
18
  gem.version = CobotClient::VERSION
18
19
 
19
20
  gem.add_dependency 'virtus', '~>1.0'
20
- gem.add_dependency 'oauth2', '~>1.0'
21
+ gem.add_dependency 'oauth2', '~>2.0'
21
22
  gem.add_dependency 'rest-client', '~>2.0.1'
22
23
  gem.add_dependency 'json', '~>2.0'
23
24
  gem.add_development_dependency 'rspec', '~>3.0'
24
- gem.add_development_dependency 'rake', '~>10.0'
25
+ gem.add_development_dependency 'rake', '~>12.3.3'
25
26
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rest_client'
2
4
  require 'json'
3
5
 
@@ -14,22 +16,6 @@ module CobotClient
14
16
  @access_token = access_token
15
17
  end
16
18
 
17
- def get_resources(subdomain)
18
- get subdomain, '/resources'
19
- end
20
-
21
- def create_booking(subdomain, resource_id, attributes)
22
- post subdomain, "/resources/#{resource_id}/bookings", attributes
23
- end
24
-
25
- def update_booking(subdomain, id, attributes)
26
- put subdomain, "/bookings/#{id}", attributes
27
- end
28
-
29
- def delete_booking(subdomain, id)
30
- delete subdomain, "/bookings/#{id}"
31
- end
32
-
33
19
  # args: either a full URL or subdomain, path, plus a body as hash
34
20
  def post(*args)
35
21
  request :post, *args
@@ -51,13 +37,15 @@ module CobotClient
51
37
  rewrap_errors do
52
38
  RestClient.get(
53
39
  build_url(url || subdomain, path, params),
54
- headers).body
55
- end, symbolize_names: true)
40
+ headers
41
+ ).body
42
+ end, symbolize_names: true
43
+ )
56
44
  end
57
45
 
58
46
  # args: either a full URL or subdomain, path
59
47
  def delete(*args)
60
- url, subdomain, path, _ = parse_args(*args)
48
+ url, subdomain, path, = parse_args(*args)
61
49
  rewrap_errors do
62
50
  RestClient.delete(build_url(url || subdomain, path), headers)
63
51
  end
@@ -69,9 +57,9 @@ module CobotClient
69
57
  url, subdomain, path, body = parse_args(*args)
70
58
  rewrap_errors do
71
59
  response = RestClient.public_send(method,
72
- build_url(url || subdomain, path),
73
- body.to_json,
74
- headers.merge(content_type_header))
60
+ build_url(url || subdomain, path),
61
+ body.to_json,
62
+ headers.merge(content_type_header))
75
63
  JSON.parse response.body, symbolize_names: true unless response.code == 204
76
64
  end
77
65
  end
@@ -79,7 +67,7 @@ module CobotClient
79
67
  def rewrap_errors(&block)
80
68
  retry_errors(&block)
81
69
  rescue RestClient::Exception => e
82
- fail CobotClient::Exceptions::EXCEPTIONS_MAP[e.class].new(e.response)
70
+ raise CobotClient::Exceptions::EXCEPTIONS_MAP[e.class], e.response
83
71
  end
84
72
 
85
73
  def retry_errors
@@ -98,11 +86,11 @@ module CobotClient
98
86
  end
99
87
 
100
88
  def parse_args(*args)
101
- if args.size == 3 || (args.size == 2 && args[0].match(%r{https?://}))
102
- params = args.pop
103
- else
104
- params = {}
105
- end
89
+ params = if args.size == 3 || (args.size == 2 && args[0].match(%r{https?://}))
90
+ args.pop
91
+ else
92
+ {}
93
+ end
106
94
  if args.size == 1
107
95
  url = args[0]
108
96
  path = nil
@@ -120,13 +108,13 @@ module CobotClient
120
108
  cobot_url(subdomain_or_url, "/api#{path}", params: params)
121
109
  else
122
110
  uri = URI.parse(subdomain_or_url)
123
- uri.query = URI.encode_www_form(params) if params && params.any?
111
+ uri.query = URI.encode_www_form(params) if params&.any?
124
112
  uri.to_s
125
113
  end
126
114
  end
127
115
 
128
116
  def content_type_header
129
- {'Content-Type' => 'application/json'}
117
+ { 'Content-Type' => 'application/json' }
130
118
  end
131
119
 
132
120
  def headers
@@ -16,18 +16,22 @@ module CobotClient
16
16
  #
17
17
  # Returns the links as `[CobotClient::NavigationLink]`
18
18
  def install_links(new_links)
19
- if (links = get_links).empty?
20
- new_links.each do |link|
21
- links << create_link(link)
19
+ existing_links = get_links
20
+ missing_links = new_links.reject do |new_link|
21
+ existing_links.find do |existing_link|
22
+ existing_link.section == new_link.section && existing_link.iframe_url == new_link.iframe_url
22
23
  end
23
24
  end
24
- links
25
+ created_links = missing_links.map do |link|
26
+ create_link(link)
27
+ end
28
+ existing_links + created_links
25
29
  end
26
30
 
27
31
  private
28
32
 
29
33
  def get_links
30
- @api_client.get(@subdomain, "/navigation_links").map do |attributes|
34
+ @api_client.get(@subdomain, '/navigation_links').map do |attributes|
31
35
  NavigationLink.new attributes
32
36
  end
33
37
  end
@@ -37,8 +41,7 @@ module CobotClient
37
41
  section: link.section,
38
42
  label: link.label,
39
43
  iframe_url: link.iframe_url,
40
- user_editable: link.user_editable
41
- )
44
+ user_editable: link.user_editable)
42
45
 
43
46
  NavigationLink.new response
44
47
  end
@@ -1,3 +1,3 @@
1
1
  module CobotClient
2
- VERSION = '3.1.0'
2
+ VERSION = '5.0.0'
3
3
  end
data/lib/cobot_client.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "cobot_client/version"
1
+ require 'cobot_client/version'
2
2
  require 'cobot_client/engine' if defined?(Rails)
3
3
  require 'cobot_client/exceptions'
4
4
 
@@ -7,5 +7,4 @@ module CobotClient
7
7
  autoload :NavigationLink, 'cobot_client/navigation_link'
8
8
  autoload :NavigationLinkService, 'cobot_client/navigation_link_service'
9
9
  autoload :UrlHelper, 'cobot_client/url_helper'
10
- autoload :XdmHelper, 'cobot_client/xdm_helper'
11
10
  end
@@ -9,71 +9,6 @@ describe CobotClient::ApiClient do
9
9
  CobotClient::ApiClient.retry_time = 0
10
10
  end
11
11
 
12
- context 'listing resources' do
13
- it 'calls rest client' do
14
- expect(RestClient).to receive(:get).with('https://co-up.cobot.me/api/resources',
15
- hash_including('Authorization' => 'Bearer token-123')) { default_response }
16
-
17
- api_client.get_resources 'co-up'
18
- end
19
-
20
- it 'returns the json' do
21
- allow(RestClient).to receive(:get) { double(:response, body: [{id: 'resource-1'}].to_json) }
22
-
23
- resources = api_client.get_resources 'co-up'
24
-
25
- expect(resources).to eql([{id: 'resource-1'}])
26
- end
27
- end
28
-
29
- context 'creating a booking' do
30
- it 'calls rest client' do
31
- expect(RestClient).to receive(:post).with(
32
- 'https://co-up.cobot.me/api/resources/res-1/bookings',
33
- {title: 'meeting'}.to_json,
34
- hash_including('Authorization' => 'Bearer token-123')) { default_response }
35
-
36
- api_client.create_booking 'co-up', 'res-1', title: 'meeting'
37
- end
38
-
39
- it 'returns the json' do
40
- allow(RestClient).to receive(:post) { double(:response,
41
- code: 201, body: {title: 'meeting'}.to_json) }
42
-
43
- booking = api_client.create_booking 'co-up', 'res-1', title: 'meeting'
44
-
45
- expect(booking).to eql({title: 'meeting'})
46
- end
47
- end
48
-
49
- context 'updating a booking' do
50
- it 'calls rest client' do
51
- expect(RestClient).to receive(:put).with('https://co-up.cobot.me/api/bookings/booking-1',
52
- {title: 'meeting'}.to_json,
53
- hash_including('Authorization' => 'Bearer token-123')) { default_response }
54
-
55
- api_client.update_booking 'co-up', 'booking-1', title: 'meeting'
56
- end
57
-
58
- it 'returns the json' do
59
- allow(RestClient).to receive(:put) { double(:response, code: 200,
60
- body: {title: 'meeting'}.to_json) }
61
-
62
- booking = api_client.update_booking 'co-up', 'booking-1', title: 'meeting'
63
-
64
- expect(booking).to eql({title: 'meeting'})
65
- end
66
- end
67
-
68
- context 'deleting a booking' do
69
- it 'calls rest client' do
70
- expect(RestClient).to receive(:delete).with('https://co-up.cobot.me/api/bookings/booking-1',
71
- hash_including('Authorization' => 'Bearer token-123')) { default_response }
72
-
73
- api_client.delete_booking 'co-up', 'booking-1'
74
- end
75
- end
76
-
77
12
  context '#put' do
78
13
  it 'calls rest client' do
79
14
  expect(RestClient).to receive(:put).with(
@@ -5,19 +5,34 @@ describe CobotClient::NavigationLinkService, '#install_links' do
5
5
  let(:api_client) { instance_double(CobotClient::ApiClient) }
6
6
 
7
7
  context 'when there are links already' do
8
+ let(:existing_link) do
9
+ instance_double(CobotClient::NavigationLink, label: 'existing link',
10
+ section: 'admin/setup', iframe_url: 'http://example.com/1').as_null_object
11
+ end
12
+ let(:new_link) do
13
+ instance_double(CobotClient::NavigationLink, label: 'new link',
14
+ section: 'admin/setup', iframe_url: 'http://example.com/2').as_null_object
15
+ end
16
+
8
17
  before(:each) do
9
18
  allow(api_client).to receive(:get)
10
- .with('co-up', '/navigation_links') { [{label: 'test link'}] }
19
+ .with('co-up', '/navigation_links')
20
+ .and_return([{label: 'existing link',
21
+ section: 'admin/setup', iframe_url: 'http://example.com/1'}])
11
22
  end
12
23
 
13
- it 'installs no links' do
14
- expect(api_client).to_not receive(:post)
24
+ it 'installs the missing links' do
25
+ expect(api_client).to receive(:post)
26
+ .with('co-up', '/navigation_links', hash_including(label: 'new link',
27
+ section: 'admin/setup', iframe_url: 'http://example.com/2')) { {} }
15
28
 
16
- service.install_links [double(:link)]
29
+ service.install_links [existing_link, new_link]
17
30
  end
18
31
 
19
- it 'returns the links' do
20
- expect(service.install_links([double(:link)]).map(&:label)).to eql(['test link'])
32
+ it 'returns all the links' do
33
+ allow(api_client).to receive(:post) { {label: 'new link'} }
34
+
35
+ expect(service.install_links([existing_link, new_link]).map(&:label)).to eql(['existing link', 'new link'])
21
36
  end
22
37
  end
23
38
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cobot_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Lang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-21 00:00:00.000000000 Z
11
+ date: 2022-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: virtus
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.0'
33
+ version: '2.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.0'
40
+ version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rest-client
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '10.0'
89
+ version: 12.3.3
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '10.0'
96
+ version: 12.3.3
97
97
  description: Client for the Cobot API plus helpers
98
98
  email:
99
99
  - alex@cobot.me
@@ -141,8 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  - !ruby/object:Gem::Version
142
142
  version: '0'
143
143
  requirements: []
144
- rubyforge_project:
145
- rubygems_version: 2.6.13
144
+ rubygems_version: 3.1.6
146
145
  signing_key:
147
146
  specification_version: 4
148
147
  summary: Client for the Cobot API plus helpers