ixtlan 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/Manifest.txt +64 -0
  2. data/README.txt +86 -0
  3. data/Rakefile +38 -0
  4. data/generators/ixtlan_datamapper_model/ixtlan_datamapper_model_generator.rb +20 -0
  5. data/generators/ixtlan_datamapper_model/templates/model.rb +17 -0
  6. data/generators/ixtlan_datamapper_rspec_model/ixtlan_datamapper_rspec_model_generator.rb +20 -0
  7. data/generators/ixtlan_datamapper_rspec_model/templates/model_spec.rb +58 -0
  8. data/generators/ixtlan_datamapper_rspec_scaffold/ixtlan_datamapper_rspec_scaffold_generator.rb +37 -0
  9. data/generators/ixtlan_datamapper_rspec_scaffold/templates/controller.rb +99 -0
  10. data/generators/ixtlan_datamapper_rspec_scaffold/templates/controller_spec.rb +206 -0
  11. data/generators/ixtlan_datamapper_rspec_scaffold/templates/guard.rb +8 -0
  12. data/generators/ixtlan_datamapper_rspec_scaffold/templates/i18n.rb +11 -0
  13. data/lib/dm-serializer/common.rb +28 -0
  14. data/lib/dm-serializer/to_xml.rb +99 -0
  15. data/lib/dm-serializer/xml_serializers/libxml.rb +42 -0
  16. data/lib/dm-serializer/xml_serializers/nokogiri.rb +36 -0
  17. data/lib/dm-serializer/xml_serializers/rexml.rb +30 -0
  18. data/lib/dm-serializer/xml_serializers.rb +17 -0
  19. data/lib/dm-serializer.rb +1 -0
  20. data/lib/ixtlan/audit_config.rb +35 -0
  21. data/lib/ixtlan/cms_script.rb +29 -0
  22. data/lib/ixtlan/controllers/texts_controller.rb +65 -0
  23. data/lib/ixtlan/digest.rb +15 -0
  24. data/lib/ixtlan/error_notifier/error_notification.rhtml +1 -0
  25. data/lib/ixtlan/guard.rb +125 -0
  26. data/lib/ixtlan/logger_config.rb +65 -0
  27. data/lib/ixtlan/models/authentication.rb +30 -0
  28. data/lib/ixtlan/models/configuration.rb +74 -0
  29. data/lib/ixtlan/models/configuration_locale.rb +19 -0
  30. data/lib/ixtlan/models/group.rb +69 -0
  31. data/lib/ixtlan/models/group_locale_user.rb +22 -0
  32. data/lib/ixtlan/models/group_user.rb +39 -0
  33. data/lib/ixtlan/models/locale.rb +37 -0
  34. data/lib/ixtlan/models/permission.rb +29 -0
  35. data/lib/ixtlan/models/phrase.rb +71 -0
  36. data/lib/ixtlan/models/role.rb +35 -0
  37. data/lib/ixtlan/models/text.rb +140 -0
  38. data/lib/ixtlan/models/translation.rb +40 -0
  39. data/lib/ixtlan/models/user.rb +112 -0
  40. data/lib/ixtlan/models/word.rb +12 -0
  41. data/lib/ixtlan/models.rb +13 -0
  42. data/lib/ixtlan/modified_by.rb +80 -0
  43. data/lib/ixtlan/monkey_patches.rb +38 -0
  44. data/lib/ixtlan/optimistic_persistence.rb +20 -0
  45. data/lib/ixtlan/optimistic_persistence_module.rb +22 -0
  46. data/lib/ixtlan/optimistic_persistence_validation.rb +21 -0
  47. data/lib/ixtlan/passwords.rb +19 -0
  48. data/lib/ixtlan/rails/audit.rb +22 -0
  49. data/lib/ixtlan/rails/error_handling.rb +130 -0
  50. data/lib/ixtlan/rails/guard.rb +11 -0
  51. data/lib/ixtlan/rails/session_timeout.rb +93 -0
  52. data/lib/ixtlan/rails/timestamps_modified_by_filter.rb +33 -0
  53. data/lib/ixtlan/rails/unrestful_authentication.rb +137 -0
  54. data/lib/ixtlan/rolling_file.rb +61 -0
  55. data/lib/ixtlan/session.rb +18 -0
  56. data/lib/ixtlan/user_logger.rb +49 -0
  57. data/lib/ixtlan/version.rb +3 -0
  58. data/lib/ixtlan.rb +2 -0
  59. data/lib/models.rb +14 -0
  60. data/spec/authentication_spec.rb +30 -0
  61. data/spec/guard_spec.rb +125 -0
  62. data/spec/guards/samples.rb +12 -0
  63. data/spec/spec.opts +1 -0
  64. data/spec/spec_helper.rb +170 -0
  65. metadata +210 -0
