ecoportal-api 0.3.8 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +11 -3
  3. data/.yardopts +10 -0
  4. data/Gemfile.lock +10 -5
  5. data/Rakefile +22 -1
  6. data/ecoportal-api.gemspec +6 -4
  7. data/lib/ecoportal/api/common.rb +7 -4
  8. data/lib/ecoportal/api/common/base_class.rb +29 -0
  9. data/lib/ecoportal/api/common/base_model.rb +89 -20
  10. data/lib/ecoportal/api/common/batch_operation.rb +0 -1
  11. data/lib/ecoportal/api/common/batch_response.rb +5 -0
  12. data/lib/ecoportal/api/common/client.rb +61 -1
  13. data/lib/ecoportal/api/common/doc_helpers.rb +2 -0
  14. data/lib/ecoportal/api/common/hash_diff.rb +25 -23
  15. data/lib/ecoportal/api/common/response.rb +4 -0
  16. data/lib/ecoportal/api/common/wrapped_response.rb +19 -10
  17. data/lib/ecoportal/api/internal.rb +17 -20
  18. data/lib/ecoportal/api/internal/account.rb +23 -16
  19. data/lib/ecoportal/api/internal/login_provider.rb +1 -1
  20. data/lib/ecoportal/api/internal/login_providers.rb +10 -0
  21. data/lib/ecoportal/api/internal/people.rb +3 -8
  22. data/lib/ecoportal/api/internal/permissions.rb +1 -1
  23. data/lib/ecoportal/api/internal/person.rb +18 -16
  24. data/lib/ecoportal/api/internal/person_details.rb +1 -5
  25. data/lib/ecoportal/api/internal/person_schema.rb +1 -5
  26. data/lib/ecoportal/api/internal/person_schemas.rb +2 -6
  27. data/lib/ecoportal/api/internal/policy_group.rb +1 -1
  28. data/lib/ecoportal/api/internal/policy_groups.rb +10 -1
  29. data/lib/ecoportal/api/v1.rb +27 -4
  30. data/lib/ecoportal/api/v1/people.rb +62 -25
  31. data/lib/ecoportal/api/v1/person.rb +47 -28
  32. data/lib/ecoportal/api/v1/person_details.rb +27 -13
  33. data/lib/ecoportal/api/v1/person_schema.rb +3 -6
  34. data/lib/ecoportal/api/v1/person_schemas.rb +26 -9
  35. data/lib/ecoportal/api/v1/schema_field.rb +1 -1
  36. data/lib/ecoportal/api/v1/schema_field_value.rb +2 -1
  37. data/lib/ecoportal/api/version.rb +1 -1
  38. metadata +45 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ecc5fc4d6be63751a1e9629798350e16eb2db7b0f7284efd6e77d0d18527338e
4
- data.tar.gz: 3ea7c357cd0ec82dc62065dcae78425910c0c1b7fbd74167dd9c120475086bc0
3
+ metadata.gz: 1336e02ab24ebd2ffa1ee734fa8c41ce18bb8afc892e771e38aac15c50c5ba72
4
+ data.tar.gz: 2e7ec0cb920b9972d666e3645d43ae3a503cd9425d968c24519712257751b14a
5
5
  SHA512:
6
- metadata.gz: 59c4c973da0173148a3c7f8deeaf7f439cbb0f5cbd96489bbb0c9bde30ffc715ab4e33f178c58c9d82c84bfe4c53f91ce015c8d3db951c138cfd8a861792c9a6
7
- data.tar.gz: c2597d285cf99804dc76343d02cae48f654ad3e33db954462d9731af1a67c4bb547fe1ef2fc010ce2ebfd8442831eb9c774f33a3140247365f7ad44843f76cf1
6
+ metadata.gz: a877e517ddb1ee1cd71e6e40806a685a2bcb09ee7a7c73726e4fbd1527175cdb0e84bf24e592cb56b7f3686ab1b6729931346636add41edf5b987156444f1942
7
+ data.tar.gz: d60a8dc08b2d26b28b4aeaec0bd0cf708f2a05977761554362ab848c640d5cc5f5b74b9054eddcf5f4d62f0952a24719da086bf3572ccea980c0754295d8db01
data/.gitignore CHANGED
@@ -1,11 +1,19 @@
1
+ # it's a gem, ignore the lockfile
2
+ Gemfile.lock
3
+
4
+ # build artifacts
5
+ *.gem
1
6
  /.bundle/
