upgrow 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/lib/upgrow.rb +2 -8
- data/lib/upgrow/action.rb +66 -16
- data/lib/upgrow/actions.rb +31 -0
- data/lib/upgrow/active_record_adapter.rb +24 -15
- data/lib/upgrow/active_record_schema.rb +63 -0
- data/lib/upgrow/basic_model.rb +64 -0
- data/lib/upgrow/basic_repository.rb +49 -22
- data/lib/upgrow/error.rb +19 -0
- data/lib/upgrow/immutable_object.rb +26 -21
- data/lib/upgrow/input.rb +7 -0
- data/lib/upgrow/model.rb +12 -12
- data/lib/upgrow/model_schema.rb +31 -0
- data/lib/upgrow/repository.rb +3 -0
- data/lib/upgrow/result.rb +18 -55
- data/lib/upgrow/schema.rb +33 -0
- data/test/application_system_test_case.rb +11 -0
- data/test/dummy/app/actions/application_action.rb +10 -0
- data/test/dummy/app/actions/articles/create_action.rb +15 -0
- data/test/dummy/app/actions/articles/destroy_action.rb +9 -0
- data/test/dummy/app/actions/articles/edit_action.rb +12 -0
- data/test/dummy/app/actions/articles/index_action.rb +11 -0
- data/test/dummy/app/actions/articles/new_action.rb +8 -0
- data/test/dummy/app/actions/articles/show_action.rb +11 -0
- data/test/dummy/app/actions/articles/update_action.rb +15 -0
- data/test/dummy/app/actions/comments/create_action.rb +15 -0
- data/test/dummy/app/actions/comments/destroy_action.rb +9 -0
- data/test/dummy/app/actions/comments/new_action.rb +8 -0
- data/test/dummy/app/actions/sessions/create_action.rb +23 -0
- data/test/dummy/app/actions/sessions/destroy_action.rb +6 -0
- data/test/dummy/app/actions/sessions/new_action.rb +8 -0
- data/test/dummy/app/actions/user_action.rb +10 -0
- data/test/dummy/app/actions/users/create_action.rb +13 -0
- data/test/dummy/app/actions/users/new_action.rb +8 -0
- data/test/dummy/app/controllers/application_controller.rb +10 -0
- data/test/dummy/app/controllers/articles_controller.rb +32 -28
- data/test/dummy/app/controllers/comments_controller.rb +41 -0
- data/test/dummy/app/controllers/sessions_controller.rb +34 -0
- data/test/dummy/app/controllers/users_controller.rb +29 -0
- data/test/dummy/app/helpers/application_helper.rb +27 -3
- data/test/dummy/app/helpers/users_helper.rb +15 -0
- data/test/dummy/app/inputs/article_input.rb +3 -0
- data/test/dummy/app/inputs/comment_input.rb +11 -0
- data/test/dummy/app/inputs/session_input.rb +9 -0
- data/test/dummy/app/inputs/user_input.rb +9 -0
- data/test/dummy/app/models/article.rb +0 -2
- data/test/dummy/app/models/comment.rb +4 -0
- data/test/dummy/app/models/user.rb +4 -0
- data/test/dummy/app/records/article_record.rb +2 -0
- data/test/dummy/app/records/comment_record.rb +7 -0
- data/test/dummy/app/records/user_record.rb +9 -0
- data/test/dummy/app/repositories/article_repository.rb +26 -0
- data/test/dummy/app/repositories/comment_repository.rb +3 -0
- data/test/dummy/app/repositories/user_repository.rb +12 -0
- data/test/dummy/config/routes.rb +6 -1
- data/test/dummy/db/migrate/20210320140432_create_comments.rb +12 -0
- data/test/dummy/db/migrate/20210409164927_create_users.rb +22 -0
- data/test/dummy/db/schema.rb +24 -1
- data/test/system/articles_test.rb +87 -29
- data/test/system/comments_test.rb +81 -0
- data/test/system/guest_user_test.rb +14 -0
- data/test/system/sign_in_test.rb +57 -0
- data/test/system/sign_out_test.rb +19 -0
- data/test/system/sign_up_test.rb +38 -0
- data/test/test_helper.rb +6 -1
- data/test/upgrow/action_test.rb +101 -9
- data/test/upgrow/actions_test.rb +24 -0
- data/test/upgrow/active_record_adapter_test.rb +12 -17
- data/test/upgrow/active_record_schema_test.rb +92 -0
- data/test/upgrow/basic_model_test.rb +95 -0
- data/test/upgrow/basic_repository_test.rb +48 -27
- data/test/upgrow/immutable_object_test.rb +43 -7
- data/test/upgrow/input_test.rb +19 -1
- data/test/upgrow/model_schema_test.rb +44 -0
- data/test/upgrow/model_test.rb +48 -11
- data/test/upgrow/result_test.rb +19 -64
- data/test/upgrow/schema_test.rb +44 -0
- metadata +128 -50
- data/test/dummy/app/actions/create_article_action.rb +0 -13
- data/test/dummy/app/actions/delete_article_action.rb +0 -7
- data/test/dummy/app/actions/edit_article_action.rb +0 -10
- data/test/dummy/app/actions/list_articles_action.rb +0 -8
- data/test/dummy/app/actions/show_article_action.rb +0 -10
- data/test/dummy/app/actions/update_article_action.rb +0 -13
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Comments
|
4
|
+
class CreateAction < ApplicationAction
|
5
|
+
expose :comment
|
6
|
+
|
7
|
+
def perform(input)
|
8
|
+
if input.valid?
|
9
|
+
@comment = CommentRepository.new.create(input)
|
10
|
+
else
|
11
|
+
failure(input.errors)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sessions
|
4
|
+
class CreateAction < ApplicationAction
|
5
|
+
def perform(input)
|
6
|
+
if input.valid?
|
7
|
+
@current_user = UserRepository.new.find_for_authentication(input)
|
8
|
+
unless @current_user
|
9
|
+
failure(
|
10
|
+
Upgrow::Error.new(
|
11
|
+
message: 'Invalid email or password.',
|
12
|
+
code: :invalid_email_or_password,
|
13
|
+
attribute: :password
|
14
|
+
),
|
15
|
+
Upgrow::Error.new(attribute: :email)
|
16
|
+
)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
failure(input.errors)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,3 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
class ApplicationController < ActionController::Base
|
3
|
+
rescue_from(UserAction::UnauthorizedError) { redirect_to(new_session_path) }
|
4
|
+
|
5
|
+
before_action :instantiate_action
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def instantiate_action
|
10
|
+
action_class = Upgrow::Actions[controller_name, action_name]
|
11
|
+
@action = action_class.new(user_id: session[:user_id])
|
12
|
+
end
|
3
13
|
end
|
@@ -2,57 +2,61 @@
|
|
2
2
|
|
3
3
|
class ArticlesController < ApplicationController
|
4
4
|
def index
|
5
|
-
@
|
5
|
+
@result = @action.perform
|
6
6
|
end
|
7
7
|
|
8
8
|
def show
|
9
|
-
@
|
9
|
+
@result = @action.perform(params[:id])
|
10
10
|
end
|
11
11
|
|
12
12
|
def new
|
13
13
|
@input = ArticleInput.new
|
14
|
+
@result = @action.perform
|
14
15
|
end
|
15
16
|
|
16
17
|
def edit
|
17
|
-
|
18
|
+
@result = @action.perform(params[:id])
|
18
19
|
@input = ArticleInput.new(
|
19
|
-
title: article.title, body: article.body
|
20
|
+
title: @result.article.title, body: @result.article.body
|
20
21
|
)
|
21
22
|
end
|
22
23
|
|
23
24
|
def create
|
24
|
-
@input = ArticleInput.new(
|
25
|
+
@input = ArticleInput.new(
|
26
|
+
article_params.merge(user_id: session[:user_id])
|
27
|
+
)
|
28
|
+
|
29
|
+
@result = @action.perform(@input)
|
25
30
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
render(:new)
|
35
|
-
end
|
31
|
+
if @result.success?
|
32
|
+
redirect_to(
|
33
|
+
article_path(@result.article.id),
|
34
|
+
notice: 'Article was successfully created.'
|
35
|
+
)
|
36
|
+
else
|
37
|
+
render(:new)
|
38
|
+
end
|
36
39
|
end
|
37
40
|
|
38
41
|
def update
|
39
|
-
@input = ArticleInput.new(
|
42
|
+
@input = ArticleInput.new(
|
43
|
+
article_params.merge(user_id: session[:user_id])
|
44
|
+
)
|
45
|
+
|
46
|
+
@result = @action.perform(params[:id], @input)
|
40
47
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
@errors = errors
|
50
|
-
render(:edit)
|
51
|
-
end
|
48
|
+
if @result.success?
|
49
|
+
redirect_to(
|
50
|
+
article_path(@result.article.id),
|
51
|
+
notice: 'Article was successfully updated.'
|
52
|
+
)
|
53
|
+
else
|
54
|
+
render(:edit)
|
55
|
+
end
|
52
56
|
end
|
53
57
|
|
54
58
|
def destroy
|
55
|
-
|
59
|
+
@action.perform(params[:id])
|
56
60
|
redirect_to(articles_url, notice: 'Article was successfully destroyed.')
|
57
61
|
end
|
58
62
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CommentsController < ApplicationController
|
4
|
+
def new
|
5
|
+
@input = CommentInput.new(article_id: params[:article_id])
|
6
|
+
@result = @action.perform
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@input = CommentInput.new(
|
11
|
+
comment_params.merge(article_id: params[:article_id],
|
12
|
+
user_id: session[:user_id])
|
13
|
+
)
|
14
|
+
|
15
|
+
@result = @action.perform(@input)
|
16
|
+
|
17
|
+
if @result.success?
|
18
|
+
redirect_to(
|
19
|
+
article_path(@result.comment.article_id),
|
20
|
+
notice: 'Comment was successfully created.'
|
21
|
+
)
|
22
|
+
else
|
23
|
+
render(:new)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def destroy
|
28
|
+
@action.perform(params[:id])
|
29
|
+
redirect_to(
|
30
|
+
article_path(params[:article_id]),
|
31
|
+
notice: 'Comment was successfully destroyed.'
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Only allow a list of trusted parameters through.
|
38
|
+
def comment_params
|
39
|
+
params.require(:comment_input).permit(:body)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class SessionsController < ApplicationController
|
4
|
+
def new
|
5
|
+
@input = SessionInput.new
|
6
|
+
@result = @action.perform
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@input = SessionInput.new(session_params)
|
11
|
+
|
12
|
+
@result = @action.perform(@input)
|
13
|
+
|
14
|
+
if @result.success?
|
15
|
+
reset_session
|
16
|
+
session[:user_id] = @result.current_user.id
|
17
|
+
redirect_to(root_path)
|
18
|
+
else
|
19
|
+
render(:new)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def destroy
|
24
|
+
reset_session
|
25
|
+
redirect_to(root_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Only allow a list of trusted parameters through.
|
31
|
+
def session_params
|
32
|
+
params.require(:session_input).permit(:email, :password)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class UsersController < ApplicationController
|
4
|
+
def new
|
5
|
+
@input = UserInput.new
|
6
|
+
@result = @action.perform
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@input = UserInput.new(user_params)
|
11
|
+
|
12
|
+
@result = @action.perform(@input)
|
13
|
+
|
14
|
+
if @result.success?
|
15
|
+
reset_session
|
16
|
+
session[:user_id] = @result.current_user.id
|
17
|
+
redirect_to(root_path)
|
18
|
+
else
|
19
|
+
render(:new)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Only allow a list of trusted parameters through.
|
26
|
+
def user_params
|
27
|
+
params.require(:user_input).permit(:email, :password)
|
28
|
+
end
|
29
|
+
end
|
@@ -24,7 +24,9 @@ module ApplicationHelper
|
|
24
24
|
|
25
25
|
if method
|
26
26
|
errors_for(method).each do |error|
|
27
|
-
result += @template.content_tag(
|
27
|
+
result += @template.content_tag(
|
28
|
+
:p, error.message, class: 'help is-danger'
|
29
|
+
)
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
@@ -46,6 +48,7 @@ module ApplicationHelper
|
|
46
48
|
def text_field(method, label: true, expanded: false, field: true, **args)
|
47
49
|
input_class = ['input']
|
48
50
|
input_class << 'is-danger' if errors_for(method).any?
|
51
|
+
|
49
52
|
output = control(expanded: expanded) do
|
50
53
|
super(method, class: input_class, **args)
|
51
54
|
end
|
@@ -68,6 +71,28 @@ module ApplicationHelper
|
|
68
71
|
field(method: method, label: true) { output }
|
69
72
|
end
|
70
73
|
|
74
|
+
def email_field(method, **args)
|
75
|
+
input_class = ['input']
|
76
|
+
input_class << 'is-danger' if errors_for(method).any?
|
77
|
+
|
78
|
+
output = control(expanded: false) do
|
79
|
+
super(method, class: input_class, **args)
|
80
|
+
end
|
81
|
+
|
82
|
+
field(method: method, label: true) { output }
|
83
|
+
end
|
84
|
+
|
85
|
+
def password_field(method, **args)
|
86
|
+
input_class = ['input']
|
87
|
+
input_class << 'is-danger' if errors_for(method).any?
|
88
|
+
|
89
|
+
output = control(expanded: false) do
|
90
|
+
super(method, class: input_class, **args)
|
91
|
+
end
|
92
|
+
|
93
|
+
field(method: method, label: true) { output }
|
94
|
+
end
|
95
|
+
|
71
96
|
# Render a form submit button.
|
72
97
|
#
|
73
98
|
# @param text [Symbol] the text for the button.
|
@@ -95,8 +120,7 @@ module ApplicationHelper
|
|
95
120
|
end
|
96
121
|
|
97
122
|
def errors_for(method)
|
98
|
-
(options[:errors] ||
|
99
|
-
.full_messages_for(method)
|
123
|
+
(options[:errors] || []).select { |error| error.attribute == method }
|
100
124
|
end
|
101
125
|
end
|
102
126
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UsersHelper
|
4
|
+
def user_signed_in?
|
5
|
+
current_user.present?
|
6
|
+
end
|
7
|
+
|
8
|
+
def current_user
|
9
|
+
@result.current_user
|
10
|
+
end
|
11
|
+
|
12
|
+
def belongs_to_current_user?(model)
|
13
|
+
user_signed_in? && model.user_id == current_user.id
|
14
|
+
end
|
15
|
+
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
class ArticleInput < Upgrow::Input
|
3
4
|
attribute :title
|
4
5
|
attribute :body
|
6
|
+
attribute :user_id
|
5
7
|
|
8
|
+
validates :user_id, presence: true
|
6
9
|
validates :title, presence: true
|
7
10
|
validates :body, presence: true, length: { minimum: 10 }
|
8
11
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CommentInput < Upgrow::Input
|
4
|
+
attribute :article_id
|
5
|
+
attribute :user_id
|
6
|
+
attribute :body
|
7
|
+
|
8
|
+
validates :article_id, presence: true
|
9
|
+
validates :user_id, presence: true
|
10
|
+
validates :body, presence: true, length: { minimum: 10 }
|
11
|
+
end
|