lesli 5.0.23 → 5.1.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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/lesli/application.css +1 -192
  3. data/app/controllers/lesli/abouts_controller.rb +1 -1
  4. data/app/controllers/lesli/{items → item}/activities_controller.rb +1 -1
  5. data/app/controllers/lesli/item/discussions_controller.rb +126 -0
  6. data/app/controllers/lesli/item/tasks_controller.rb +126 -0
  7. data/app/helpers/lesli/customization_helper.rb +1 -1
  8. data/app/helpers/lesli/html_helper.rb +1 -1
  9. data/app/models/concerns/lesli/item/activities.rb +106 -0
  10. data/app/models/concerns/lesli/item/discussions.rb +92 -0
  11. data/app/models/concerns/lesli/item/tasks.rb +95 -0
  12. data/app/models/lesli/account.rb +1 -0
  13. data/app/models/lesli/{items → item}/activity.rb +5 -13
  14. data/app/models/lesli/item/discussion.rb +10 -0
  15. data/{lib/lesli/r_spec.rb → app/models/lesli/item/task.rb} +9 -10
  16. data/app/views/lesli/partials/_application-lesli-header.html.erb +12 -0
  17. data/config/initializers/lesli_migration_helpers.rb +2 -2
  18. data/db/migrate/v1/0000000210_create_lesli_users.rb +1 -1
  19. data/lib/generators/lesli/base_generator.rb +172 -0
  20. data/lib/generators/lesli/controller/controller_generator.rb +40 -0
  21. data/lib/generators/lesli/controller/templates/controller.rb.tt +86 -0
  22. data/lib/generators/lesli/install/install_generator.rb +1 -1
  23. data/lib/generators/lesli/model/model_generator.rb +44 -0
  24. data/lib/generators/lesli/model/templates/model.rb.tt +16 -0
  25. data/lib/generators/lesli/scaffold/scaffold_generator.rb +47 -0
  26. data/lib/generators/lesli/service/service_generator.rb +40 -0
  27. data/lib/generators/lesli/service/templates/service.rb.tt +44 -0
  28. data/lib/generators/lesli/views/templates/_form.html.erb.tt +22 -0
  29. data/lib/generators/lesli/views/templates/index.html.erb.tt +17 -0
  30. data/lib/generators/lesli/views/templates/new.html.erb.tt +4 -0
  31. data/lib/generators/lesli/views/templates/show.html.erb.tt +22 -0
  32. data/lib/generators/lesli/views/views_generator.rb +106 -0
  33. data/lib/lesli/engine.rb +1 -23
  34. data/lib/lesli/router.rb +42 -43
  35. data/lib/lesli/version.rb +2 -2
  36. data/lib/migrate/common.rb +1 -1
  37. data/lib/migrate/items/activity_structure.rb +11 -5
  38. data/lib/migrate/items/discussion_structure.rb +9 -3
  39. data/lib/migrate/items/{action_structure.rb → task_structure.rb} +12 -6
  40. data/lib/migrate/shared/catalog_structure.rb +16 -0
  41. data/lib/tasks/lesli/db.rake +9 -0
  42. data/readme.md +1 -1
  43. metadata +58 -79
  44. data/app/assets/config/lesli_manifest.js +0 -42
  45. data/app/assets/images/lesli/brand/app-auth.svg +0 -9
  46. data/app/assets/images/lesli/brand/app-icon.svg +0 -48
  47. data/app/assets/images/lesli/brand/app-logo.png +0 -0
  48. data/app/assets/images/lesli/brand/app-logo.svg +0 -4
  49. data/app/assets/images/lesli/brand/favicon.png +0 -0
  50. data/app/assets/images/lesli/brand/favicon.svg +0 -61
  51. data/app/assets/images/lesli/brand/login-background.jpg +0 -0
  52. data/app/assets/images/lesli/brand/register-background.jpg +0 -0
  53. data/app/assets/javascripts/lesli/application.js +0 -1
  54. data/app/controllers/lesli/items/actions_controller.rb +0 -122
  55. data/app/controllers/lesli/items/discussions_controller.rb +0 -93
  56. data/app/models/lesli/items/action.rb +0 -15
  57. data/app/models/lesli/items/discussion.rb +0 -15
  58. data/config/importmap.rb +0 -1
  59. data/db/structure/00000000_locations.json +0 -32
  60. data/db/structure/00000020_catalogs.json +0 -0
  61. data/db/structure/00000201_workflows.json +0 -17
  62. data/db/structure/00000202_workflow_statuses.json +0 -24
  63. data/db/structure/00000203_workflow_associations.json +0 -14
  64. data/db/structure/00000204_workflow_actions.json +0 -39
  65. data/db/structure/00000205_workflow_checks.json +0 -27
  66. data/db/structure/00000300_custom_fields.json +0 -8
  67. data/db/structure/00000301_custom_fields.json +0 -38
  68. data/db/structure/00000401_custom_validations.json +0 -14
  69. data/db/structure/00000402_custom_validation_rules.json +0 -23
  70. data/db/structure/00000403_custom_validation_fields.json +0 -14
  71. data/lib/generators/application_lesli_generator_base.rb +0 -164
  72. data/lib/generators/lesli/spec/USAGE +0 -8
  73. data/lib/generators/lesli/spec/spec_generator.rb +0 -22
  74. data/lib/generators/lesli/spec/templates/spec-factory.template +0 -17
  75. data/lib/generators/lesli/spec/templates/spec-model.template +0 -70
  76. data/lib/generators/lesli/view/USAGE +0 -8
  77. data/lib/generators/lesli/view/templates/spec-factory.template +0 -17
  78. data/lib/generators/lesli/view/templates/spec-model.template +0 -70
  79. data/lib/generators/lesli/view/view_generator.rb +0 -22
  80. data/lib/scss/_apps.scss +0 -94
  81. data/lib/scss/application.scss +0 -34
  82. data/lib/tasks/lesli/docs.rake +0 -47
  83. data/lib/tasks/lesli/git.rake +0 -70
  84. data/lib/tasks/lesli/github.rake +0 -89
  85. data/lib/test/config.rb +0 -111
  86. data/lib/test/helpers/response_integration_helper.rb +0 -46
  87. data/lib/test/lesli.rb +0 -61