7
+ /vendor/bundle
8
+ /spec/reports/
9
+ /tmp/
10
+ /pkg/
11
+
12
+ # docs
2
13
  /.yardoc
3
14
  /_yardoc/
4
15
  /coverage/
5
16
  /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
17
 
10
18
  # rspec failure tracking
11
19
  .rspec_status
@@ -0,0 +1,10 @@
1
+ --readme README.md
2
+ --charset utf-8
3
+ --markup-provider=redcarpet
4
+ --markup=markdown
5
+ --no-private
6
+ --output-dir ./doc
7
+ 'lib/**/*.rb'
8
+ -
9
+ CHANGELOG.md
10
+ LICENSE
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ecoportal-api (0.3.3)
4
+ ecoportal-api (0.4.1)
5
5
  hash-polyfill (~> 0)
6
6
  http (~> 3)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- addressable (2.5.2)
11
+ addressable (2.6.0)
12
12
  public_suffix (>= 2.0.2, < 4.0)
13
13
  diff-lcs (1.3)
14
14
  domain_name (0.5.20180417)
@@ -23,8 +23,9 @@ GEM
23
23
  domain_name (~> 0.5)
24
24
  http-form_data (2.1.1)
25
25
  http_parser.rb (0.6.0)
26
- public_suffix (3.0.2)
26
+ public_suffix (3.0.3)
27
27
  rake (10.5.0)
28
+ redcarpet (3.4.0)
28
29
  rspec (3.7.0)
29
30
  rspec-core (~> 3.7.0)
30
31
  rspec-expectations (~> 3.7.0)
@@ -40,16 +41,20 @@ GEM
40
41
  rspec-support (3.7.1)
41
42
  unf (0.1.4)
42
43
  unf_ext
43
- unf_ext (0.0.7.5)
44
+ unf_ext (0.0.7.6)
45
+ yard (0.9.18)
44
46
 
45
47
  PLATFORMS
46
48
  ruby
49
+ x64-mingw32
47
50
 
48
51
  DEPENDENCIES
49
52
  bundler (~> 1.16)
50
53
  ecoportal-api!
51
54
  rake (~> 10.0)
55
+ redcarpet (~> 3.4, >= 3.4.0)
52
56
  rspec (~> 3.0)
57
+ yard (~> 0.9, >= 0.9.18)
53
58
 
54
59
  BUNDLED WITH
55
- 1.16.1
60
+ 1.17.3
data/Rakefile CHANGED
@@ -1,6 +1,27 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require "yard"
4
+ require "redcarpet"
3
5
 
6
+ desc "run the specs"
4
7
  RSpec::Core::RakeTask.new(:spec)
5
8
 
6
- task :default => :spec
9
+ desc "run rspec showing backtrace"
10
+ RSpec::Core::RakeTask.new(:spec_trace) do |task|
11
+ task.rspec_opts = ['--backtrace']
12
+ end
13
+
14
+ desc "run rspec stopping on first fail, and show backtrace"
15
+ RSpec::Core::RakeTask.new(:spec_fast) do |task|
16
+ task.rspec_opts = ['--fail-fast', '--backtrace']
17
+ end
18
+
19
+ # default task name is yard
20
+ desc "Yard: generate all the documentation"
21
+ YARD::Rake::YardocTask.new(:doc) do |t|
22
+ #t.files = ['lib/**/*.rb']
23
+ end
24
+
25
+ task :default => [:spec]
26
+ task :rspec_trace => :spec_trace
27
+ task :rspec_fast => :spec_fast
@@ -20,10 +20,12 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.16"
24
- spec.add_development_dependency "rake", "~> 10.0"
25
- spec.add_development_dependency "rspec", "~> 3.0"
23
+ spec.add_development_dependency "bundler", "~> 1.16"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.0"
26
+ spec.add_development_dependency "yard", "~> 0.9", ">= 0.9.18"
27
+ spec.add_development_dependency "redcarpet", "~> 3.4", ">= 3.4.0"
26
28
 
27
- spec.add_dependency 'http', '~> 3'
29
+ spec.add_dependency 'http', '~> 3'
28
30
  spec.add_dependency 'hash-polyfill', '~> 0'
