rack-backend-api 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -292,6 +292,7 @@ CHANGE LOG
292
292
  0.0.5 Ordered list of fields to keep before validation
293
293
  0.1.0 Introduce sorting functionality
294
294
  0.2.0 Control what you send on 201 responses
295
+ 0.2.1 Have a title in forms + Only use `_method` if not POST
295
296
 
296
297
  COPYRIGHT
297
298
  =========
data/lib/backend_api.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class BackendAPI
2
- VERSION = [0,2,0]
2
+ VERSION = [0,2,1]
3
3
  WRAP = <<-EOT
4
4
  <!doctype html>
5
5
  <html>
@@ -27,9 +27,10 @@ module ::Sequel::Plugins::RackBackendApiAdapter
27
27
  cols ||= default_backend_columns
28
28
  fields_list = respond_to?(:crushyform) ? crushyform(cols) : backend_fields(cols)
29
29
  o = "<form action='#{url}' method='POST' #{"enctype='multipart/form-data'" if fields_list.match(/type='file'/)} class='backend-form'>\n"
30
+ o << backend_form_title
30
31
  o << fields_list
31
- method = self.new? ? 'POST' : 'PUT'
32
- o << "<input type='hidden' name='_method' value='#{opts[:method] || method}' />\n"
32
+ opts[:method] = 'PUT' if (opts[:method].nil? && !self.new?)
33
+ o << "<input type='hidden' name='_method' value='#{opts[:method]}' />\n" unless opts[:method].nil?
33
34
  o << "<input type='hidden' name='_destination' value='#{opts[:destination]}' />\n" unless opts[:destination].nil?
34
35
  o << "<input type='hidden' name='_submit_text' value='#{opts[:submit_text]}' />\n" unless opts[:submit_text].nil?
35
36
  o << "<input type='hidden' name='_no_wrap' value='#{opts[:no_wrap]}' />\n" unless opts[:no_wrap].nil?
@@ -42,6 +43,13 @@ module ::Sequel::Plugins::RackBackendApiAdapter
42
43
  end
43
44
 
44
45
  def backend_delete_form(url, opts={}); backend_form(url, [], {:submit_text=>'X', :method=>'DELETE'}.update(opts)); end
46
+
47
+ def backend_form_title
48
+ n = self.respond_to?(:to_label) ? self.to_label : self.backend_to_label
49
+ "<h2>#{'Edit ' unless self.new?}#{n}</h2>"
50
+ end
51
+
52
+ def backend_to_label; [self.new? ? 'New' : nil, model.name, id].compact!.join(' '); end
45
53
 
46
54
  # Silly but usable form prototype
47
55
  # Not really meant to be used in a real case
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rack-backend-api'
3
- s.version = "0.2.0"
3
+ s.version = "0.2.1"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.summary = "A Rack middleware that provides a simple API for your Admin section"
6
6
  s.description = "The purpose of this Rack Middleware is to provide an API that interfaces with database actions in order to build a CMS."
data/test/db.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'sequel'
2
2
  ::Sequel::Model.plugin :schema
3
- ::Sequel::Model.plugin :crushyform rescue nil
4
3
  DB = ::Sequel.sqlite
5
4
 
6
5
  class Haiku < ::Sequel::Model
@@ -12,6 +11,7 @@ class Haiku < ::Sequel::Model
12
11
  foreign_key :author_id, :authors
13
12
  end
14
13
  create_table unless table_exists?
14
+ plugin :crushyform
15
15
  many_to_one :author
16
16
  def validate
17
17
  errors[:title] << "Should start with a decent char" if title.to_s!='' && title[0]<65
@@ -26,6 +26,7 @@ class Author < ::Sequel::Model
26
26
  String :surname, :crushyform=>{:required=>true}
27
27
  end
28
28
  create_table unless table_exists?
29
+ plugin :crushyform
29
30
  one_to_many :haikus
30
31
  def validate
31
32
  errors[:name] << 'Cannot be blank' if name.to_s==''
@@ -40,6 +41,7 @@ class Pic < ::Sequel::Model
40
41
  String :image, :crushyform=>{:type=>:attachment}
41
42
  end
42
43
  create_table unless table_exists?
44
+ plugin :crushyform
43
45
  end
