api-extensions 0.0.1 → 0.0.2

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjYxMWQxNDgwYmY0YjJmMDY5OGZhMWZkNzdhNmM0NjkwODAzNzZjMg==
4
+ N2U3NWJjOWY4MWM1OGY2ZDZjMDgwNWJmY2ZkODY2NTU3ZTYzZjQyZg==
5
5
  data.tar.gz: !binary |-
6
- YzViOWVhNGRkMjljMGI5ODhhZGU1ZjVhMTMwNmNlYWZmOTRhM2RkZQ==
6
+ OTJiZmZmOTI2NmU1ZTgyNjg5ODk4OGIxMzc1YzVkZDM2ZWQyY2I4Yw==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZjA0NDk1M2VkMGI0YmE4MzFkY2RlYTQzN2IzZWRhNjljNzkxYThmNzgzODBi
10
- MWMyOWIwYzBjMzhmYjRjMzIwZWQ5MGMyMDU4ZTdhODJkMDc4ZjQ4MTgyZjVj
11
- YjNjZDIwMjg5ZTc1NjM2MDUzZDQxMWUyNzBmMzU2ZjhkMGQyYmU=
9
+ ZDY3NGM1MmU0MDRkNjQyM2FkY2FjNTc2MmI1YTA0OGJkOTM0MWIzZTc0MThm
10
+ YmM1YTAxMWUxZTdlNjE1OWJjNDFkNmJjZjczOGQ5ZDQyOWZlYzkxMWZkM2Rj
11
+ ODU1ZWFlMTRmZjY0YzllYTIxYTFlYTFlMjAwMTUxYWIzMDc0MWQ=
12
12
  data.tar.gz: !binary |-
