cuba-api 0.1.0 → 0.2.0

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.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
@@ -27,6 +27,8 @@ require 'cuba_api/current_user'
27
27
  require 'cuba_api/guard'
28
28
  require 'cuba_api/accept_content'
29
29
  require 'cuba_api/config'
30
+ require 'cuba_api/input_filter'
31
+ require 'cuba_api/response_status'
30
32
 
31
33
  class CubaAPI < Cuba
32
34
 
@@ -36,5 +38,7 @@ class CubaAPI < Cuba
36
38
  plugin CubaApi::AcceptContent
37
39
  plugin CubaApi::CurrentUser
38
40
  plugin CubaApi::Guard
41
+ plugin CubaApi::InputFilter
42
+ plugin CubaApi::ResponseStatus
39
43
 
40
- end
44
+ end
@@ -31,6 +31,9 @@ module CubaApi
31
31
  def accept( *args )
32
32
  args.each do |arg|
33
33
  (MIMES[ arg ] || []).each do |mime|
34
+ if arg == :yaml
35
+ require 'safe_yaml' unless defined?( YAML )
36
+ end
34
37
  mimes[ mime ] = "to_#{arg}".to_sym
35
38
  end
36
39
  end
@@ -68,4 +71,4 @@ module CubaApi
68
71
  base.append_aspect :accept_content
69
72
  end
70
73
  end
71
- end
74
+ end
@@ -52,4 +52,4 @@ module CubaApi
52
52
  authenticated? ? current_user.login : "???"
53
53
  end
54
54
  end