@@ -1,93 +0,0 @@
1
- =begin
2
-
3
- Lesli
4
-
5
- Copyright (c) 2025, Lesli Technologies, S. A.
6
-
7
- This program is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- This program is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU General Public License for more details.
16
-
17
- You should have received a copy of the GNU General Public License
18
- along with this program. If not, see http://www.gnu.org/licenses/.
19
-
20
- Lesli · Ruby on Rails SaaS Development Framework.
21
-
22
- Made with ♥ by LesliTech
23
- Building a better future, one line of code at a time.
24
-
25
- @contact hello@lesli.tech
26
- @website https://www.lesli.tech
27
- @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
28
-
29
- // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
30
- // ·
31
- =end
32
-
33
- module Lesli
34
- module Items
35
- class DiscussionsController < ApplicationLesliController
36
- before_action :set_discussion, only: [:create]
37
-
38
- def create
39
- discussion = @parent_resource.discussions.new({
40
- message: discussion_params[:message],
41
- user_id: current_user.id
42
- })
43
-
44
- if discussion.save
45
- respond_with_lesli(:turbo => [
46
- stream_notification_success("Comment created"),
47
- turbo_stream.update("#{@discussion_parent_object}-discussions") do
48
- LesliView::Items::Discussions.new(@parent_resource, public_send(@discussion_path_string, @parent_resource)).render_in(view_context)
49
- end
50
- ])
51
- else
52
- respond_with_lesli(
53
- :turbo => stream_notification_danger(discussion.errors.full_messages)
54
- )
55
- end
56
- end
57
-
58
- private
59
-
60
- def set_discussion
61
-
62
- # Get the item model class, example: LesliSupport::Ticket::Discussion
63
- @discussion_model = self.class.name.gsub("Controller","").singularize.constantize
64
-
65
- # Get the parent model class, example: LesliSupport::Ticket
66
- @discussion_model_parent = @discussion_model.reflect_on_association(:item).klass
67
-
68
- # Get the row owner name, example: from LesliSupport::Ticket gets ticket
69
- @discussion_parent_object = "#{@discussion_model_parent.name.demodulize.underscore}"
70
-
71
- # Get the parent associations id, example: ticket_id
72
- @discussion_model_parent_id = "#{@discussion_parent_object}_id"
73
-
74
- # Get the local path method, example: ticket_discussions_path
75
- @discussion_path_string = "#{@discussion_parent_object}_discussions_path"
76
-
77
- # Get the parent resource
78
- @parent_resource = @discussion_model_parent.find_by_id(
79
- params[@discussion_model_parent_id.to_sym]
80
- )
81
- end
82
-
83
- def discussion_params
84
- # Get the params key, example: ticket_discussion
85
- discussion_model_param_key = @discussion_model.model_name.param_key
86
- params.require(discussion_model_param_key.to_sym).permit(
87
- :message,
88
- @discussion_model_parent_id
89
- )
90
- end
91
- end
92
- end
93
- end
@@ -1,15 +0,0 @@
1
- module Lesli
2
- module Items
3
- class Action < ApplicationRecord
4
- self.abstract_class = true
5
- # default_scope {
6
- # select(
7
- # :id,
8
- # :message,
9
- # :created_at,
10
- # LesliDate::Formatter.new.date_time.db_column('created_at')
11
- # ).order(created_at: :desc)
12
- # }
13
- end
14
- end
15
- end
@@ -1,15 +0,0 @@
1
- module Lesli
2
- module Items
3
- class Discussion < ApplicationRecord
4
- self.abstract_class = true
5
- default_scope {
6
- select(
7
- :id,
8
- :message,
9
- :created_at,
10
- LesliDate::Formatter.new.date_time.db_column('created_at')
11
- ).order(created_at: :desc)
12
- }
13
- end
14
- end
15
- end
data/config/importmap.rb DELETED
@@ -1 +0,0 @@
1
- # Pin npm packages by running ./bin/importmap
@@ -1,32 +0,0 @@
1
- [{
2
- "name": "street_name",
3
- "type": "string"
4
- },{
5
- "name": "street_number",
6
- "type": "string"
7
- },{
8
- "name": "street_other",
9
- "type": "string"
10
- },{
11
- "name": "postcode",
12
- "type": "string"
13
- },{
14
- "name": "state",
15
- "type": "string"
16
- },{
17
- "name": "city",
18
- "type": "string"
19
- },{
20
- "name": "country",
21
- "type": "string"
22
- },{
23
- "name": "latitude",
24
- "type": "string"
25
- },{
26
- "name": "longitude",
27
- "type": "string"
28
- },{
29
- "name": "deleted_at",
30
- "type": "datetime",
31
- "index": true
32
- }]
File without changes
@@ -1,17 +0,0 @@
1
- [
2
- {
3
- "name": "name",
4
- "type": "string"
5
- },{
6
- "name": "deletion_protection",
7
- "type": "boolean",
8
- "default": false
9
- },{
10
- "name": "default",
11
- "type": "boolean"
12
- },{
13
- "name": "deleted_at",
14
- "type": "datetime",
15
- "index": true
16
- }
17
- ]
@@ -1,24 +0,0 @@
1
- [
2
- {
3
- "name": "number",
4
- "type": "integer"
5
- },
6
- {
7
- "name": "name",
8
- "type": "string"
9
- },
10
- {
11
- "name":"next_statuses",
12
- "type":"string"
13
- },
14
- {
15
- "name": "status_type",
16
- "type": "string",
17
- "default": "normal"
18
- },
19
- {
20
- "name": "deleted_at",
21
- "type": "datetime",
22
- "index": true
23
- }
24
- ]
@@ -1,14 +0,0 @@
1
- [
2
- {
3
- "name": "workflow_for",
4
- "type": "string"
5
- },
6
- {
7
- "name": "global",
8
- "type": "boolean"
9
- },{
10
- "name": "deleted_at",
11
- "type": "datetime",
12
- "index": true
13
- }
14
- ]
@@ -1,39 +0,0 @@
1
- [{
2
- "name": "name",
3
- "type": "string"
4
- },{
5
- "name": "active",
6
- "type": "boolean",
7
- "default": false
8
- },{
9
- "name": "initial_status_id",
10
- "type": "bigint"
11
- },{
12
- "name": "final_status_id",
13
- "type": "bigint"
14
- },{
15
- "name": "action_type",
16
- "type": "string"
17
- },{
18
- "name": "execute_immediately",
19
- "type": "boolean"
20
- },{
21
- "name": "template_path",
22
- "type": "string"
23
- },{
24
- "name": "input_data",
25
- "type": "json"
26
- },{
27
- "name": "system_data",
28
- "type": "json"
29
- },{
30
- "name": "concerning_users",
31
- "type": "json"
32
- },{
33
- "name": "configuration",
34
- "type": "json"
35
- },{
36
- "name": "deleted_at",
37
- "type": "datetime",
38
- "index": true
39
- }]
@@ -1,27 +0,0 @@
1
- [{
2
- "name": "name",
3
- "type": "string"
4
- },{
5
- "name": "active",
6
- "type": "boolean",
7
- "default": false
8
- },{
9
- "name": "initial_status_id",
10
- "type": "bigint"
11
- },{
12
- "name": "final_status_id",
13
- "type": "bigint"
14
- },{
15
- "name": "user_type",
16
- "type": "string"
17
- },{
18
- "name": "users_id",
19
- "type": "bigint"
20
- },{
21
- "name": "roles_id",
22
- "type": "bigint"
23
- },{
24
- "name": "deleted_at",
25
- "type": "datetime",
26
- "index": true
27
- }]
@@ -1,8 +0,0 @@
1
- [{
2
- "name": "custom_field_value",
3
- "type": "text"
4
- },{
5
- "name": "deleted_at",
6
- "type": "datetime",
7
- "index": true
8
- }]
@@ -1,38 +0,0 @@
1
- [{
2
- "name": "field_name",
3
- "type": "string"
4
- }, {
5
- "name": "field_label",
6
- "type": "string"
7
- }, {
8
- "name": "field_type",
9
- "type": "string"
10
- }, {
11
- "name": "field_instructions",
12
- "type": "string"
13
- }, {
14
- "name": "field_placeholder",
15
- "type": "string"
16
- }, {
17
- "name": "required",
18
- "type": "boolean"
19
- }, {
20
- "name": "value_default",
21
- "type": "string"
22
- }, {
23
- "name": "value_allowed",
24
- "type": "json"
25
- }, {
26
- "name": "value_format",
27
- "type": "string"
28
- }, {
29
- "name": "value_multiple",
30
- "type": "boolean"
31
- }, {
32
- "name": "value_length",
33
- "type": "integer"
34
- },{
35
- "name": "deleted_at",
36
- "type": "datetime",
37
- "index": true
38
- }]
@@ -1,14 +0,0 @@
1
- [{
2
- "name": "name",
3
- "type": "string"
4
- }, {
5
- "name": "description",
6
- "type": "string"
7
- }, {
8
- "name": "enabled",
9
- "type": "boolean"
10
- }, {
11
- "name": "deleted_at",
12
- "type": "datetime",
13
- "index": true
14
- }]
@@ -1,23 +0,0 @@
1
- [{
2
- "name": "rule_required",
3
- "type": "boolean"
4
- }, {
5
- "name": "rule_min_length",
6
- "type": "numeric"
7
- },{
8
- "name": "rule_max_length",
9
- "type": "numeric"
10
- },{
11
- "name": "rule_min_length_error_msg",
12
- "type": "string"
13
- }, {
14
- "name": "rule_max_length_error_msg",
15
- "type": "string"
16
- }, {
17
- "name": "rule_required_error_msg",
18
- "type": "string"
19
- },{
20
- "name": "deleted_at",
21
- "type": "datetime",
22
- "index": true
23
- }]
@@ -1,14 +0,0 @@
1
- [{
2
- "name": "model_to_validate",
3
- "type": "string"
4
- }, {
5
- "name": "column_to_validate",
6
- "type": "string"
7
- }, {
8
- "name": "enabled",
9
- "type": "boolean"
10
- },{
11
- "name": "deleted_at",
12
- "type": "datetime",
13
- "index": true
14
- }]
@@ -1,164 +0,0 @@
1
- =begin
2
-
3
- Lesli
4
-
5
- Copyright (c) 2025, Lesli Technologies, S. A.
6
-
7
- This program is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- This program is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU General Public License for more details.
16
-
17
- You should have received a copy of the GNU General Public License
18
- along with this program. If not, see http://www.gnu.org/licenses/.
19
-
20
- Lesli · Ruby on Rails SaaS Development Framework.
21
-
22
- Made with ♥ by LesliTech
23
- Building a better future, one line of code at a time.
24
-
25
- @contact hello@lesli.tech
26
- @website https://www.lesli.tech
27
- @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
28
-
29
- // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
30
- // ·
31
- =end
32
-
33
-
34
- =begin
35
-
36
- Information reference:
37
-
38
-
39
- rails generate lesli:test CloudEngine/Things
40
-
41
- @info = {
42
- :engine=>"CloudEngine",
43
- :engine_code=>"cloud_engine",
44
- :engine_name=>"engine",
45
- :resources=>"Things",
46
- :resources_code=>"things",
47
- :resources_camel=>"things",
48
- :resource=>"Thing",
49
- :resource_camel=>"thing"
50
- }
51
-
52
- @vue = {
53
- :path_base=> "~/engines/cloud_engine/lib/vue",
54
- :path_apps=> "~/engines/cloud_engine/lib/vue/apps/thing",
55
- :path_store=> "~/engines/cloud_engine/lib/vue/stores/thing.js",
56
- :path_components=> "~/engines/cloud_engine/lib/vue/apps/thing/components"
57
- }
58
-
59
- @services = {
60
- :path=> "~/engines/cloud_engine/app/services/thing_services.rb"
61
- }
62
-
63
- @rspec = {
64
- :path_request=> "~/engines/cloud_engine/spec/requests/thing"
65
- }
66
- =end
67
- module Lesli
68
- class ApplicationLesliGeneratorBase < Rails::Generators::NamedBase
69
-
70
- @info;
71
- @model;
72
- @factory;
73
- @services;
74
- @rspec;
75
- @vue;
76
-
77
- def parse_info
78
-
79
- engine, resource = name.split("/")
80
-
81
- # engine information
82
- engine_code = engine.underscore
83
-
84
- # resource information
85
- resource_code = resource.underscore
86
-
87
- @info = {
88
- :engine => engine,
89
- :engine_code => engine_code,
90
-
91
- :resource => resource,
92
- :resource_code => resource_code,
93
-
94
- :engine_resource => "#{engine}::#{resource}",
95
- :engine_resource_code => "#{engine_code}_#{resource_code}"
96
- }
97
- end
98
-
99
- def parse_model
100
-
101
- tabla = "#{@info[:engine_resource]}".constantize
102
- .columns.map do |column|
103
-
104
- if column.type == :string
105
- value = '""'
106
- faker = "Faker::String.random"
107
- end
108
-
109
- if column.type == :integer
110
- value = 1
111
- faker = "Faker::Number.digit"
112
- end
113
-
114
- if column.type == :datetime
115
- value = "'#{Time.now}'"
116
- faker = 'Faker::Date.between(from: 2.days.ago, to: Date.today)'
117
- end
118
-
119
- {
120
- :name => column.name,
121
- :type => column.type,
122
- :null => column.null,
123
- :value => value,
124
- :faker => faker
125
- }
126
- end
127
-
128
- @model = {
129
- :name => @info[:engine_resource],
130
- :columns => tabla
131
- }
132
- end
133
-
134
- # def parse_services
135
-
136
- # path_base = Rails.root.join("engines", @info[:engine_code], "app", "services")
137
-
138
- # @services = {
139
- # :path => path_base.join(@info[:resource].downcase + "_services.rb")
140
- # }
141
- # end
142
-
143
- # def parse_vue
144
-
145
- # path_base = Rails.root.join("engines", @info[:engine_code], "lib", "vue")
146
-
147
- # @vue = {
148
- # :path_base => path_base,
149
- # :path_apps => path_base.join("apps", @info[:resources_code]),
150
- # :path_store => path_base.join("stores", "#{ @info[:resources_camel] }.js"),
151
- # :path_components => path_base.join("apps", @info[:resources_code], "components")
152
- # }
153
- # end
154
-
155
- # def parse_rspec
156
- # path_base = Rails.root.join("engines", @info[:engine_code], "spec")
157
-
158
- # @rspec = {
159
- # :path_request => path_base.join("requests", @info[:resources_code]),
160
- # :url => @info[:engine_name] + "/" + @info[:resources_code]
161
- # }
162
- # end
163
- end
164
- end
@@ -1,8 +0,0 @@
1
- Description:
2
- Explain the generator
3
-
4
- Example:
5
- bin/rails generate lesli:spec Lesli/Account
6
-
7
- This will create:
8
- what/will/it/create
@@ -1,22 +0,0 @@
1
-
2
-
3
- # ·
4
- require "#{Lesli::Engine.root}/lib/generators/application_lesli_generator_base.rb"
5
-
6
- module Lesli
7
- class SpecGenerator < ApplicationLesliGeneratorBase
8
- source_root File.expand_path("templates", __dir__)
9
-
10
- def generator
11
- L2.msg "Generating Lesli Model spec"
12
-
13
- pp @info;
14
- pp @model;
15
- pp @services;
16
- pp @rspec;
17
-
18
- #template("spec-factory.template", "#{(@info[:engine].constantize)::Engine.root.join('spec', 'factories', @info[:engine_resource_code])}.rb")
19
- template("spec-model.template", "#{(@info[:engine].constantize)::Engine.root.join('spec', 'models', @info[:engine_resource_code])}_spec.rb")
20
- end
21
- end
22
- end
@@ -1,17 +0,0 @@
1
- =begin
2
- <%# TODO: Use the license file if no lesli.txt file found %>
3
- <%= File.read(Lesli::Engine.root.join("lesli.txt")).to_s.force_encoding("ASCII-8BIT") %>=end
4
-
5
- FactoryBot.define do
6
- factory :<%= @info[:engine_resource_code] %>, class: <%= @info[:engine_resource] %> do
7
- name { Faker::Company.name }
8
-
9
- <% @model[:columns].each do |column| %>
10
- <%= column[:name] %> { <%= column[:faker] %> }<% end %>
11
-
12
- after(:create) do |account, evaluator|
13
- account.user = FactoryBot.create(:user, account_id: account.id)
14
- account.save
15
- end
16
- end
17
- end
@@ -1,70 +0,0 @@
1
- =begin
2
- <%# TODO: Use the license file if no lesli.txt file found %>
3
- <%= File.read(Lesli::Engine.root.join("lesli.txt")).to_s.force_encoding("ASCII-8BIT") %>=end
4
-
5
- require "rails_helper"
6
- require Lesli::Engine.root.join("spec/support/testers/model")
7
-
8
- RSpec.describe <%= @model[:name]%>, type: :model do
9
-
10
- # Setup runs before each test
11
- let(:<%= @info[:engine_resource_code] %>) { FactoryBot.create(:<%= @info[:engine_resource_code] %>) }
12
-
13
- it "is valid with valid attributes" do
14
- expect(<%= @info[:engine_resource_code] %>).to be_valid
15
- end
16
-
17
- <% @model[:columns].each do |column| %>
18
- <% next if ["id", "created_at", "updated_at"].include?(column[:name]) %>
19
- <% if !column[:null] %>
20
- it "is valid with valid attributes" do
21
- <%= @info[:engine_resource_code] %>.<%= column[:name]%> = nil
22
- expect(<%= @info[:engine_resource_code] %>).not_to be_valid
23
- end
24
- <% end %>
25
- <% end %>
26
-
27
- =begin
28
-
29
-
30
- it "is invalid without a name" do
31
- account.name = nil
32
- expect(account).not_to be_valid
33
- end
34
-
35
- it "is invalid without an email" do
36
- account.email = nil
37
- expect(account).not_to be_valid
38
- end
39
-
40
- it "is invalid with a duplicate email" do
41
- account.save
42
- duplicate_account = Account.new(name: "Test Account 2", email: "test@example.com", balance: 50.0)
43
- expect(duplicate_account).not_to be_valid
44
- end
45
-
46
- it "is invalid without a balance" do
47
- account.balance = nil
48
- expect(account).not_to be_valid
49
- end
50
-
51
- it "is invalid with a negative balance" do
52
- account.balance = -1
53
- expect(account).not_to be_valid
54
- end
55
-
56
- # Test associations
57
- it "has many transactions" do
58
- expect(account).to respond_to(:transactions)
59
- end
60
-
61
- # Test custom methods
62
- describe "#update_balance" do
63
- it "updates the balance correctly" do
64
- account.save
65
- account.update_balance(50.0)
66
- expect(account.reload.balance).to eq(150.0)
67
- end
68
- end
69
- =end
70
- end