29
31
  end
@@ -4,11 +4,14 @@ module Ecoportal
4
4
  end
5
5
  end
6
6
  end
7
- require 'ecoportal/api/common/client'
7
+
8
+ require 'ecoportal/api/common/base_class'
9
+ require 'ecoportal/api/common/hash_diff'
10
+ require 'ecoportal/api/common/base_model'
11
+ require 'ecoportal/api/common/doc_helpers'
8
12
  require 'ecoportal/api/common/logging'
13
+ require 'ecoportal/api/common/client'
9
14
  require 'ecoportal/api/common/response'
10
15
  require 'ecoportal/api/common/wrapped_response'
11
- require 'ecoportal/api/common/base_model'
12
- require 'ecoportal/api/common/batch_operation'
13
16
  require 'ecoportal/api/common/batch_response'
14
- require 'ecoportal/api/common/hash_diff'
17
+ require 'ecoportal/api/common/batch_operation'
@@ -0,0 +1,29 @@
1
+ module Ecoportal
2
+ module API
3
+ module Common
4
+ module BaseClass
5
+
6
+ def class_resolver(name, klass)
7
+ define_singleton_method(name) { resolve_class(klass) }
8
+ define_method(name) { self.class.resolve_class(klass) }
9
+ end
10
+
11
+ def resolve_class(klass)
12
+ @resolved ||= {}
13
+ @resolved[klass] ||=
14
+ case klass
15
+ when Class
16
+ klass
17
+ when String
18
+ Kernel.const_get(klass)
19
+ when Symbol
20
+ resolve_class(self.send(klass))
21
+ else
22
+ raise "Unknown class: #{klass}"
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -2,21 +2,65 @@ module Ecoportal
2
2
  module API
3
3
  module Common
4
4
  class BaseModel
5
- attr_reader :doc
6
- def initialize(doc = {})
7
- @doc = doc
8
- @original_doc = JSON.parse(doc.to_json)
5
+ class UnlinkedModel < Exception
6
+ def initialize (msg = "Something went wrong when linking the document.")
7
+ super(msg)
8
+ end
9
9
  end
10
10
 
11
- def self.build(doc = {})
12
- new(doc).tap do |instance|
13
- instance.instance_variable_set("@original_doc", {})
11
+ extend BaseClass
12
+
13
+ class << self
14
+ def passthrough(*methods, to: :doc)
15
+ methods.each do |method|
16
+ method = method.to_s
17
+ define_method method do
18
+ send(to)[method]
19
+ end
20
+ define_method "#{method}=" do |value|
21
+ send(to)[method] = value
22
+ end
23
+ end
14
24
  end
25
+
26
+ def embeds_one(method, key: method, nullable: false, klass:)
27
+ method = method.to_s.freeze
28
+ var = "@#{method}".freeze
29
+ key = key.to_s.freeze
30
+ define_method(method) do
31
+ return instance_variable_get(var) if instance_variable_defined?(var)
32
+ doc[key] ||= {} unless nullable
33
+ return instance_variable_set(var, nil) unless doc[key]
34
+
35
+ self.class.resolve_class(klass).new(
36
+ doc[key], parent: self, key: key
37
+ ).tap {|obj| instance_variable_set(var, obj)}
38
+ end
39
+ end
40
+
15
41
  end
16
42
 
17
- def print
18
- puts JSON.pretty_generate(as_json)
19
- self
43
+ attr_reader :_parent, :_key
44
+
45
+ def initialize(doc = {}, parent: self, key: nil)
46
+ @_parent = parent
47
+ @_key = key
48
+ if !_parent || !_key
49
+ @doc = doc
50
+ @original_doc = JSON.parse(@doc.to_json)
51
+ end
52
+ end
53
+
54
+ def doc
55
+ raise UnlinkedModel.new unless linked?
56
+ return _parent.doc[_key] unless _parent == self
57
+ @doc
58
+ end
59
+
60
+ def original_doc
61
+ raise UnlinkedModel.new unless linked?
62
+ return _parent.original_doc[_key] unless _parent == self
63
+ @original_doc
20
64
  end
21
65
 
22
66
  def as_json
@@ -29,20 +73,45 @@ module Ecoportal
29
73
 