55
- end
55
+ end
@@ -0,0 +1,46 @@
1
+ require 'ixtlan/babel/factory'
2
+ module CubaApi
3
+ module InputFilter
4
+
5
+ module ClassMethods
6
+ def factory
7
+ @_factory ||= Ixtlan::Babel::Factory.new
8
+ end
9
+ end
10
+
11
+ def new_instance( clazz, context = nil )
12
+ clazz.new( params( clazz, context ) )
13
+ end
14
+
15
+ def params( clazz = nil, context = nil )
16
+ filter_params_and_keeps( clazz, context )
17
+ @_data[ 0 ] || {}
18
+ end
19
+
20
+ def keeps( clazz = nil, context = nil )
21
+ filter_params_and_keeps( clazz, context )
22
+ @_data[ 1 ] || {}
23
+ end
24
+
25
+ def filter_params_and_keeps( clazz, context )
26
+ if clazz
27
+ @_data ||=
28
+ begin
29
+ filter = self.class.factory.new_filter( clazz ).use( context )
30
+ filter.filter_it( parse_request_body )
31
+ end
32
+ end
33
+ @_data ||= {}
34
+ end
35
+ private :filter_params_and_keeps
36
+
37
+ def parse_request_body
38
+ if env[ 'CONTENT_TYPE' ] == 'application/json'
39
+ JSON.parse( req.body.read )
40
+ else
41
+ {}
42
+ end
43
+ end
44
+ protected :parse_request_body
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ require 'ixtlan/babel/params_filter'
2
+ module CubaApi
3
+ module InputFilter
4
+
5
+ module ClassMethods
6
+ def factory
7
+ @_factory ||= Ixtlan::Babel::Factory.new
8
+ end
9
+ end
10
+
11
+ def new_instance( clazz, context = nil )
12
+ filter = self.class.factory.new_params_filter( clazz ).use( context )
13
+ filter.new( parse_request_body )
14
+ end
15
+
16
+ def params( clazz = nil, context = nil )
17
+ filter_params_and_keeps( clazz, context )
18
+ @_data[ 0 ] || {}
19
+ end
20
+
21
+ def keeps( clazz = nil, context = nil )
22
+ filter_params_and_keeps( clazz, context )
23
+ @_data[ 1 ] || {}
24
+ end
25
+
26
+ def filter_params_and_keeps( clazz, context )
27
+ if clazz
28
+ @_data ||=
29
+ begin
30
+ filter = self.class.factory.new_filter( clazz ).use( context )
31
+ filter.filter_it( parse_request_body )
32
+ end
33
+ end
34
+ end
35
+ private :filter_params_and_keeps
36
+
37
+ def parse_request_body
38
+ if env[ 'CONTENT_TYPE' ] == 'application/json'
39
+ JSON.parse( req.body.read )
40
+ else
41
+ {}
42
+ end
43
+ end
44
+ protected :parse_request_body
45
+ end
46
+ end
@@ -0,0 +1,142 @@
1
+ require 'cuba_api'
2
+ require 'ixtlan/configuration/resource'
3
+ require 'ixtlan/configuration/serializer'
4
+ require 'ixtlan/babel/params_filter'
5
+ class CubaAPI
6
+ module ResponseStatus
7
+ def response_status( obj, options = {})
8
+ if options[:response_status] != false
9
+ if obj.respond_to?( :errors ) && obj.errors.size > 0
10
+ res.status = 412 # Precondition Failed
11
+ obj = obj.errors
12
+ elsif req.post?
13
+ res.status = 201 # Created
14
+ res[ 'Location' ] = env[ 'SCRIPT_NAME' ] + "/#{obj.id}" if obj.respond_to? :id
15
+ elsif req.delete?
16
+ res.status = 204 # No Content
17
+ obj = ''
18
+ end
19
+ end
20
+ obj
21
+ end
22
+
23
+ def self.included( base )
24
+ base.prepend_aspect :response_status
25
+ end
26
+ end
27
+
28
+ module InputFilter
29
+
30
+ module ClassMethods
31
+ def factory
32
+ @_factory ||= Ixtlan::Babel::Factory.new
33
+ end
34
+ end
35
+
36
+ def new_instance( clazz, context = nil )
37
+ filter = self.class.factory.new_params_filter( clazz ).use( context )
38
+ filter.new( parse_request_body )
39
+ end
40
+
41
+ def params( clazz = nil, context = nil )
42
+ filter_params_and_keeps( clazz, context )
43
+ @_data[ 0 ] || {}
44
+ end
45
+
46
+ def keeps( clazz = nil, context = nil )
47
+ filter_params_and_keeps( clazz, context )
48
+ @_data[ 1 ] || {}
49
+ end
50
+
51
+ def filter_params_and_keeps( clazz, context )
52
+ if clazz
53
+ @_data ||=
54
+ begin
55
+ filter = self.class.factory.new_filter( clazz ).use( context )
56
+ filter.filter_it( parse_request_body )
57
+ end
58
+ end
59
+ end
60
+ private :filter_params_and_keeps
61
+
62
+ def parse_request_body
63
+ if env[ 'CONTENT_TYPE' ] == 'application/json'
64
+ JSON.parse( req.body.read )
65
+ else
66
+ {}
67
+ end
68
+ end
69
+ private :parse_request_body
70
+
71
+ end
72
+ end
73
+
74
+ CubaAPI.plugin CubaAPI::InputFilter
75
+ CubaAPI.plugin CubaAPI::ResponseStatus
76
+ module Ixtlan
77
+ module Configuration
78
+ class ConfigurationFilter < Ixtlan::Babel::ParamsFilter
79
+
80
+ root 'configuration'
81
+
82
+ add_context( :single,
83
+ :keep => [ :updated_at ],
84
+ :except => [:id, :created_at, :updated_at, :modified_by_id] )
85
+ end
86
+
87
+ class Cuba < ::CubaAPI
88
+
89
+ define do
90
+ on get do
91
+ write Configuration.instance
92
+ end
93
+
94
+ on post do
95
+ updated_at = keeps( Configuration )[ :updated_at ]
96
+ p keeps
97
+ puts req.request_method
98
+ config = Configuration.optimistic_get!( updated_at,
99
+ Configuration.instance.id )
100
+ #config = Configuration.instance
101
+ config.attributes = params
102
+ config.modified_by = current_user if config.dirty?
103
+ config.save
104
+ write config
105
+ end
106
+
107
+ # on get, :id do |id|
108
+ # write Configuration.get!( id )
109
+ # end
110
+
111
+ # on get do
112
+ # write Configuration.all
113
+ # end
114
+
115
+ # on post do
116
+ # config = new_instance( Configuration )
117
+ # config.save
118
+ # write config
119
+ # end
120
+
121
+ # on put, :id do |id|
122
+ # updated_at = keeps( Configuration )[ :updated_at ]
123
+ # config = Configuration.optimistic_get!( updated_at,
124
+ # id )
125
+ # config.attributes = params
126
+ # config.modified_by = current_user if config.dirty?
127
+ # config.save
128
+ # write config
129
+ # end
130
+
131
+ # on delete, :id do |id|
132
+ # updated_at = keeps( Configuration )[ :updated_at ]
133
+ # config = Configuration.optimistic_get( updated_at,
134
+ # id )
135
+ # config.destroy
136
+ # head 200
137
+ # end
138
+
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,25 @@
1
+ module CubaApi
2
+ module ResponseStatus
3
+ def response_status( obj, options = {})
4
+ if options[:response_status] != false
5
+ if obj.respond_to?( :errors ) && obj.errors.size > 0
6
+ res.status = 412 # Precondition Failed
7
+ obj = obj.errors
8
+ elsif req.post?
9
+ res.status = 201 # Created
10
+ if obj.respond_to?( :id )
11
+ res[ 'Location' ] = env[ 'SCRIPT_NAME' ].to_s+ "/#{obj.id}"
12
+ end
13
+ elsif req.delete?
14
+ res.status = 204 # No Content
15
+ obj = ''
16
+ end
17
+ end
18
+ obj
19
+ end
20
+
21
+ def self.included( base )
22
+ base.prepend_aspect :response_status
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ module CubaApi
2
+ module ResponseStatus
3
+ def response_status( obj, options = {})
4
+ if options[:response_status] != false
5
+ if obj.respond_to?( :errors ) && obj.errors.size > 0
6
+ res.status = 412 # Precondition Failed
7
+ obj = obj.errors
8
+ elsif req.post?
9
+ res.status = 201 # Created
10
+ res[ 'Location' ] = env[ 'SCRIPT_NAME' ] + "/#{obj.id}" if obj.respond_to? :id
11
+ elsif req.delete?
12
+ res.status = 204 # No Content
13
+ obj = ''
14
+ end
15
+ end
16
+ obj
17
+ end
18
+
19
+ def self.included( base )
20
+ base.prepend_aspect :response_status
21
+ end
22
+ end
23
+ end
@@ -34,7 +34,7 @@ module CubaApi
34
34
  if options[:serializer] == false || obj.is_a?( String )
