sfkb 0.1.2 → 0.1.3

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: 74bcb08c5677a0a76c460619f7ad20114454024382d3b8ddf45aeaf3194a33c6
4
- data.tar.gz: 6b2f4b46fd09d98f68a29a5be7dba289dff17e45c6d2869aabfa496016fe4885
3
+ metadata.gz: 70f109dc8cfd8cc42fb9de11011ef9d8686e20e8b1818221bd8621ff716b095f
4
+ data.tar.gz: 6c2e478a2c2a2e680dfa90bcfa225d0324cdeb324c3d0926dabf94cb27c9d05c
5
5
  SHA512:
6
- metadata.gz: d5a8f43459e81bd9f0486ec67a6dbf7f846dd74571a6b6877df0d0dd4c933732df57ec493cc322ce6cd491a7c7077bab92face507b7f528e7c50ee7f10cabfbb
7
- data.tar.gz: 7dd1ba208860dd203abd3c9310b1d3dca7b703e7ab58310d15fcd2a329fc659f381355f5a32ffc890a658d66d42c54c2489d1c481793971914fe51c7826918f7
6
+ metadata.gz: 49fefbe358e7264e0aa185843cc4c869f6676991698e7311824f7d9c42c1a0672aa091b008a5123ff67c6593d614e1f0e6954969db73bc6a0448427c33ce492b
7
+ data.tar.gz: 9c79a3ddfd6a7e3538baf6fe1dd9e1867de24f0767a1709b715ca50d4081b2c3349adcedb043e3d0bce3a68eed28dd4d860b7a20a5e6ba8d2c1b084ca358d789
data/README.md CHANGED
@@ -5,7 +5,12 @@ SalesForce Knowledge Base
5
5
  A Ruby library that extends [Restforce][] to provide convenient access to
6
6
  Articles and ArticlesVersions in the Salesforce Knowledge Base.
7
7
 