44
46
 
45
47
  class CamelCasedClass < ::Sequel::Model
@@ -48,6 +50,7 @@ class CamelCasedClass < ::Sequel::Model
48
50
  String :name
49
51
  end
50
52
  create_table unless table_exists?
53
+ plugin :crushyform
51
54
  end
52
55
 
53
56
  class TopFive < ::Sequel::Model
@@ -57,9 +60,18 @@ class TopFive < ::Sequel::Model
57
60
  String :flavour
58
61
  end
59
62
  create_table unless table_exists?
63
+ plugin :crushyform
60
64
  plugin :list
61
65
  end
62
66
 
67
+ class NoCrushyform < ::Sequel::Model
68
+ set_schema do
69
+ primary_key :id
70
+ String :name
71
+ end
72
+ create_table unless table_exists?
73
+ end
74
+
63
75
  Haiku.create( :title=>'Autumn', :body=>"Rust the ground\nFlush the branches\nReveal the trees" )
64
76
  Haiku.create( :title=>'Winter', :body=>"There is snow\nIt covers you\nBut you are still the most beautiful" )
65
77
  Haiku.create( :title=>'Spring', :body=>"No inspiration" )
@@ -73,3 +85,5 @@ TopFive.create(:flavour=>'Vanilla')
73
85
  TopFive.create(:flavour=>'Chocolate')
74
86
  TopFive.create(:flavour=>'Coconut')
75
87
  TopFive.create(:flavour=>'Apricot')
88
+
89
+ NoCrushyform.create(:name=>'Fernando')
@@ -73,6 +73,10 @@ describe 'API Misc' do
73
73
  res2.status.should==200
74
74
  res1.body.should==res2.body.gsub('camel_cased_class', 'CamelCasedClass')
75
75
  end
76
+
77
+ should "Only accept defined constants before eval (security)" do
78
+ lambda{req_lint(BackendAPI.new).get('/*ca%20mel_cas-ed_class')}.should.raise(NameError)
79
+ end
76
80
  end
77
81
 
78
82
  describe 'API Post' do
@@ -39,7 +39,7 @@ describe 'Sequel Adapter' do
39
39
  end
40
40
 
41
41
  should 'Have Method Override value POST/PUT automatically set by default in the form' do
42
- Haiku.new.backend_form('/url').should.match(/name='_method' value='POST'/)
42
+ Haiku.new.backend_form('/url').should.not.match(/name='_method'/)
43
43
  Haiku.first.backend_form('/url').should.match(/name='_method' value='PUT'/)
44
44
  end
45
45
 
@@ -88,7 +88,26 @@ describe 'Sequel Adapter' do
88
88
  end
89
89
 
90
90
  should "Have an instance method called backend_show that says 'OK' by default" do
91
- Haiku[1].backend_show.should=='OK'
91
+ Author[1].backend_show.should=='OK'
92
+ end
93
+
94
+ should "Have default labels for when Model#to_label is not implemented" do
95
+ NoCrushyform.new.backend_to_label.should=='New NoCrushyform'
96
+ NoCrushyform[1].backend_to_label.should=='NoCrushyform 1'
97
+ end
98
+
99
+ should "Have a correct form title for instances" do
100
+ # No crushyform
101
+ NoCrushyform.new.backend_form_title.should=='<h2>New NoCrushyform</h2>' # New
102
+ NoCrushyform[1].backend_form_title.should=='<h2>Edit NoCrushyform 1</h2>' # Edit
103
+ # Crushyform
104
+ CamelCasedClass.new.backend_form_title.should=="<h2>#{CamelCasedClass.new.to_label}</h2>" # New
105
+ TopFive[1].backend_form_title.should=="<h2>Edit #{TopFive[1].to_label}</h2>" # No label
106
+ Author[1].backend_form_title.should=="<h2>Edit #{Author[1].to_label}</h2>" # Label
107
+ end
108
+
109
+ should 'Include title in the form' do
110
+ Author[1].backend_form('/url').should.match(/#{Regexp.escape(Author[1].backend_form_title)}/)
92
111
  end
93
112
 
94
113
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-backend-api
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mickael Riga
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-27 00:00:00 +01:00
18
+ date: 2011-08-05 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21