35
35
  obj
36
36
  else
37
- s = self.class.serializer_factory.new( obj )
37
+ s = self.class.serializer_factory.new_serializer( obj )
38
38
  s.use( options[ :use ] ) if options[ :use ]
39
39
  s
40
40
  end
@@ -44,4 +44,4 @@ module CubaApi
44
44
  base.append_aspect :serializer
45
45
  end
46
46
  end
47
- end
47
+ end
@@ -54,4 +54,4 @@ module CubaApi
54
54
  res.write obj.to_s
55
55
  end
56
56
  end
57
- end
57
+ end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
+ require 'cuba_api/config'
2
3
  require 'cuba_api/write_aspect'
3
4
  require 'cuba_api/accept_content'
5
+ require 'yaml'
4
6
 
5
7
  class B
6
8
  def method_missing( method, *args )
@@ -25,6 +27,8 @@ describe CubaApi::AcceptContent do
25
27
  end
26
28
 
27
29
  it 'creates yaml' do
30
+ skip("to_yaml add extra line with ...") if defined?( JRUBY_VERSION ) and (( JRUBY_VERSION =~ /^1.6./ ) == 0 ) and ( nil == (RUBY_VERSION =~ /^1.8/) )
31
+
28
32
  _, _, resp = Cuba.call({"SCRIPT_NAME" => "/bla.yaml"})
29
33
  resp[ 0 ] = resp[ 0 ].sub(/.*!/, "---!").sub( /\n\n/, "\n")
30
34
  resp.join.must.eq "---!ruby/object:B {}\n"
@@ -47,6 +51,8 @@ describe CubaApi::AcceptContent do
47
51
  end
48
52
 
49
53
  it 'gives preference to script extension' do
54
+ skip("to_yaml add extra line with ...") if defined?( JRUBY_VERSION ) and (( JRUBY_VERSION =~ /^1.6./ ) == 0 ) and ( nil == (RUBY_VERSION =~ /^1.8/) )
55
+
50
56
  _, _, resp = Cuba.call({"SCRIPT_NAME" => "/bla.yaml", "HTTP_ACCEPT" => "application/xml"})
51
57
  resp[ 0 ] = resp[ 0 ].sub(/.*!/, "---!").sub( /\n\n/, "\n")
52
58
  resp.join.must.eq "---!ruby/object:B {}\n"
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'cuba_api/write_aspect'
3
+ require 'cuba_api/serializer'
4
+ require 'yaml'
5
+ require 'ixtlan/babel/serializer'
6
+
7
+ class A
8
+ def attributes
9
+ { :name => 'me and the corner' }
10
+ end
11
+ end
12
+ class ASerializer < Ixtlan::Babel::Serializer
13
+ end
14
+ module ToYaml
15
+ def to_yaml( obj, opts )
16
+ obj.to_yaml
17
+ end
18
+ end
19
+
20
+ describe CubaApi::Serializer do
21
+
22
+ before do
23
+ Cuba.reset!
24
+ Cuba[ :aspects ] = []
25
+ Cuba.plugin CubaApi::WriteAspect
26
+ Cuba.plugin CubaApi::Serializer
27
+ Cuba.plugin ToYaml
28
+ Cuba.append_aspect :to_yaml
29
+ Cuba.define do
30
+ on default do
31
+ write A.new
32
+ end
33
+ end
34
+ end
35
+
36
+ it 'should write out yaml' do
37
+ _, _, resp = Cuba.call({})
38
+
39
+ resp.must.eq ["---\nname: me and the corner\n"]
40
+ end
41
+ end
@@ -18,8 +18,8 @@ describe CubaApi::WriteAspect do
18
18
 
19
19
  before do
20
20
  Cuba.reset!
21
- Cuba[ :aspects ] = []
22
21
  Cuba.plugin CubaApi::Config
22
+ Cuba[ :aspects ] = []
23
23
  Cuba.plugin CubaApi::WriteAspect
24
24
  Cuba.plugin Plugin