30
74
  def as_update
31
75
  new_doc = as_json
32
- Common::HashDiff.diff(new_doc, @original_doc)
76
+ Common::HashDiff.diff(new_doc, original_doc)
33
77
  end
34
78
 
35
- def self.passthrough(*methods, to:)
36
- methods.each do |method|
37
- method = method.to_s
38
- define_method method do
39
- send(to)[method]
40
- end
41
- define_method "#{method}=" do |value|
42
- send(to)[method] = value
43
- end
79
+ def dirty?
80
+ as_update != {}
81
+ end
82
+
83
+ def consolidate!
84
+ raise UnlinkedModel.new unless linked?
85
+ case
86
+ when @original_doc
87
+ @original_doc = JSON.parse(@doc.to_json)
88
+ else
89
+ _parent.original_doc[_key] = JSON.parse(doc.to_json)
44
90
  end
45
91
  end
92
+
93
+ def reset!
94
+ raise UnlinkedModel.new unless linked?
95
+ case
96
+ when @doc
97
+ @doc = JSON.parse(@original_doc.to_json)
98
+ else
99
+ _parent.doc[_key] = JSON.parse(original_doc.to_json)
100
+ end
101
+ end
102
+
103
+ def print
104
+ puts JSON.pretty_generate(as_json)
105
+ self
106
+ end
107
+
108
+ protected
109
+
110
+ def linked?
111
+ is_root = _parent == self && defined?(@doc)
112
+ is_root || _parent.doc[_key]
113
+ end
114
+
46
115
  end
47
116
  end
48
117
  end
@@ -1,4 +1,3 @@
1
- require 'ecoportal/api/common/doc_helpers'
2
1
  module Ecoportal
3
2
  module API
4
3
  module Common
@@ -2,20 +2,25 @@ module Ecoportal
2
2
  module API
3
3
  module Common
4
4
  class BatchResponse
5
+
5
6
  attr_reader :status, :body, :result
7
+
6
8
  def initialize(status, body, result = nil)
7
9
  @status = HTTP::Response::Status.new(status)
8
10
  @body = body
9
11
  @result = result
10
12
  end
13
+
11
14
  def success?
12
15
  status.success?
13
16
  end
17
+
14
18
  def each
15
19
  [*@result].each do |doc|
16
20
  yield doc
17
21
  end
18
22
  end
23
+
19
24
  def print
20
25
  if success?
21
26
  each(&:print)
@@ -2,9 +2,22 @@ require 'http'
2
2
  module Ecoportal
3
3
  module API
4
4
  module Common
5
+ # @note
6
+ # - You can see the documentation of the `HTTP` module in [the repository](https://github.com/httprb/http)
7
+ # - it does `extend` the module `Chainable` ([chainable.rb](https://github.com/httprb/http/blob/master/lib/http/chainable.rb)),
8
+ # - where all the http requests are dev by using `HTTP::Client#request` ([client.rb](https://github.com/httprb/http/blob/master/lib/http/client.rb))
9
+ # - which calls `build_request` (new `HTTP::Request`) and `perform` (new `HTTP::Connection`)
10
+ # - to return `HTTP::Response` ([response.rb](https://github.com/httprb/http/blob/master/lib/http/response.rb))
11
+ # @attr_reader logger [Logger] the logger.
5
12
  class Client
6
13
  attr_accessor :logger
7
14
 
15
+ # @note the `api_key` will be automatically added as parameter `X-ApiKey` in the header of the http requests.
16
+ # @param api_key [String] the key version to stablish the api connection.
17
+ # @param version [String] it is part of the base url and will determine the api version we query against.
18
+ # @param host [String] api server domain.
19
+ # @param logger [Logger] an object with `Logger` interface to generate logs.
20
+ # @return [Client] an object that holds the configuration of the api connection.
8
21
  def initialize(api_key:, version: "v1", host: "live.ecoportal.com", logger: nil)
9
22
  @version = version
10
23
  @api_key = api_key
@@ -21,10 +34,27 @@ module Ecoportal
21
34
  @response_logging_enabled = true
22
35
  end
23
36
 