data/Manifest.txt ADDED
@@ -0,0 +1,64 @@
1
+ generators/ixtlan_datamapper_model/ixtlan_datamapper_model_generator.rb
2
+ generators/ixtlan_datamapper_model/templates/model.rb
3
+ generators/ixtlan_datamapper_rspec_model/ixtlan_datamapper_rspec_model_generator.rb
4
+ generators/ixtlan_datamapper_rspec_model/templates/model_spec.rb
5
+ generators/ixtlan_datamapper_rspec_scaffold/ixtlan_datamapper_rspec_scaffold_generator.rb
6
+ generators/ixtlan_datamapper_rspec_scaffold/templates/controller.rb
7
+ generators/ixtlan_datamapper_rspec_scaffold/templates/controller_spec.rb
8
+ generators/ixtlan_datamapper_rspec_scaffold/templates/guard.rb
9
+ generators/ixtlan_datamapper_rspec_scaffold/templates/i18n.rb
10
+ lib/models.rb
11
+ lib/ixtlan.rb
12
+ lib/dm-serializer.rb
13
+ lib/dm-serializer/xml_serializers/libxml.rb
14
+ lib/dm-serializer/xml_serializers/nokogiri.rb
15
+ lib/dm-serializer/xml_serializers/rexml.rb
16
+ lib/dm-serializer/common.rb
17
+ lib/dm-serializer/xml_serializers.rb
18
+ lib/dm-serializer/to_xml.rb
19
+ lib/ixtlan/models/group_locale_user.rb
20
+ lib/ixtlan/models/role.rb
21
+ lib/ixtlan/models/phrase.rb
22
+ lib/ixtlan/models/translation.rb
23
+ lib/ixtlan/models/user.rb
24
+ lib/ixtlan/models/permission.rb
25
+ lib/ixtlan/models/locale.rb
26
+ lib/ixtlan/models/configuration_locale.rb
27
+ lib/ixtlan/models/word.rb
28
+ lib/ixtlan/models/configuration.rb
29
+ lib/ixtlan/models/authentication.rb
30
+ lib/ixtlan/models/text.rb
31
+ lib/ixtlan/models/group_user.rb
32
+ lib/ixtlan/models/group.rb
33
+ lib/ixtlan/rolling_file.rb
34
+ lib/ixtlan/cms_script.rb
35
+ lib/ixtlan/logger_config.rb
36
+ lib/ixtlan/models.rb
37
+ lib/ixtlan/audit_config.rb
38
+ lib/ixtlan/session.rb
39
+ lib/ixtlan/optimistic_persistence.rb
40
+ lib/ixtlan/monkey_patches.rb
41
+ lib/ixtlan/modified_by.rb
42
+ lib/ixtlan/optimistic_persistence_module.rb
43
+ lib/ixtlan/optimistic_persistence_validation.rb
44
+ lib/ixtlan/error_notifier/error_notification.rhtml
45
+ lib/ixtlan/controllers/texts_controller.rb
46
+ lib/ixtlan/guard.rb
47
+ lib/ixtlan/rails/audit.rb
48
+ lib/ixtlan/rails/error_handling.rb
49
+ lib/ixtlan/rails/unrestful_authentication.rb
50
+ lib/ixtlan/rails/session_timeout.rb
51
+ lib/ixtlan/rails/timestamps_modified_by_filter.rb
52
+ lib/ixtlan/rails/guard.rb
53
+ lib/ixtlan/passwords.rb
54
+ lib/ixtlan/digest.rb
55
+ lib/ixtlan/version.rb
56
+ lib/ixtlan/user_logger.rb
57
+ Manifest.txt
58
+ Rakefile
59
+ README.txt
60
+ spec/authentication_spec.rb
61
+ spec/guard_spec.rb
62
+ spec/guards/samples.rb
63
+ spec/spec_helper.rb
64
+ spec/spec.opts
data/README.txt ADDED
@@ -0,0 +1,86 @@
1
+ = ixtlan core
2
+
3
+ * http://github.com/mkristian/ixtlan-core
4
+
5
+ == DESCRIPTION:
6
+
7
+ this is set of rails and datamapper plugins for setting up a little more advanced rails application then the default rails generator does. the focus is on security and privacy as well a complete restful xml support.
8
+
9
+ === features
10
+
11
+ * usermanagement: user, group, locale
12
+
13
+ * authentication: session based authentication for both html as well restful xml
14
+
15
+ * authorization: each controller/action pair has a set of allowed roles
16
+
17
+ * privacy: configurable duration for logfiles carrying user specific data. error logs are dumped (complete environment including user specific data as well) and the file location is sent as notification
18
+
19
+ * session idle timeout: configurable server side session idle timeout
20
+
21
+ * audit: a simple log file which documents the action of a user - one action per line
22
+
23
+ * optimistic transaction: through an exception on modification of stale resources
24
+
25
+ * easy add modified_by attributes to a resource and ensure the user gets set before saving such a resource
26
+
27
+ * logger configuration tries to unify logging
28
+
29
+ * basic scaffold like html interface for user,group,locale
30
+
31
+ * rails template setting up such an application - works for both ruby as well jruby
32
+
33
+ * http cache headers so that no data gets save on any proxy or filesystem (as long the user is logged in)
34
+
35
+ * global config: extra configuration file which can carry the all the production passwords and can be left out from the (public) version control system: config/preinitializer.rb for rails and config/global.yml
36
+
37
+ === TODOs
38
+
39
+ * session timeout on html pages so the browser displays the login page after timetout (little modification of the layout.html.erb)
40
+
41
+ * user, group, locale to work also with ldap
42
+
43
+ * html interface for configuration, user profile
44
+
45
+ * setup database specific logger for data_objects - each driver has its own logger
46
+
47
+ * maintanance mode: allow only users who belong to the superuser group
48
+
49
+ * change the db config to have #{RAILS_ROOT} in front of relative filenames to work inside an servlet engine (ixtlan_rails_templates.rb)
50
+
51
+ * locale binding to user/group
52
+
53
+ == user management and authorization
54
+
55
+ each user can belong to one or more groups, each user/group pair can belong to one or more locales. this part can be configured by an admin by changing resource relationships.
56
+
57
+ === authorization
58
+
59
+ each controller/action pair has a set of allowed roles. authorization is granted if on of roles match with one of the groups of the current user (logged in user). this is done by a before filter in rails: guard. the user interface can introspect the guard to allow the user only the actions which s/he actually can be performe. in case some actions needs to verify the locale binding a specialized before filter needs to be implemented.
60
+
61
+ the roles are currently hardcoded in app/guards/XYZ_guard.rb - one guard for each controller.
62
+
63
+ == LICENSE:
64
+
65
+ (The MIT License)
66
+
67
+ Copyright (c) 2009 Kristian Meier
68
+
69
+ Permission is hereby granted, free of charge, to any person obtaining
70
+ a copy of this software and associated documentation files (the
71
+ 'Software'), to deal in the Software without restriction, including
72
+ without limitation the rights to use, copy, modify, merge, publish,
73
+ distribute, sublicense, and/or sell copies of the Software, and to
74
+ permit persons to whom the Software is furnished to do so, subject to
75
+ the following conditions:
76
+
77
+ The above copyright notice and this permission notice shall be
78
+ included in all copies or substantial portions of the Software.
79
+
80
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
81
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
82
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
83
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
84
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
85
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
86
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/ixtlan/version.rb'
6
+
7
+ require 'spec'
8
+ require 'spec/rake/spectask'
9
+ require 'pathname'
10
+ require 'yard'
11
+
12
+ Hoe.spec('ixtlan') do |p|
13
+ p.developer('mkristian', 'm.kristian@web.de')
14
+ p.extra_deps = [['dm-core', '~>0.10.1'], ['dm-validations', '~>0.10.1'], ['dm-timestamps', '~>0.10.1'], ['dm-migrations', '~>0.10.1'], ['slf4r', '~>0.2.0'], ['datamapper4rails', '~>0.3.2'],['rack-datamapper', '~>0.2.5'], ['logging', '~>1.2.3']]
15
+ p.rspec_options << '--options' << 'spec/spec.opts'
16
+ end
17
+
18
+ desc 'Install the package as a gem.'
19
+ task :install => [:clean, :package] do
20
+ gem = Dir['pkg/*.gem'].first
21
+ sh "gem install --local #{gem} --no-ri --no-rdoc"
22
+ end
23
+
24
+ desc 'generate rails using all generators and run the specs'
25
+ task :integration_tests => [:spec, :install] do
26
+ require 'datamapper4rails/integration_test'
27
+ Datamapper4Rails::IntegrationTest.new do |t|
28
+ t.directory = 'temp'
29
+ t.rails_template = 'ixtlan_rails_templates.rb'
30
+ t.generate "ixtlan_datamapper_model name name:string"
31
+ t.generate "ixtlan_datamapper_rspec_model domain name:string"
32
+ t.generate "ixtlan_datamapper_rspec_scaffold word name:string"
33
+ end
34
+ end
35
+
36
+ YARD::Rake::YardocTask.new
37
+
38
+ # vim: syntax=Ruby
@@ -0,0 +1,20 @@
1
+ require 'rails_generator/generators/components/model/model_generator'
2
+ require 'active_record'
3
+ require 'datamapper4rails/overlay'
4
+
5
+ class IxtlanDatamapperModelGenerator < DatamapperModelGenerator
6
+
7
+ def manifest
8
+ overlay_dirs.add_generator("datamapper_model")
9
+ super
10
+ end
11
+
12
+ def add_options!(opt)
13
+ opt.separator ''
14
+ opt.separator 'Options:'
15
+ opt.on("--skip-timestamps",
16
+ "Don't add timestamps for this model") { |v| options[:skip_timestamps] = v }
17
+ opt.on("--skip-modified-by",
18
+ "Don't add modified_by references for this model") { |v| options[:skip_modified_by] = v }
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ class <%= class_name %>
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ <% Array(attributes).each do |attribute| -%>
6
+ property :<%= attribute.name %>, <%= attribute.type.to_s.capitalize %>, :nullable => false <% if attribute.type == :string or attribute.type == :text or attribute.type == :slug -%>, :format => /^[^<'&">]*$/<% if attribute.type == :string or attribute.type == :slug %>, :length => 255<% end -%><% end -%>
7
+
8
+ <% end -%>
9
+ <% unless options[:skip_timestamps] -%>
10
+ timestamps :at
11
+ <% end -%>
12
+
13
+ <% unless options[:skip_modified_by] -%>
14
+ modified_by "Ixtlan::Models::User"
15
+ <% end -%>
16
+
17
+ end
@@ -0,0 +1,20 @@
1
+ require 'rails_generator/generators/components/model/model_generator'
2
+ require 'active_record'
3
+ require 'datamapper4rails/overlay'
4
+
5
+ class IxtlanDatamapperRspecModelGenerator < DatamapperRspecModelGenerator
6
+
7
+ def manifest
8
+ overlay_dirs.add_generator("ixtlan_datamapper_model")
9
+ super
10
+ end
11
+
12
+ def add_options!(opt)
13
+ opt.separator ''
14
+ opt.separator 'Options:'
15
+ opt.on("--skip-timestamps",
16
+ "Don't add timestamps for this model") { |v| options[:skip_timestamps] = v }
17
+ opt.on("--skip-modified-by",
18
+ "Don't add modified_by references for this model") { |v| options[:skip_modified_by] = v }
19
+ end
20
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper')
2
+
3
+ describe <%= class_name %> do
4
+ before(:each) do
5
+ <% unless options[:skip_modified_by] -%>
6
+ user = Ixtlan::Models::User.first
7
+ unless user
8
+ user = Ixtlan::Models::User.new(:login => 'root', :email => 'root@exmple.com', :name => 'Superuser', :language => 'en', :id => 1, :created_at => DateTime.now, :updated_at => DateTime.now)
9
+ user.created_by_id = 1
10
+ user.updated_by_id = 1
11
+ user.save!
12
+ end
13
+ <% end -%>
14
+ @valid_attributes = {
15
+ <% unless options[:skip_modified_by] -%>
16
+ :current_user => user,
17
+ <% end -%>
18
+ <% attributes.each_with_index do |attribute, attribute_index| -%>
19
+ :<%= attribute.name %> => <%= attribute.default_value %><%= attribute_index == attributes.length - 1 ? '' : ','%>
20
+ <% end -%>
21
+ }
22
+ end
23
+
24
+ it "should create a new instance given valid attributes" do
25
+ <%= singular_name %> = <%= class_name %>.create(@valid_attributes)
26
+ <%= singular_name %>.valid?.should be_true
27
+ end
28
+
29
+ <% attributes.each do |attribute| -%>
30
+ it "should require <%= attribute.name %>" do
31
+ <%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => nil))
32
+ <%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
33
+ end
34
+
35
+ <% if [:string, :text, :slug].member? attribute.type -%>
36
+ it 'should not match <%= attribute.name %>' do
37
+ <%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "<script" ))
38
+ <%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
39
+ <%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "sc'ript" ))
40
+ <%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
41
+ <%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "scr&ipt" ))
42
+ <%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
43
+ <%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => 'scr"ipt' ))
44
+ <%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
45
+ <%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "script>" ))
46
+ <%= singular_name %>.errors.on(:<%= attribute.name %>).should_not == nil
47
+ end
48
+
49
+ <% elsif [:integer, :big_decimal, :float].member? attribute.type %>
50
+ it "should be numerical <%= attribute.name %>" do
51
+ <%= singular_name %> = <%= class_name %>.create(@valid_attributes.merge(:<%= attribute.name %> => "none-numberic" ))
52
+ <%= singular_name %>.<%= attribute.name %>.to_i.should == 0
53
+ <%= singular_name %>.errors.size.should == 1
54
+ end
55
+
56
+ <% end -%>
57
+ <% end -%>
58
+ end
@@ -0,0 +1,37 @@
1
+ require 'datamapper4rails/overlay'
2
+ require 'datamapper4rails/rspec_default_values'
3
+
4
+ class IxtlanDatamapperRspecScaffoldGenerator < DatamapperRspecScaffoldGenerator
5
+
6
+ def manifest
7
+ overlay_dirs.add_generator("ixtlan_datamapper_model")
8
+ overlay_dirs.add_generator("ixtlan_datamapper_rspec_model")
9
+ overlay_dirs.add_generator("datamapper_rspec_scaffold")
10
+
11
+ m = super
12
+
13
+ unless options[:skip_guard]
14
+ m.directory(File.join('app/guards', controller_class_path))
15
+ m.template 'guard.rb', File.join('app/guards', controller_class_path, "#{table_name}_guard.rb")
16
+ end
17
+
18
+ if options[:i18n]
19
+ m.directory(File.join('config/locales', controller_class_path))
20
+ m.template 'i18n.rb', File.join('config/locales', controller_class_path, "#{table_name}.yml")
21
+ end
22
+
23
+ m
24
+ end
25
+
26
+ def add_options!(opt)
27
+ super
28
+ opt.on("--skip-timestamps",
29
+ "Don't add timestamps for this model") { |v| options[:skip_timestamps] = v }
30
+ opt.on("--skip-modified-by",
31
+ "Don't add modified_by references for this model") { |v| options[:skip_modified_by] = v }
32
+ opt.on("--skip-guard",
33
+ "Don't add guards for the actions on this model") { |v| options[:add_guard] = v }
34
+ opt.on("--i18n",
35
+ "Use i18n keys instead of text") { |v| options[:i18n] = v }
36
+ end
37
+ end
@@ -0,0 +1,99 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+
3
+ # GET /<%= table_name %>
4
+ # GET /<%= table_name %>.xml
5
+ def index
6
+ @<%= table_name %> = <%= class_name %>.all()
7
+
8
+ respond_to do |format|
9
+ format.html
10
+ format.xml { render :xml => @<%= table_name %> }
11
+ end
12
+ end
13
+
14
+ # GET /<%= table_name %>/1
15
+ # GET /<%= table_name %>/1.xml
16
+ def show
17
+ @<%= file_name %> = <%= class_name %>.get!(params[:id])
18
+
19
+ respond_to do |format|
20
+ format.html # show.html.erb
21
+ format.xml { render :xml => @<%= file_name %> }
22
+ end
23
+ end
24
+
25
+ # GET /<%= table_name %>/new
26
+ # GET /<%= table_name %>/new.xml
27
+ def new
28
+ @<%= file_name %> = <%= class_name %>.new
29
+
30
+ respond_to do |format|
31
+ format.html # new.html.erb
32
+ format.xml { render :xml => @<%= file_name %> }
33
+ end
34
+ end
35
+
36
+ # GET /<%= table_name %>/1/edit
37
+ def edit
38
+ @<%= file_name %> = <%= class_name %>.get!(params[:id])
39
+ end
40
+
41
+ # POST /<%= table_name %>
42
+ # POST /<%= table_name %>.xml
43
+ def create
44
+ @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>])
45
+ <% unless options[:skip_modified_by] -%>
46
+ @<%= file_name %>.current_user = current_user
47
+ <% end -%>
48
+
49
+ respond_to do |format|
50
+ if @<%= file_name %>.save
51
+ flash[:notice] = <% if options[:i18n] -%>t('<%= plural_name %>.<%= singular_name %>_created')<% else -%>'<%= class_name %> was successfully created.'<% end -%>
52
+
53
+ format.html { redirect_to(<%= file_name %>_url(@<%= file_name %>.id)) }
54
+ format.xml { render :xml => @<%= file_name %>, :status => :created, :location => <%= file_name %>_url(@<%= file_name %>.id) + ".xml" }
55
+ else
56
+ format.html { render :action => "new" }
57
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
58
+ end
59
+ end
60
+ end
61
+
62
+ # PUT /<%= table_name %>/1
63
+ # PUT /<%= table_name %>/1.xml
64
+ def update
65
+ @<%= file_name %> = <%= class_name %>.get!(params[:id])
66
+ <% unless options[:skip_modified_by] -%>
67
+ @<%= file_name %>.current_user = current_user
68
+ <% end -%>
69
+
70
+ respond_to do |format|
71
+ if @<%= file_name %>.update(params[:<%= file_name %>]) or not @<%= file_name %>.dirty?
72
+ flash[:notice] = <% if options[:i18n] -%>t('<%= plural_name %>.<%= singular_name %>_updated')<% else -%>'<%= class_name %> was successfully updated.'<% end -%>
73
+
74
+ format.html { redirect_to(<%= file_name %>_url(@<%= file_name %>.id)) }
75
+ format.xml { render :xml => @<%= file_name %> }
76
+ else
77
+ format.html { render :action => "edit" }
78
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
79
+ end
80
+ end
81
+ end
82
+
83
+ # DELETE /<%= table_name %>/1
84
+ # DELETE /<%= table_name %>/1.xml
85
+ def destroy
86
+ @<%= file_name %> = <%= class_name %>.get(params[:id])
87
+ <% unless options[:skip_modified_by] -%>
88
+ @<%= file_name %>.current_user = current_user
89
+ <% end -%>
90
+ @<%= file_name %>.destroy if @<%= file_name %>
91
+
92
+ respond_to do |format|
93
+ flash[:notice] = <% if options[:i18n] -%>t('<%= plural_name %>.<%= singular_name %>_deleted')<% else -%>'<%= class_name %> was successfully deleted.'<% end -%>
94
+
95
+ format.html { redirect_to(<%= table_name %>_url) }
96
+ format.xml { head :ok }
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,206 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper')
2
+
3
+ describe <%= controller_class_name %>Controller do
4
+
5
+ def mock_<%= file_name %>(stubs={})
6
+ @mock_<%= file_name %> ||= mock_model(<%= class_name %>, stubs)
7
+ end
8
+
9
+ def mock_array(*args)
10
+ a = args
11
+ def a.model
12
+ <%= class_name %>
13
+ end
14
+ a
15
+ end
16
+
17
+ def mock_arguments(merge = {})
18
+ args = merge
19
+ <% unless options[:skip_modified_by] -%>
20
+ args.merge!(:current_user= => nil)
21
+ <% end -%>
22
+ <% unless options[:skip_audit] -%>
23
+ args.merge!(:model => <%= class_name %>, :key => 12)
24
+ <% end -%>
25
+ args
26
+ end
27
+
28
+ <% unless options[:skip_guard] -%>
29
+ before(:each) do
30
+ user = Ixtlan::Models::User.new(:id => 1, :login => 'root')
31
+ def user.groups
32
+ [Ixtlan::Models::Group.new(:name => "root")]
33
+ end
34
+ controller.send(:current_user=, user)
35
+ mock_configuration = mock_model(Ixtlan::Models::Configuration,{})
36
+ Ixtlan::Models::Configuration.should_receive(:instance).any_number_of_times.and_return(mock_configuration)
37
+ mock_configuration.should_receive(:session_idle_timeout).any_number_of_times.and_return(1)
38
+ end
39
+ <% end -%>
40
+
41
+ describe "GET index" do
42
+
43
+ it "exposes all <%= table_name %> as @<%= table_name %>" do
44
+ <%= class_name %>.should_receive(:all).and_return(mock_array(mock_<%= file_name %>))
45
+ get :index
46
+ assigns[:<%= table_name %>].should == mock_array(mock_<%= file_name %>)
47
+ end
48
+
49
+ describe "with mime type of xml" do
50
+
51
+ it "renders all <%= table_name.pluralize %> as xml" do
52
+ <%= class_name %>.should_receive(:all).and_return(<%= file_name.pluralize %> = mock_array("Array of <%= class_name.pluralize %>"))
53
+ <%= file_name.pluralize %>.should_receive(:to_xml).and_return("generated XML")
54
+ get :index, :format => 'xml'
55
+ response.body.should == "generated XML"
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ describe "GET show" do
63
+
64
+ it "exposes the requested <%= file_name %> as @<%= file_name %>" do
65
+ <%= class_name %>.should_receive(:get!).with("37").and_return(mock_<%= file_name %>(mock_arguments))
66
+ get :show, :id => "37"
67
+ assigns[:<%= file_name %>].should equal(mock_<%= file_name %>)
68
+ end
69
+
70
+ describe "with mime type of xml" do
71
+
72
+ it "renders the requested <%= file_name %> as xml" do
73
+ <%= class_name %>.should_receive(:get!).with("37").and_return(mock_<%= file_name %>(mock_arguments))
74
+ mock_<%= file_name %>.should_receive(:to_xml).and_return("generated XML")
75
+ get :show, :id => "37", :format => 'xml'
76
+ response.body.should == "generated XML"
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+
83
+ describe "GET new" do
84
+
85
+ it "exposes a new <%= file_name %> as @<%= file_name %>" do
86
+ <%= class_name %>.should_receive(:new).and_return(mock_<%= file_name %>(mock_arguments))
87
+ get :new
88
+ assigns[:<%= file_name %>].should equal(mock_<%= file_name %>)
89
+ end
90
+
91
+ end
92
+
93
+ describe "GET edit" do
94
+
95
+ it "exposes the requested <%= file_name %> as @<%= file_name %>" do
96
+ <%= class_name %>.should_receive(:get!).with("37").and_return(mock_<%= file_name %>(mock_arguments))
97
+ get :edit, :id => "37"
98
+ assigns[:<%= file_name %>].should equal(mock_<%= file_name %>)
99
+ end
100
+
101
+ end
102
+
103
+ describe "POST create" do
104
+
105
+ describe "with valid params" do
106
+
107
+ it "exposes a newly created <%= file_name %> as @<%= file_name %>" do
108
+ <%= class_name %>.should_receive(:new).with({'these' => 'params'}).and_return(mock_<%= file_name %>(mock_arguments(:save => true)))
109
+ post :create, :<%= file_name %> => {:these => 'params'}
110
+ assigns(:<%= file_name %>).should equal(mock_<%= file_name %>)
111
+ end
112
+
113
+ it "redirects to the created <%= file_name %>" do
114
+ <%= class_name %>.stub!(:new).and_return(mock_<%= file_name %>(mock_arguments(:save => true)))
115
+ post :create, :<%= file_name %> => {}
116
+ response.should redirect_to(<%= table_name.singularize %>_url(mock_<%= file_name %>))
117
+ end
118
+
119
+ end
120
+
121
+ describe "with invalid params" do
122
+
123
+ it "exposes a newly created but unsaved <%= file_name %> as @<%= file_name %>" do
124
+ <%= class_name %>.stub!(:new).with({'these' => 'params'}).and_return(mock_<%= file_name %>(mock_arguments(:save => false)))
125
+ post :create, :<%= file_name %> => {:these => 'params'}
126
+ assigns(:<%= file_name %>).should equal(mock_<%= file_name %>)
127
+ end
128
+
129
+ it "re-renders the 'new' template" do
130
+ <%= class_name %>.stub!(:new).and_return(mock_<%= file_name %>(mock_arguments(:save => false)))
131
+ post :create, :<%= file_name %> => {}
132
+ response.should render_template('new')
133
+ end
134
+
135
+ end
136
+
137
+ end
138
+
139
+ describe "PUT udpate" do
140
+
141
+ describe "with valid params" do
142
+
143
+ it "updates the requested <%= file_name %>" do
144
+ <%= class_name %>.should_receive(:get!).with("37").and_return(mock_<%= file_name %>(mock_arguments))
145
+ mock_<%= file_name %>.should_receive(:update).with({'these' => 'params'})
146
+ mock_<%= file_name %>.should_receive(:dirty?)
147
+ put :update, :id => "37", :<%= file_name %> => {:these => 'params'}
148
+ end
149
+
150
+ it "exposes the requested <%= file_name %> as @<%= file_name %>" do
151
+ <%= class_name %>.stub!(:get!).and_return(mock_<%= file_name %>(mock_arguments(:update => true)))
152
+ put :update, :id => "1"
153
+ assigns(:<%= file_name %>).should equal(mock_<%= file_name %>)
154
+ end
155
+
156
+ it "redirects to the <%= file_name %>" do
157
+ <%= class_name %>.stub!(:get!).and_return(mock_<%= file_name %>(mock_arguments(:update => true)))
158
+ put :update, :id => "1"
159
+ response.should redirect_to(<%= table_name.singularize %>_url(mock_<%= file_name %>))
160
+ end
161
+
162
+ end
163
+
164
+ describe "with invalid params" do
165
+
166
+ it "updates the requested <%= file_name %>" do
167
+ <%= class_name %>.should_receive(:get!).with("37").and_return(mock_<%= file_name %>(mock_arguments))
168
+ mock_<%= file_name %>.should_receive(:update).with({'these' => 'params'})
169
+ mock_<%= file_name %>.should_receive(:dirty?)
170
+ put :update, :id => "37", :<%= file_name %> => {:these => 'params'}
171
+ end
172
+
173
+ it "exposes the <%= file_name %> as @<%= file_name %>" do
174
+ <%= class_name %>.stub!(:get!).and_return(mock_<%= file_name %>(mock_arguments(:update => false)))
175
+ mock_<%= file_name %>.should_receive(:dirty?)
176
+ put :update, :id => "1"
177
+ assigns(:<%= file_name %>).should equal(mock_<%= file_name %>)
178
+ end
179
+
180
+ it "re-renders the 'edit' template" do
181
+ <%= class_name %>.stub!(:get!).and_return(mock_<%= file_name %>(mock_arguments(:update => false, :dirty? => true)))
182
+ put :update, :id => "1"
183
+ response.should render_template('edit')
184
+ end
185
+
186
+ end
187
+
188
+ end
189
+
190
+ describe "DELETE destroy" do
191
+
192
+ it "destroys the requested <%= file_name %>" do
193
+ <%= class_name %>.should_receive(:get).with("37").and_return(mock_<%= file_name %>(mock_arguments))
194
+ mock_<%= file_name %>.should_receive(:destroy)
195
+ delete :destroy, :id => "37"
196
+ end
197
+
198
+ it "redirects to the <%= table_name %> list" do
199
+ <%= class_name %>.should_receive(:get).with("1").and_return(mock_<%= file_name %>(mock_arguments(:destroy => true)))
200
+ delete :destroy, :id => "1"
201
+ response.should redirect_to(<%= table_name %>_url)
202
+ end
203
+
204
+ end
205
+
206
+ end
@@ -0,0 +1,8 @@
1
+ Ixtlan::Guard.initialize(:<%= table_name %>,
2
+ { :index => [],
3
+ :show => [],
4
+ :edit => [],
5
+ :update => [],
6
+ :new => [],
7
+ :create => [],
8
+ :destroy => [] })
@@ -0,0 +1,11 @@
1
+ en:
2
+ <%= plural_name %>:
3
+ <%= singular_name %>_created: <%= class_name %> was successfully created.
4
+ <%= singular_name %>_updated: <%= class_name %> was successfully updated.
5
+ <%= singular_name %>_deleted: <%= class_name %> was successfully deleted.
6
+ new_<%= singular_name %>: new <%= singular_name %>
7
+ <%= singular_name %>: <%= singular_name %>
8
+ list: <%= singular_name %>list
9
+ <% for attribute in attributes -%>
10
+ <%= attribute.column.name %>: <%= attribute.column.human_name %>
11
+ <% end -%>