25
25
  Cuba.append_aspect :one
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'cuba_api/config'
3
+ require 'cuba_api/write_aspect'
4
+
5
+ module Plugin
6
+ def one( obj, opts )
7
+ obj + "-one"
8
+ end
9
+ def two( obj, opts )
10
+ obj + "-two"
11
+ end
12
+ def three( obj, opts )
13
+ obj + "-three"
14
+ end
15
+ end
16
+
17
+ describe CubaApi::WriteAspect do
18
+
19
+ before do
20
+ Cuba.plugin CubaApi::Config
21
+ Cuba.plugin CubaApi::WriteAspect
22
+ Cuba.plugin Plugin
23
+ Cuba.append_aspect :one
24
+ Cuba.prepend_aspect :two
25
+ Cuba.append_aspect :three
26
+ Cuba.define do
27
+ on true do
28
+ write 'start'
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+ it 'should execute aspects in the right order' do
35
+ _, _, resp = Cuba.call({})
36
+
37
+ resp.must.eq ["start-two-one-three"]
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'cuba_api/config'
3
+ require 'cuba_api/write_aspect'
4
+
5
+ module Plugin
6
+ def one( obj, opts )
7
+ obj + "-one"
8
+ end
9
+ def two( obj, opts )
10
+ obj + "-two"
11
+ end
12
+ def three( obj, opts )
13
+ obj + "-three"
14
+ end
15
+ end
16
+
17
+ describe CubaApi::WriteAspect do
18
+
19
+ before do
20
+ Cuba.plugin CubaApi::Config
21
+ Cuba.plugin CubaApi::WriteAspect
22
+ Cuba.plugin Plugin
23
+ Cuba.append_aspect :one
24
+ Cuba.prepend_aspect :two
25
+ Cuba.append_aspect :three
26
+ Cuba.define do
27
+ on true do
28
+ write 'start'
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+ it 'should execute aspects in the right order' do
35
+ _, _, resp = Cuba.call({})
36
+
37
+ resp.must.eq ["start-two-one-three"]
38
+ end
39
+ end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'cuba_api/config'
2
3
  require 'cuba_api/current_user'
3
4
 
4
5
  class SessionManager
@@ -16,8 +17,9 @@ describe CubaApi::CurrentUser do
16
17
 
17
18
  before do
18
19
  Cuba.reset!
20
+ Cuba.plugin CubaApi::Config
19
21
  Cuba.plugin CubaApi::CurrentUser
20
- Cuba.use Rack::Session::Cookie
22
+ Cuba.use Rack::Session::Cookie, :secret => 'asd'
21
23
  Cuba[ :sessions ] = SessionManager.new
22
24
  Cuba.define do