37
+ # Logger interface.
38
+ # @example:
39
+ # log(:info) {"General information on what's going on"}
40
+ # log(:warn) {"This is a warning that something is likely to have gone amiss"}
41
+ # log(:error) {"Something went wrong"}
42
+ # log(:fatal) {"An unrecoverable error has happend"}
43
+ # @param level [Symbol] the level that the message should be logged.
44
+ # @yield [] generates the message.
45
+ # @yieldreturn [String] the generated message.
24
46
  def log(level, &block)
25
- @logger.send(level, &block) if @logger
47
+ logger.send(level, &block) if logger
26
48
  end
27
49
 
50
+ # Sends an http `GET` request against the api version using `path` to complete the base url,
51
+ # and adding the key_value pairs of `params` in the http _header_.
52
+ # @param path [String] the tail that completes the url of the request.
53
+ # @param params [Hash] the header paramters of the http request (not including the api key).
54
+ # @option params [String] :page the current page we are requesting with given the `:per_page` offset.
55
+ # @option params [String] :per_page the offset or the number of entries you get per request.
56
+ # @option params [String] :q some text to search. Omit this parameter to target all the entries.
57
+ # @return [Common::Reponse] the basic custom response object.
28
58
  def get(path, params: {})
29
59
  instrument("GET", path, params) do
30
60
  request do |http|
@@ -33,6 +63,12 @@ module Ecoportal
33
63
  end
34
64
  end
35
65
 
66
+ # Sends an http `POST` request against the api version using `path` to complete the base url,
67
+ # and the `data` as a body of the http request.
68
+ # @note it automatically adds the http header param `Content-Type` as `application/json`
69
+ # @param path [String] the tail that completes the url of the request.
70
+ # @param data [String] the body of the query in json format.
71
+ # @return [Common::Reponse] the basic custom response object.
36
72
  def post(path, data:)
37
73
  instrument("POST", path, data) do
38
74
  request do |http|
@@ -41,6 +77,12 @@ module Ecoportal
41
77
  end
42
78
  end
43
79
 
80
+ # Sends an http `PATCH` request against the api version using `path` to complete the base url,
81
+ # and the `data` as a body of the http request.
82
+ # @note it automatically adds the http header param `Content-Type` as `application/json`
83
+ # @param path [String] the tail that completes the url of the request.
84
+ # @param data [String] the body of the query in json format.
85
+ # @return [Common::Reponse] the basic custom response object.
44
86
  def patch(path, data:)
45
87
  instrument("PATCH", path, data) do
46
88
  request do |http|
@@ -49,6 +91,9 @@ module Ecoportal
49
91
  end
50
92
  end
51
93
 
94
+ # Sends an http `DELETE` request against the api version using `path` to complete the base url.
95
+ # @param path [String] the tail that completes the url of the request.
96
+ # @return [Common::Reponse] the basic custom response object.
52
97
  def delete(path)
53
98
  instrument("DELETE", path) do
54
99
  request do |http|
@@ -57,18 +102,33 @@ module Ecoportal
57
102
  end
58
103
  end
59
104
 
105
+ # Allows to launch a different operation via `block`, providing the
106
+ # basic HTTP connection to the block.
107
+ # @yield [http] launch specific http request.
108
+ # @yieldparam http [HTTP] the http connection.
109
+ # @yieldreturn [Common::Response] the basic custom reponse object.
110
+ # @return [Common::Reponse] the basic custom response object.
60
111
  def request
61
112
  wrap_response yield(base_request)
62
113
  end
63
114
 
115
+ # Wrap with basic custom object of the gem for responses.
116
+ # @param response [HTTP::Response]
117
+ # @return [Common::Reponse] the basic custom response object.
64
118
  def wrap_response(response)
65
119
  Ecoportal::API::Common::Response.new(response)
66
120
  end
67
121
 
122
+ # Creates a HTTP object adding the `X-ApiKey` param to the header.
123
+ # @note It configures HTTP so it only allows body data in json format.
124
+ # @return [HTTP] HTTP object.
68
125
  def base_request
69
126
  @base_request ||= HTTP.headers("X-ApiKey" => @api_key).accept(:json)
70
127
  end
71
128
 
129
+ # Full URl builder of the request
130
+ # @param path [String] the tail that completes the url of the request.
131
+ # @return [String] the final url.
72
132
  def url_for(path)
73
133
  @base_uri+@version+path
74
134
  end