8
- [![Build Status](https://travis-ci.org/bjjb/sfkb.svg?branch=master)](https://travis-ci.org/bjjb/sfkb)
8
+ [![Build Status](http://img.shields.io/travis/bjjb/sfkb.svg?style=flat-square)](https://travis-ci.org/bjjb/sfkb)
9
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/8e717aedee6a4e956683/test_coverage)](https://codeclimate.com/github/bjjb/sfkb/test_coverage)
10
+ [![Maintainability](https://api.codeclimate.com/v1/badges/8e717aedee6a4e956683/maintainability)](https://codeclimate.com/github/bjjb/sfkb/maintainability)
11
+ [![Dependency Status](http://img.shields.io/gemnasium/bjjb/sfkb.svg?style=flat-square)](https://gemnasium.com/bjjb/sfkb)
12
+ [![Gem Version](http://img.shields.io/gem/v/sfkb.svg?style=flat-square)](https://rubygems.org/gems/sfkb)
13
+ [![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](http://bjjb.mit-license.org)
9
14
 
10
15
  ## Requirements
11
16
 
@@ -32,13 +37,14 @@ instantiating a `SFKB::Client`.
32
37
  For example, here's how to print the titles of the master versions of the
33
38
  first 10 documents:
34
39
 
35
- ```
40
+ ```ruby
36
41
  require 'sfkb'
37
42
  SFKB.new.articles.take(10).each { |a| puts a.OnlineMasterVersion.data.Title }
38
43
  ```
39
44
 
40
45
  Here's how to list the titles of every translation of every draft article:
41
- ```
46
+
47
+ ```ruby
42
48
  sf = SFKB.new
43
49
  sf.articles.select(:hasTranslations?) do |a|
44
50
  sf.translations(a, 'Draft').each do |t|
@@ -24,16 +24,30 @@ module SFKB
24
24
  def autodefine(object)
25
25
  return unless object.respond_to?(:additionalInformation)
26
26
  return unless info = object.additionalInformation
27
- info.each do |k, v|
28
- if [true, false].include?(v)
29
- define_predicate(object, k, v)
30
- elsif k.to_s == 'data'
31
- define_link(object, :data, v)
32
- elsif k.to_s == 'urls'
33
- define_links(object, v) { |o| autodefine(o) }
34
- end
27
+ autodefine_data(object, info[:data])
28
+ autodefine_links(object, info[:urls])
29
+ autodefine_predicates(object, info)
30
+ object
31
+ end
32
+
33
+ def autodefine_predicates(object, predicates)
34
+ predicates.each do |k, v|
35
+ next unless [true, false].include?(v)
36
+ define_predicate(object, k, v)
35
37
  end
36
38
  object
37
39
  end
40
+
41
+ def autodefine_data(object, data)
42
+ return object if data.nil?
43
+ define_link(object, :data, data)
44
+ object
45
+ end
46
+
47
+ def autodefine_links(object, urls)
48
+ return if urls.nil?
49
+ define_links(object, urls) { |o| autodefine(o) }
50
+ object
51
+ end
38
52
  end
39
53
  end
@@ -2,7 +2,10 @@ module SFKB
2
2
  # Some REST helpers
3
3
  module REST
4
4
  # Used to interpolate variables into REST endpoint URIs
5
- @@placeholder = /[<{](.+?)[>}]/
5
+ @@placeholder = /[<{](.+?)[>}]/.freeze
6
+
7
+ # Used to identify URLs; %s should be the api_version
8
+ @@url_pattern = '/services/data/v%s'.freeze
6
9
 
7
10
  # { a: :b }.inject({}, &@@stringify) #=> { 'a' => :b }
8
11
  @@stringify = lambda do |collector, kv|
@@ -27,24 +30,44 @@ module SFKB
27
30
  [path, params].reject(&:nil?).reject(&:empty?).join('?')
28
31
  end
29
32
 
33
+ # The starting URL
34
+ def services_url
35
+ @@url_pattern % options[:api_version]
36
+ end
37
+
30
38
  # The REST API starts here
31
39
  def index
32
- endpoint("/services/data/v#{options[:api_version]}") do |k, v|
33
- endpoint(v) { |k, v| endpoint(v) }
34
- end
35
- end
36
-
37
- # Fetches the object at url, and extends it with methods
38
- def endpoint(url)
39
- get(url).body.tap do |o|
40
- o.each do |k, v|
41
- o.define_singleton_method(k) do
42
- ivar = :"@#{k}"
43
- return instance_variable_get(ivar) if instance_variable_defined?(ivar)
44
- instance_variable_set(ivar, block_given? ? yield(k, v) : v)
45
- end
46
- end
47
- end
40
+ endpoint(get(services_url).body)
41
+ end
42
+
43
+ # endpoint takes a map, and for eack key/value pair, adds a singleton
44
+ # method to the map which will fetch that resource (if it looks like a
45
+ # URL).
46
+ def endpoint(map)
47
+ map.each { |k, v| apply_endpoint(map, k, v) }
48
+ map
49
+ end
50
+
51
+ # applies an endpoint to obj, named k, which fetches v and makes it an
52
+ # endpoint if it looks like a URL
53
+ def apply_endpoint(obj, k, v)
54
+ α = -> { endpoint(get(v).body) }
55
+ β = -> { v }
56
+ λ = url?(v) ? -> { α.call } : -> { β.call }
57
+ obj.define_singleton_method(k, &λ) if url?(v)
58
+ obj
59
+ end
60
+
61
+ # Identifies a valid URL for this REST instance
62
+ def url?(string)
63
+ return false unless string.to_s =~ url_pattern
64
+ return false if string.to_s =~ @@placeholder
65
+ true
66
+ end
67
+
68
+ # Identifies a valid URL for this REST instance
69
+ def url_pattern
70
+ %r{#{services_url}}
48
71
  end
49
72
 
50
73
  extend self
@@ -2,56 +2,44 @@ require 'test_helper'
2
2
  require 'sfkb/rest'
3
3
 
4
4
  describe SFKB::REST do
5
- let(:klass) { Class.new(Minitest::Mock) { include SFKB::REST } }
6
- let(:subject) { klass.new }
5
+ include SFKB::REST
6
+ let(:options) { { api_version: 'X' } }
7
7
  let(:response) { |x| OpenStruct.new(body: x) }
8
8
 
9
9
  describe 'url' do
10
10
  it 'joins paths to params amd substitutes vars' do
11
- assert_equal '/foo', subject.url('/foo')
12
- assert_equal '/foo?x=1', subject.url('/foo', x: 1)
13
- assert_equal '/foo?x=1&y=2', subject.url('/foo', x: 1, y: 2)
11
+ assert_equal '/foo', url('/foo')
12
+ assert_equal '/foo?x=1', url('/foo', x: 1)
13
+ assert_equal '/foo?x=1&y=2', url('/foo', x: 1, y: 2)
14
14
  end
15
15
 
16
16
  it 'substitutes vars' do
17
- assert_equal '/foo/1/2', subject.url('/foo/<x>/<y>', x: 1, y: 2)
18
- assert_equal '/foo/1?y=2', subject.url('/foo/<x>', x: 1, y: 2)
19
- assert_equal '/foo/1?b=2&b=3&c=4',
20
- subject.url('/foo/<a>', a: 1, b: %w(2 3), c: 4)
21
- assert_raises { subject.url('/foo/<blah>') }
17
+ assert_equal '/foo/1/2', url('/foo/<x>/<y>', x: 1, y: 2)
18
+ assert_equal '/foo/1?y=2', url('/foo/<x>', x: 1, y: 2)
19
+ assert_equal '/a/1?b=2&b=3&c=4', url('/a/<a>', a: 1, b: %w(2 3), c: 4)
20
+ assert_raises { url('/x/<blah>') }
22
21
  end
23
22
  end
24
23
 
25
24
  describe 'index' do
26
- let(:index) { subject.index }
27
-
28
- before do
29
- subject.expect(:options, { api_version: 'X' })
30
- subject.expect(:get, OpenStruct.new(body: { a: '/a' }), ['/services/data/vX'])
31
- end
32
-
33
- it 'looks up the index for the current api version' do
34
- index
35
- subject.verify
36
- end
37
-
38
- it 'is a whatever was returned, hopefully a hash' do
39
- assert_equal({ a: '/a' }, index)
40
- end
41
-
42
- it 'adds endpoints for the url values of the hash' do
43
- subject.expect(:get, OpenStruct.new(body: { b: '/b', c: '/c' }), ['/a'])
44
- assert_equal({ b: '/b', c: '/c'}, index.a)
25
+ let(:services) { { 'a' => '/services/data/vX/a', 'b' => { foo: 123 } } }
26
+ let(:responses) do
27
+ {
28
+ '/services/data/vX' => services,
29
+ '/services/data/vX/a' => { 'b' => '/services/data/vX/b' },
30
+ '/services/data/vX/b' => { 'c' => '/services/data/vX/c' },
31
+ '/services/data/vX/c' => OpenStruct.new('d' => 'You got me.')
32
+ }
45
33
  end
46
-
47
- it 'adds endpoints for the subresource' do
48
- subject.expect(:get, OpenStruct.new(body: { b: '/b', c: '/c' }), ['/a'])
49
- subject.expect(:get, OpenStruct.new(body: { d: '/d', e: '/e' }), ['/b'])
50
- subject.expect(:get, OpenStruct.new(body: { f: '/f', g: '/g' }), ['/c'])
51
- assert_equal '/d', index.a.b.d
52
- assert_equal '/e', index.a.b.e
53
- assert_equal '/f', index.a.c.f
54
- assert_equal '/g', index.a.c.g
34
+ define_method(:lookup) { |url| responses.fetch(url) }
35
+ define_method(:get) { |url| OpenStruct.new(body: lookup(url)) }
36
+ it 'gets an endpoint' do
37
+ assert_equal services, index
38
+ assert_respond_to index, :a
39
+ assert_respond_to index.a, :b
40
+ assert_respond_to index.a.b, :c
41
+ assert_respond_to index.a.b.c, :d
42
+ assert_equal 'You got me.', index.a.b.c.d
55
43
  end
56
44
  end
57
45
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfkb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - JJ Buckley
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-15 00:00:00.000000000 Z
11
+ date: 2018-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.12'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.12'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: restforce
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,20 +108,6 @@ dependencies:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
110
  version: '5.11'
97
- - !ruby/object:Gem::Dependency
98
- name: faraday
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '0.12'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '0.12'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: vcr
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -265,7 +265,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
265
265
  version: '0'
266
266
  requirements: []
267
267
  rubyforge_project:
268
- rubygems_version: 2.7.3
268
+ rubygems_version: 2.7.6
269
269
  signing_key:
270
270
  specification_version: 4
271
271
  summary: SalesForce Knowledge Base helper library