23
25
  on authenticated? do
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'cuba_api/config'
3
+
4
+ describe CubaApi::Config do
5
+
6
+ before do
7
+ Cuba.reset!
8
+ Cuba.plugin CubaApi::Config
9
+ Cuba[ :main ] = Cuba.method( :define )
10
+ Cuba[ :name ] = :root
11
+ class Other < Cuba; end
12
+ end
13
+
14
+ after { Cuba.config.clear }
15
+
16
+ it 'should overwrite super-cuba' do
17
+ Other[ :main ] = :other
18
+
19
+ Cuba[ :main ].class.must.eq Method
20
+ Other[ :main ].must.eq :other
21
+ end
22
+
23
+ it 'should inherit super-cuba on new attributes' do
24
+ Cuba[ :more ] = :more
25
+
26
+ Cuba[ :more ].must.eq :more
27
+ Other[ :more ].must.eq :more
28
+ end
29
+
30
+ it 'should see config from super-cuba' do
31
+ Cuba[ :name ].must.eq :root
32
+ Other[ :name ].must.eq :root
33
+ end
34
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require 'cuba_api/input_filter'
3
+ require 'ixtlan/babel/params_filter'
4
+ require 'json'
5
+ require 'stringio'
6
+
7
+ class D
8
+
9
+ attr_accessor :attributes
10
+
11
+ def initialize( args )
12
+ @attributes = args
13
+ end
14
+ end
15
+
16
+ class DFilter < Ixtlan::Babel::ParamsFilter
17
+
18
+ add_context( :single, :only => [:name], :keep => [:age] )
19
+ add_context( :update, :only => [:message], :keep => [:age] )
20
+
21
+ end
22
+
23
+ describe CubaApi::InputFilter do
24
+
25
+ before do
26
+ Cuba.reset!
27
+ Cuba.plugin CubaApi::InputFilter
28
+ Cuba.define do
29
+ on post do
30
+ attr = new_instance( D ).attributes
31
+ # whether hash is ordered-hash should not matter
32
+ res.write attr.keys.sort.collect {|k| attr[k] }.join
33
+ end
34
+ on default do
35
+ res.write params( D, :update )['message'].to_s + keeps['age'].to_s
36
+ end
37
+ end
38
+ end
39
+
40
+ it 'no json input' do
41
+ _, _, resp = Cuba.call({})
42
+ resp.join.must_be :empty?
43
+ end
44
+
45
+ it 'json input with attr and without keep' do
46
+ _, _, resp = Cuba.call( 'CONTENT_TYPE' => 'application/json',
47
+ 'rack.input' => StringIO.new( '{"name":"me","message":"be happy"}' ) )
48
+ resp.join.must.eq 'be happy'
49
+ end
50
+
51
+ it 'json input with attr and with keep' do
52
+ _, _, resp = Cuba.call( 'CONTENT_TYPE' => 'application/json',
53
+ 'rack.input' => StringIO.new( '{"name":"me","message":"be happy","age":45}' ) )
54
+ resp.join.must.eq 'be happy' + "45"
55
+ end
56
+
57
+ it 'json input without attr and without keep' do
58
+ _, _, resp = Cuba.call( 'CONTENT_TYPE' => 'application/json',
59
+ 'rack.input' => StringIO.new( '{"something":"else"}' ) )
60
+ resp.join.must_be :empty?
61
+ end
62
+
63
+ it 'json input without attr and with keep' do
64
+ _, _, resp = Cuba.call( 'CONTENT_TYPE' => 'application/json',
65
+ 'rack.input' => StringIO.new( '{"something":"else","age":45}' ) )
66
+ resp.join.must.eq "45"
67
+ end
68
+
69
+ it 'create new instance with json input' do
70
+ _, _, resp = Cuba.call( 'CONTENT_TYPE' => 'application/json',
71
+ 'REQUEST_METHOD' => 'POST',
72
+ 'rack.input' => StringIO.new( '{"name":"me","message":"be happy","age":45}' ) )
73
+ resp.join.must.eq 'me'
74
+ end
75
+
76
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ require 'cuba_api/write_aspect'
3
+ require 'cuba_api/accept_content'
4
+
5
+ class B
6
+ def method_missing( method, *args )
7
+ method.to_s
8
+ end
9
+ end
10
+
11
+ describe CubaApi::AcceptContent do
12
+
13
+ before do
14
+ Cuba.reset!
15
+ Cuba.plugin CubaApi::Config
16
+ Cuba[ :aspects ] = []
17
+ Cuba.plugin CubaApi::WriteAspect
18
+ Cuba.plugin CubaApi::AcceptContent
19
+ Cuba.accept :yaml
20
+ Cuba.define do
21
+ on default do
22
+ write B.new
23
+ end
24
+ end
25
+ end
26
+
27
+ it 'creates yaml' do
28
+ _, _, resp = Cuba.call({"SCRIPT_NAME" => "/bla.yaml"})
29
+ resp[ 0 ] = resp[ 0 ].sub(/.*!/, "---!").sub( /\n\n/, "\n")
30
+ resp.join.must.eq "---!ruby/object:B {}\n"
31
+
32
+ _, _, resp = Cuba.call({"HTTP_ACCEPT" => "application/x-yaml"})
33
+ resp[ 0 ] = resp[ 0 ].sub(/.*!/, "---!").sub( /\n\n/, "\n")
34
+ resp.join.must.eq "---!ruby/object:B {}\n"
35
+
36
+ _, _, resp = Cuba.call({"HTTP_ACCEPT" => "text/yaml"})
37
+ resp[ 0 ] = resp[ 0 ].sub(/.*!/, "---!").sub( /\n\n/, "\n")
38
+ resp.join.must.eq "---!ruby/object:B {}\n"
39
+ end
40
+
41
+ it 'gives not found for not configured xml' do
42
+ status, _, _ = Cuba.call({"SCRIPT_NAME" => "/bla.xml"})
43
+ status.must.eq 404
44
+
45
+ status, _, _ = Cuba.call({"HTTP_ACCEPT" => "application/xml"})
46
+ status.must.eq 404
47
+ end
48
+
49
+ it 'gives preference to script extension' do
50
+ _, _, resp = Cuba.call({"SCRIPT_NAME" => "/bla.yaml", "HTTP_ACCEPT" => "application/xml"})
51
+ resp[ 0 ] = resp[ 0 ].sub(/.*!/, "---!").sub( /\n\n/, "\n")
52
+ resp.join.must.eq "---!ruby/object:B {}\n"
53
+
54
+ status, _, _ = Cuba.call({"SCRIPT_NAME" => "/bla.xml", "HTTP_ACCEPT" => "application/x-yaml"})
55
+ status.must.eq 404
56
+ end
57
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+ require 'cuba_api/write_aspect'
3
+ require 'cuba_api/config'
4
+ require 'cuba_api/response_status'
5
+
6
+ class E
7
+
8
+ def id
9
+ 4711
10
+ end
11
+
12
+ def initialize( args = nil )
13
+ @errors = (args || {}).delete( :errors ) || {}
14
+ # ruby18 workaround
15
+ def @errors.to_s
16
+ inspect
17
+ end
18
+ @attributes = args
19
+ end
20
+
21
+ def deleted?
22
+ @attrbutes.nil?
23
+ end
24
+
25
+ def errors
26
+ @errors
27
+ end
28
+
29
+ def to_s
30
+ @attributes.inspect + @errors.inspect
31
+ end
32
+ end
33
+
34
+
35
+ describe CubaApi::ResponseStatus do
36
+
37
+ before do
38
+ Cuba.reset!
39
+ Cuba.plugin CubaApi::Config
40
+ Cuba.plugin CubaApi::WriteAspect
41
+ Cuba.plugin CubaApi::ResponseStatus
42
+ Cuba.define do
43
+ on get do
44
+ write E.new :errors => { :name => 'missing name' }
45
+ end
46
+ on post do
47
+ write E.new :message => 'be happy'
48
+ end
49
+ on put do
50
+ write E.new :message => 'be happy'
51
+ end
52
+ on delete do
53
+ write E.new
54
+ end
55
+ end
56
+ end
57
+
58
+ it 'status 200' do
59
+ status, _, resp = Cuba.call({'REQUEST_METHOD' => 'PUT'})
60
+ status.must.eq 200
61
+ resp.join.must.eq "{:message=>\"be happy\"}{}"
62
+ end
63
+
64
+ it 'status 201' do
65
+ status, _, resp = Cuba.call({'REQUEST_METHOD' => 'POST'})
66
+ status.must.eq 201
67
+ resp.join.must.eq "{:message=>\"be happy\"}{}"
68
+ end
69
+
70
+ it 'status 204' do
71
+ status, _, resp = Cuba.call({'REQUEST_METHOD' => 'DELETE'})
72
+ status.must.eq 204
73
+ resp.join.must_be :empty?
74
+ end
75
+
76
+ it 'status 412' do
77
+ status, _, resp = Cuba.call({'REQUEST_METHOD' => 'GET'})
78
+ status.must.eq 412
79
+ resp.join.must.eq "{:name=>\"missing name\"}"
80
+ end
81
+
82
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'cuba_api/response_status'
3
+
4
+ class E
5
+ def initialize( args = nil )
6
+ @errors = args.delete( :errors ) || {}
7
+ @attributes = args
8
+ end
9
+
10
+ def deleted?
11
+ @attrbutes.nil?
12
+ end
13
+
14
+ def errrors
15
+ @errors
16
+ end
17
+ end
18
+
19
+
20
+ describe CubaApi::ResponseStatus do
21
+
22
+ before do
23
+ Cuba.reset!
24
+ Cuba.plugin CubaApi::ResponseStatus
25
+ Cuba.plugin CubaApi::WriteAspect
26
+ Cuba.define do
27
+ on get do
28
+ write E.new :errors => { :name => 'missing name' }
29
+ end
30
+ on post do
31
+ write E.new :message => 'be happy'
32
+ end
33
+ on put do
34
+ write E.new :message => 'be happy'
35
+ end
36
+ on delete do
37
+ write E.new
38
+ end
39
+ end
40
+ end
41
+
42
+ it 'status 200' do
43
+ _, _, resp = Cuba.call({'REQUEST_METHOD' => 'GET'})
44
+ resp.join.must.eq ""
45
+ end
46
+
47
+ end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'cuba_api/config'
2
3
  require 'cuba_api/write_aspect'
