api-extensions 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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