13
- ZDYxZDQxMWFkODg0NzEwZjI1NmY0NzYzMjllNjBlOTAxNDAxN2UzMDkzMjhl
14
- NGI0ZjE2NzA1NGY4MmExMDNlYTJjOWM0NWY0NTdhMTg2ZTU5OWUyZWM3ZjIz
15
- NDBjNmRjODdmZGZhZmU3ZDY3YTIwMDU3YjRhZGI3MWJkYWQ2NGM=
13
+ YWY5MWI3MTAwZjNiYWU2NmM0ODRkZmRmZjMxMmQzYjExNmY0ZGUyNjY0MGI5
14
+ ZDdhYzUyYThmODA2ZmJjNThkOTI4MTRjYTVjNWQ2Yzk5ZmZlZWUyMjI3OTI1
15
+ NDhjOGRiNjJiYmQ2M2QwNTY1NTQ4NGY1MTk5NzcwYzY0NGI5M2Q=
data/README.md CHANGED
@@ -23,6 +23,32 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
+ ### `expand` extension
27
+
28
+ The behavior of this extension is best described at
29
+ [the api-doc repo](https://github.com/ncuesta/api-doc/blob/master/README.en.md#links-expansion).
30
+
31
+ By including the `Api::Extensions::Expand` module in any class, you will get a `process_expand`
32
+ method that will handle the expansion of linked resources - as described in the linked document.
33
+
34
+ Please note that this extension **requires that the including class responds to a `get` method**.
35
+
36
+ ```ruby
37
+ require 'api/extensions/expand'
38
+
39
+ class MyApiHandler
40
+
41
+ def initialize
42
+ include Api::Extensions::Expand
43
+ end
44
+
45
+ def handle(request)
46
+ response = fiddle_with request
47
+ process_expand request[:expand], response
48
+ end
49
+ end
50
+ ```
51
+
26
52
  ### `fields` extension
27
53
 
28
54
  The behavior of this extension is best described at
@@ -44,6 +70,13 @@ class MyApiHandler
44
70
  end
45
71
  ```
46
72
 
73
+ ## Running tests
74
+
75
+ The test suite uses Cucumber, and can be run through `rake`:
76
+
77
+ ```bash
78
+ $ rake features
79
+ ```
47
80
 
48
81
  ## Contributing
49
82
 
@@ -0,0 +1,42 @@
1
+ Feature: Expand functional extension
2
+ In order to reduce the amount of requests sent to the API
3
+ As a client application
4
+ I want to be able to specify which related links I need expanded
5
+
6
+ Scenario Outline: Invalid expand values are ignored
7
+ Given I get a request for resource "/articles/1.json"
8
+ And I get the expand parameter "<value>"
9
+ When I process the expand parameter
10
+ Then the resulting response should be the same as the original one
11
+
12
+ Examples:
13
+ | value |
14
+ | |
15
+ | , |
16
+ | ,, |
17
+ | non-existing-key |
18
+ | non,existing,key |
19
+ | non(existing) |
20
+
21
+
22
+ Scenario Outline: Links expansion for singular documents
23
+ Given I get a request for resource "/articles/1.json"
24
+ And I get the expand parameter "<value>"
25
+ When I process the expand parameter
26
+ Then the resulting response should include the original response
27
+ And the resulting response should also contain "<expanded_links>" as new attributes
28
+
29
+ Examples:
30
+ | value | expanded_links |
31
+ | title | title |
32
+ | title,name | title,name |
33
+ | title,name, | title,name |
34
+ | title,name,non_existent_field | title,name |
35
+
36
+
37
+ Scenario: Links expansion for collective documents
38
+ Given I get a request for resource "/articles.json"
39
+ And I get the expand parameter "entries(self)"
40
+ When I process the expand parameter
41
+ Then the resulting response should include the original response
42
+ And the resulting response should have the entries expanded
@@ -12,6 +12,21 @@ def resources
12
12
  'self' => { 'href' => '/link/to/self' },
13
13
  'other' => { 'href' => '/link/to/other' }
14
14
  }
15
+ },
16
+ '/articles.json' => {
17
+ 'entries' => [
18
+ {
19
+ 'links' => {
20
+ 'self' => { 'href' => '/articles/1.json' }
21
+ }
22
+ }
23
+ ],
24
+ 'total' => 1,
25
+ 'limit' => 10,
26
+ 'offset' => 0,
27
+ 'links' => {
28
+ 'self' => { 'href' => '/link/to/self' }
29
+ }
15
30
  }
16
31
  }
17
32
  end
@@ -0,0 +1,31 @@
1
+ require 'api/extensions/expand'
2
+
3
+ Before do
4
+ @expand_processor = Object.new
5
+ class << @expand_processor
6
+ def get url
7
+ end
8
+
9
+ include(Api::Extensions::Expand)
10
+ end
11
+ end
12
+
13
+ Given(/^I get the expand parameter "(.*)"$/) do |value|
14
+ @expand = value
15
+ end
16
+
17
+ When(/^I process the expand parameter$/) do
18
+ @result = @expand_processor.process_expand @expand, @response
19
+ end
20
+
21
+ Then(/^the resulting response should include the original response$/) do
22
+ pending # express the regexp above with the code you wish you had
23
+ end
24
+
25
+ Then(/^the resulting response should also contain "(.*?)" as new attributes$/) do |arg1|
26
+ pending # express the regexp above with the code you wish you had
27
+ end
28
+
29
+ Then(/^the resulting response should have the entries expanded$/) do
30
+ pending # express the regexp above with the code you wish you had
31
+ end
@@ -1,8 +1,8 @@
1
1
  require 'api/extensions/fields'
2
2
 
3
3
  Before do
4
- @processor = Object.new
5
- class << @processor
4
+ @fields_processor = Object.new
5
+ class << @fields_processor
6
6
  include(Api::Extensions::Fields)
7
7
  end
8
8
  end
@@ -17,7 +17,7 @@ Given /^I get the fields parameter "(.*)"$/ do |value|
17
17
  end
18
18
 
19
19
  When /^I process the fields parameter$/ do
20
- @result = @processor.process_fields @fields, @response, @request_path
20
+ @result = @fields_processor.process_fields @fields, @response, @request_path
21
21
  end
22
22
 
23
23
  Then /^the resulting response should include the required fields$/ do
@@ -0,0 +1,61 @@
1
+ #
2
+ # Expand extension
3
+ #
4
+ # https://github.com/ncuesta/api-doc/blob/master/README.en.md#links-expansion
5
+ #
6
+ module Api
7
+ module Extensions
8
+ module Expand
9
+ # Check requirements on inclusion
10
+ def self.included(base)
11
+ raise ::Exception.new('Base class must implement a :get method to include the ExpandProcessor module') unless base.method_defined?(:get)
12
+ end
13
+
14
+ # Process the expand functional extension
15
+ def process_expand(keys, scope)
16
+ keys.split(',').each do |key|
17
+ entries_parts = key.match(/entries\((.*)\)$/)
18
+
19
+ if entries_parts && scope['entries']
20
+ # (2) Collective key: expand=entries(self)
21
+ scope['entries'].collect! { |entry| process_expand entries_parts[1], entry }
22
+ else
23
+ recursive = key.match(/([^\(]+)\((.*)\)$/)
24
+
25
+ if recursive
26
+ # (1) Recursive key: expand=section(parent)
27
+ local_key, sub_key = recursive[1, 2]
28
+ # Expand the local key
29
+ scope = expand scope, local_key
30
+ # Recursively expand the remaining keys - if possible
31
+ new_scope = local_key == 'self' ? scope : scope[local_key]
32
+ process_expand(sub_key, new_scope) if new_scope
33
+ else
34
+ # (0) Simple key: expand=section
35
+ scope = expand scope, key
36
+ end
37
+ end
38
+ end
39
+
40
+ scope
41
+ end
42
+
43
+ # Actually expand a link
44
+ def expand(resource, link)
45
+ if resource['links'].include?(link)
46
+ sub_resource_uri = resource['links'][link]['href']
47
+ sub_resource = get sub_resource_uri
48
+
49
+ # 'self' links replace the original resource
50
+ if link == 'self'
51
+ resource = sub_resource
52
+ else
53
+ resource[link] = sub_resource
54
+ end
55
+ end
56
+
57
+ resource
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,5 +1,5 @@
1
1
  module Api
2
2
  module Extensions
3
- VERSION = '0.0.1'
3
+ VERSION = '0.0.2'
4
4
  end
5
5
  end
@@ -1,3 +1,4 @@
1
+ require 'api/extensions/expand'
1
2
  require 'api/extensions/fields'
2
3
  require 'api/extensions/version'
3
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api-extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nahuel Cuesta Luengo
@@ -81,10 +81,13 @@ files:
81
81
  - Rakefile
82
82
  - api-extensions.gemspec
83
83
  - cucumber.yml
84
+ - features/expand.feature
84
85
  - features/fields.feature
85
86
  - features/step_definitions/common_steps.rb
87
+ - features/step_definitions/expand_steps.rb
86
88
  - features/step_definitions/fields_steps.rb
87
89
  - lib/api/extensions.rb
90
+ - lib/api/extensions/expand.rb
88
91
  - lib/api/extensions/fields.rb
89
92
  - lib/api/extensions/version.rb
90
93
  homepage: https://github.com/ncuesta/api-extensions
@@ -112,6 +115,8 @@ signing_key:
112
115
  specification_version: 4
113
116
  summary: A collection of extensions for Hypermedia-driven APIs
114
117
  test_files:
118
+ - features/expand.feature
115
119
  - features/fields.feature
116
120
  - features/step_definitions/common_steps.rb
121
+ - features/step_definitions/expand_steps.rb
117
122
  - features/step_definitions/fields_steps.rb