3
4
  require 'cuba_api/serializer'
4
5
  require 'yaml'
@@ -21,6 +22,7 @@ describe CubaApi::Serializer do
21
22
 
22
23
  before do
23
24
  Cuba.reset!
25
+ Cuba.plugin CubaApi::Config
24
26
  Cuba[ :aspects ] = []
25
27
  Cuba.plugin CubaApi::WriteAspect
26
28
  Cuba.plugin CubaApi::Serializer
@@ -34,8 +36,9 @@ describe CubaApi::Serializer do
34
36
  end
35
37
 
36
38
  it 'should write out yaml' do
39
+ skip("to_yaml add extra line with ...") if defined?( JRUBY_VERSION ) and (( JRUBY_VERSION =~ /^1.6./ ) == 0 ) and ( nil == (RUBY_VERSION =~ /^1.8/) )
37
40
  _, _, resp = Cuba.call({})
38
-
41
+
39
42
  resp[ 0 ] = resp[ 0 ].sub(/.*\n/, "---\n")
40
43
  resp.must_equal ["---\nname: me and the corner\n"]
41
44
  end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'cuba_api/current_user'
3
+
4
+ class SessionManager
5
+ def to_session( user )
6
+ @u ||= user
7
+ end
8
+ def from_session( data )
9
+ u = @u.dup unless @u.nil?
10
+ def u.login; self;end
11
+ u
12
+ end
13
+ end
14
+
15
+ describe CubaApi::CurrentUser do
16
+
17
+ before do
18
+ Cuba.reset!
19
+ Cuba.plugin CubaApi::CurrentUser
20
+ Cuba.use Rack::Session::Cookie
21
+ Cuba[ :sessions ] = SessionManager.new
22
+ Cuba.define do
23
+ on authenticated? do
24
+ res.write current_user
25
+ end
26
+ on default do
27
+ name = current_user_name
28
+ current_user "user1"
29
+ res.write "logged in - #{name}"
30
+ end
31
+ end
32
+ end
33
+
34
+ it 'should authenticate' do
35
+ _, _, resp = Cuba.call({})
36
+
37
+ resp.must.eq ["logged in - ???"]
38
+
39
+ _, _, resp = Cuba.call({})
40
+
41
+ resp.must.eq ["user1"]
42
+ end
43
+ end
@@ -0,0 +1,4 @@
1
+ require 'cuba'
2
+ ENV["MT_NO_EXPECTATIONS"] = "true"
3
+
4
+ require 'mustard'
@@ -0,0 +1 @@
1
+ ENV["MT_NO_EXPECTATIONS"] = "true"
metadata CHANGED
@@ -1,95 +1,161 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuba-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
5
- prerelease:
4
+ prerelease:
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Christian Meier
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-29 00:00:00.000000000 Z
12
+ date: 2013-02-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cuba
16
- requirement: &18852600 !ruby/object:Gem::Requirement
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '3.1'
17
21
  none: false
