ixtlan 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.
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 -%>