22
+ requirement: !ruby/object:Gem::Requirement
18
23
  requirements:
19
- - - ~>
24
+ - - "~>"
20
25
  - !ruby/object:Gem::Version
21
26
  version: '3.1'
22
- type: :runtime
27
+ none: false
23
28
  prerelease: false
24
- version_requirements: *18852600
29
+ type: :runtime
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: ixtlan-babel
27
- requirement: &18850840 !ruby/object:Gem::Requirement
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - "~>"
35
+ - !ruby/object:Gem::Version
36
+ version: '0.3'
28
37
  none: false
38
+ requirement: !ruby/object:Gem::Requirement
29
39
  requirements:
30
- - - ~>
40
+ - - "~>"
31
41
  - !ruby/object:Gem::Version
32
- version: 0.2.0
42
+ version: '0.3'
43
+ none: false
44
+ prerelease: false
33
45
  type: :runtime
46
+ - !ruby/object:Gem::Dependency
47
+ name: safe_yaml
48
+ version_requirements: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '0.5'
53
+ none: false
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: '0.5'
59
+ none: false
34
60
  prerelease: false
35
- version_requirements: *18850840
61
+ type: :runtime
62
+ - !ruby/object:Gem::Dependency
63
+ name: json
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.7.6
69
+ none: false
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 1.7.6
75
+ none: false
76
+ prerelease: false
77
+ type: :development
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: 10.0.3
85
+ none: false
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: 10.0.3
91
+ none: false
92
+ prerelease: false
93
+ type: :development
36
94
  - !ruby/object:Gem::Dependency
37
95
  name: copyright-header
38
- requirement: &18849320 !ruby/object:Gem::Requirement
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: 1.0.7
39
101
  none: false
102
+ requirement: !ruby/object:Gem::Requirement
40
103
  requirements:
41
- - - ~>
104
+ - - "~>"
42
105
  - !ruby/object:Gem::Version
43
106
  version: 1.0.7
44
- type: :development
107
+ none: false
45
108
  prerelease: false
46
- version_requirements: *18849320
109
+ type: :development
47
110
  - !ruby/object:Gem::Dependency
48
111
  name: minitest
49
- requirement: &18845760 !ruby/object:Gem::Requirement
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '4.3'
50
117
  none: false
118
+ requirement: !ruby/object:Gem::Requirement
51
119
  requirements:
52
- - - ~>
120
+ - - "~>"
53
121
  - !ruby/object:Gem::Version
54
- version: 4.3.0
55
- type: :development
122
+ version: '4.3'
123
+ none: false
56
124
  prerelease: false
57
- version_requirements: *18845760
125
+ type: :development
58
126
  - !ruby/object:Gem::Dependency
59
127
  name: mustard
60
- requirement: &18844760 !ruby/object:Gem::Requirement
61
- none: false
128
+ version_requirements: !ruby/object:Gem::Requirement
62
129
  requirements:
63
- - - ~>
130
+ - - "~>"
64
131
  - !ruby/object:Gem::Version
65
132
  version: '0.1'
66
- type: :development
67
- prerelease: false
68
- version_requirements: *18844760
69
- - !ruby/object:Gem::Dependency
70
- name: rake
71
- requirement: &18843280 !ruby/object:Gem::Requirement
72
133
  none: false
134
+ requirement: !ruby/object:Gem::Requirement
73
135
  requirements:
74
- - - ~>
136
+ - - "~>"
75
137
  - !ruby/object:Gem::Version
76
- version: 10.0.3
77
- type: :development
138
+ version: '0.1'
139
+ none: false
78
140
  prerelease: false
79
- version_requirements: *18843280
141
+ type: :development
80
142
  - !ruby/object:Gem::Dependency
81
143
  name: backports
82
- requirement: &18792320 !ruby/object:Gem::Requirement
144
+ version_requirements: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - "~>"
147
+ - !ruby/object:Gem::Version
148
+ version: '2.6'
83
149
  none: false
150
+ requirement: !ruby/object:Gem::Requirement
84
151
  requirements:
85
- - - ~>
152
+ - - "~>"
86
153
  - !ruby/object:Gem::Version
87
- version: 2.6.3
88
- type: :development
154
+ version: '2.6'
155
+ none: false
89
156
  prerelease: false
90
- version_requirements: *18792320
91
- description: add content negogiation, serialization of objects (their attributes map),
92
- and some helpers for authentication + authorization to the cuba framework
157
+ type: :development
158
+ description: add content negogiation, serialization of objects (their attributes map), and some helpers for authentication + authorization to the cuba framework
93
159
  email:
94
160
  - m.kristian@web.de
95
161
  executables: []
@@ -98,49 +164,68 @@ extra_rdoc_files: []
98
164
  files:
99
165
  - MIT-LICENSE
100
166
  - README.md
167
+ - lib/cuba_api.rb
168
+ - lib/cuba_api.rb~
169
+ - lib/cuba_api/input_filter.rb~
101
170
  - lib/cuba_api/write_aspects.rb~
102
171
  - lib/cuba_api/guard.rb
103
172
  - lib/cuba_api/serializer.rb~
104
173
  - lib/cuba_api/accept_content.rb~
105
174
  - lib/cuba_api/current_user.rb
106
175
  - lib/cuba_api/write_aspect.rb
176
+ - lib/cuba_api/input_filter.rb
177
+ - lib/cuba_api/reponse_status.rb~
107
178
  - lib/cuba_api/write_aspect.rb~
108
179
  - lib/cuba_api/current_user.rb~
109
180
  - lib/cuba_api/config.rb
181
+ - lib/cuba_api/response_status.rb~
110
182
  - lib/cuba_api/guard.rb~
111
183
  - lib/cuba_api/accept_content.rb
112
184
  - lib/cuba_api/config.rb~
113
185
  - lib/cuba_api/serializer.rb
114
- - lib/cuba_api.rb
115
- - lib/cuba_api.rb~
186
+ - lib/cuba_api/response_status.rb
116
187
  - spec/serializer_spec.rb
188
+ - spec/input_filter_spec.rb~
189
+ - spec/config_spec.rb~
190
+ - spec/spec_helper.rb~
117
191
  - spec/aspects_spec.rb
192
+ - spec/accept_spec.rb~
193
+ - spec/spec_helper.rb
194
+ - spec/response_status_spec.rb~
118
195
  - spec/config_spec.rb
119
196
  - spec/accept_spec.rb
197
+ - spec/serializer_spec.rb~
120
198
  - spec/current_user_spec.rb
199
+ - spec/aspects_spec.rb~
200
+ - spec/current_user_spec.rb~
201
+ - spec/input_filter_spec.rb
202
+ - spec/response_status_spec.rb
203
+ - Gemfile
121
204
  homepage: http://github.com/mkristian/cuba-api
122
205
  licenses:
123
206
  - MIT
124
- post_install_message:
207
+ post_install_message:
125
208
  rdoc_options: []
126
209
  require_paths:
127
210
  - lib
128
211
  required_ruby_version: !ruby/object:Gem::Requirement
129
- none: false
130
212
  requirements:
131
- - - ! '>='
213
+ - - ">="
132
214
  - !ruby/object:Gem::Version
133
- version: '0'
134
- required_rubygems_version: !ruby/object:Gem::Requirement
215
+ version: !binary |-
216
+ MA==
135
217
  none: false
218
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
219
  requirements:
137
- - - ! '>='
220
+ - - ">="
138
221
  - !ruby/object:Gem::Version
139
- version: '0'
222
+ version: !binary |-
223
+ MA==
224
+ none: false
140
225
  requirements: []
141
- rubyforge_project:
142
- rubygems_version: 1.8.11
143
- signing_key:
226
+ rubyforge_project:
227
+ rubygems_version: 1.8.24
228
+ signing_key:
144
229
  specification_version: 3
145
230
  summary: set of plugins for using cuba as API server
146
231
  test_files:
@@ -149,4 +234,5 @@ test_files:
149
234
  - spec/config_spec.rb
150
235
  - spec/accept_spec.rb
151
236
  - spec/current_user_spec.rb
152
- has_rdoc:
237
+ - spec/input_filter_spec.rb
238
+ - spec/response_status_spec.rb