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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/lib/upgrow.rb +2 -8
  4. data/lib/upgrow/action.rb +66 -16
  5. data/lib/upgrow/actions.rb +31 -0
  6. data/lib/upgrow/active_record_adapter.rb +24 -15
  7. data/lib/upgrow/active_record_schema.rb +63 -0
  8. data/lib/upgrow/basic_model.rb +64 -0
  9. data/lib/upgrow/basic_repository.rb +49 -22
  10. data/lib/upgrow/error.rb +19 -0
  11. data/lib/upgrow/immutable_object.rb +26 -21
  12. data/lib/upgrow/input.rb +7 -0
  13. data/lib/upgrow/model.rb +12 -12
  14. data/lib/upgrow/model_schema.rb +31 -0
  15. data/lib/upgrow/repository.rb +3 -0
  16. data/lib/upgrow/result.rb +18 -55
  17. data/lib/upgrow/schema.rb +33 -0
  18. data/test/application_system_test_case.rb +11 -0
  19. data/test/dummy/app/actions/application_action.rb +10 -0
  20. data/test/dummy/app/actions/articles/create_action.rb +15 -0
  21. data/test/dummy/app/actions/articles/destroy_action.rb +9 -0
  22. data/test/dummy/app/actions/articles/edit_action.rb +12 -0
  23. data/test/dummy/app/actions/articles/index_action.rb +11 -0
  24. data/test/dummy/app/actions/articles/new_action.rb +8 -0
  25. data/test/dummy/app/actions/articles/show_action.rb +11 -0
  26. data/test/dummy/app/actions/articles/update_action.rb +15 -0
  27. data/test/dummy/app/actions/comments/create_action.rb +15 -0
  28. data/test/dummy/app/actions/comments/destroy_action.rb +9 -0
  29. data/test/dummy/app/actions/comments/new_action.rb +8 -0
  30. data/test/dummy/app/actions/sessions/create_action.rb +23 -0
  31. data/test/dummy/app/actions/sessions/destroy_action.rb +6 -0
  32. data/test/dummy/app/actions/sessions/new_action.rb +8 -0
  33. data/test/dummy/app/actions/user_action.rb +10 -0
  34. data/test/dummy/app/actions/users/create_action.rb +13 -0
  35. data/test/dummy/app/actions/users/new_action.rb +8 -0
  36. data/test/dummy/app/controllers/application_controller.rb +10 -0
  37. data/test/dummy/app/controllers/articles_controller.rb +32 -28
  38. data/test/dummy/app/controllers/comments_controller.rb +41 -0
  39. data/test/dummy/app/controllers/sessions_controller.rb +34 -0
  40. data/test/dummy/app/controllers/users_controller.rb +29 -0
  41. data/test/dummy/app/helpers/application_helper.rb +27 -3
  42. data/test/dummy/app/helpers/users_helper.rb +15 -0
  43. data/test/dummy/app/inputs/article_input.rb +3 -0
  44. data/test/dummy/app/inputs/comment_input.rb +11 -0
  45. data/test/dummy/app/inputs/session_input.rb +9 -0
  46. data/test/dummy/app/inputs/user_input.rb +9 -0
  47. data/test/dummy/app/models/article.rb +0 -2
  48. data/test/dummy/app/models/comment.rb +4 -0
  49. data/test/dummy/app/models/user.rb +4 -0
  50. data/test/dummy/app/records/article_record.rb +2 -0
  51. data/test/dummy/app/records/comment_record.rb +7 -0
  52. data/test/dummy/app/records/user_record.rb +9 -0
  53. data/test/dummy/app/repositories/article_repository.rb +26 -0
  54. data/test/dummy/app/repositories/comment_repository.rb +3 -0
  55. data/test/dummy/app/repositories/user_repository.rb +12 -0
  56. data/test/dummy/config/routes.rb +6 -1
  57. data/test/dummy/db/migrate/20210320140432_create_comments.rb +12 -0
  58. data/test/dummy/db/migrate/20210409164927_create_users.rb +22 -0
  59. data/test/dummy/db/schema.rb +24 -1
  60. data/test/system/articles_test.rb +87 -29
  61. data/test/system/comments_test.rb +81 -0
  62. data/test/system/guest_user_test.rb +14 -0
  63. data/test/system/sign_in_test.rb +57 -0
  64. data/test/system/sign_out_test.rb +19 -0
  65. data/test/system/sign_up_test.rb +38 -0
  66. data/test/test_helper.rb +6 -1
  67. data/test/upgrow/action_test.rb +101 -9
  68. data/test/upgrow/actions_test.rb +24 -0
  69. data/test/upgrow/active_record_adapter_test.rb +12 -17
  70. data/test/upgrow/active_record_schema_test.rb +92 -0
  71. data/test/upgrow/basic_model_test.rb +95 -0
  72. data/test/upgrow/basic_repository_test.rb +48 -27
  73. data/test/upgrow/immutable_object_test.rb +43 -7
  74. data/test/upgrow/input_test.rb +19 -1
  75. data/test/upgrow/model_schema_test.rb +44 -0
  76. data/test/upgrow/model_test.rb +48 -11
  77. data/test/upgrow/result_test.rb +19 -64
  78. data/test/upgrow/schema_test.rb +44 -0
  79. metadata +128 -50
  80. data/test/dummy/app/actions/create_article_action.rb +0 -13
  81. data/test/dummy/app/actions/delete_article_action.rb +0 -7
  82. data/test/dummy/app/actions/edit_article_action.rb +0 -10
  83. data/test/dummy/app/actions/list_articles_action.rb +0 -8
  84. data/test/dummy/app/actions/show_article_action.rb +0 -10
  85. data/test/dummy/app/actions/update_article_action.rb +0 -13
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'application_system_test_case'
4
+
5
+ class GuestUserTest < ApplicationSystemTestCase
6
+ test 'index page is shown for a guest User' do
7
+ visit root_path
8
+ assert_title 'Articles'
9
+
10
+ within '.navbar' do
11
+ assert_link 'Sign in'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'application_system_test_case'
4
+
5
+ class SignInTest < ApplicationSystemTestCase
6
+ test 'successful sign in' do
7
+ sign_in
8
+
9
+ assert_title 'Articles'
10
+
11
+ within '.navbar' do
12
+ assert_link 'existing@example.com'
13
+ end
14
+ end
15
+
16
+ test 'all fields are required' do
17
+ visit root_path
18
+
19
+ click_link 'Sign in'
20
+ click_button 'Sign in'
21
+
22
+ assert_title 'Sign In'
23
+
24
+ assert_text "Email can't be blank"
25
+ assert_text "Password can't be blank"
26
+ end
27
+
28
+ test 'sign in fails when email is incorrect' do
29
+ visit root_path
30
+
31
+ click_link 'Sign in'
32
+
33
+ fill_in 'Email', with: 'wrong@example.com'
34
+ fill_in 'Password', with: '123xyz'
35
+
36
+ click_button 'Sign in'
37
+
38
+ assert_title 'Sign In'
39
+
40
+ assert_text 'Invalid email or password'
41
+ end
42
+
43
+ test 'sign in fails when password is incorrect' do
44
+ visit root_path
45
+
46
+ click_link 'Sign in'
47
+
48
+ fill_in 'Email', with: 'existing@example.com'
49
+ fill_in 'Password', with: 'wrong'
50
+
51
+ click_button 'Sign in'
52
+
53
+ assert_title 'Sign In'
54
+
55
+ assert_text 'Invalid email or password'
56
+ end
57
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'application_system_test_case'
4
+
5
+ class SignOutTest < ApplicationSystemTestCase
6
+ test 'successful sign out' do
7
+ sign_in
8
+
9
+ find_link('existing@example.com').hover
10
+
11
+ click_on 'Sign out'
12
+
13
+ assert_title 'Articles'
14
+
15
+ within '.navbar' do
16
+ assert_link 'Sign in'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'application_system_test_case'
4
+
5
+ class SignUpTest < ApplicationSystemTestCase
6
+ test 'successful sign up' do
7
+ visit root_path
8
+
9
+ click_on 'Sign in'
10
+ click_on 'Sign up'
11
+
12
+ assert_title 'Sign Up'
13
+
14
+ fill_in 'Email', with: 'volmer@example.com'
15
+ fill_in 'Password', with: 'abc123word'
16
+
17
+ click_on 'Sign up'
18
+
19
+ assert_title 'Articles'
20
+ within '.navbar' do
21
+ assert_link 'volmer@example.com'
22
+ end
23
+ end
24
+
25
+ test 'all fields are required' do
26
+ visit root_path
27
+
28
+ click_on 'Sign in'
29
+ click_on 'Sign up'
30
+
31
+ click_on 'Sign up'
32
+
33
+ assert_title 'Sign Up'
34
+
35
+ assert_text "Email can't be blank"
36
+ assert_text "Password can't be blank"
37
+ end
38
+ end
data/test/test_helper.rb CHANGED
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support/test_case'
3
4
  require 'minitest/autorun'
4
5
  require 'pry-byebug'
5
- require 'upgrow'
6
6
 
7
+ module Warning
8
+ def self.warn(message)
9
+ raise message.to_s
10
+ end
11
+ end
7
12
  Warning[:deprecated] = true
@@ -2,24 +2,116 @@
2
2
 
3
3
  require 'test_helper'
4
4
 
5
+ require 'upgrow/action'
6
+ require 'upgrow/input'
7
+
5
8
  module Upgrow
6
9
  class ActionTest < ActiveSupport::TestCase
7
- test '.result_class is an empty Result by default' do
8
- assert_equal([:errors], Action.result_class.members)
10
+ class SampleAction < Action
11
+ expose :user
12
+
13
+ def perform
14
+ @user = 'volmer'
15
+ end
9
16
  end
10
17
 
11
- test '.result sets the members in the Action Result class' do
12
- result_class = Action.result_class
18
+ class SubSampleAction < SampleAction
19
+ expose :article
13
20
 
14
- Action.result(:user, :data)
21
+ def perform
22
+ super
23
+ @article = 'The Hobbit'
24
+ end
25
+ end
26
+
27
+ class EmptyAction < SubSampleAction
28
+ def perform; end
29
+ end
30
+
31
+ class FailedAction < SampleAction
32
+ def perform
33
+ super
34
+ failure(:error_1, :error_2)
35
+ end
36
+ end
37
+
38
+ class SampleInput < Input
39
+ attribute :name
40
+ validates :name, presence: true
41
+ end
42
+
43
+ test '.exposures is empty by default' do
44
+ assert_empty Action.exposures
45
+ end
46
+
47
+ test '.expose sets the exposures in the Action Result class' do
48
+ assert_equal([:user], SampleAction.exposures)
49
+ end
50
+
51
+ test '.expose includes inherited exposures' do
52
+ assert_equal([:user, :article], SubSampleAction.exposures)
53
+ end
54
+
55
+ test '#perform raises NoMethodError error when it is not implemented' do
56
+ assert_raises(NoMethodError) do
57
+ Action.perform
58
+ end
59
+ end
15
60
 
16
- assert_equal([:user, :data, :errors], Action.result_class.members)
61
+ test '#perform returns the exposed instance variables' do
62
+ result = SubSampleAction.new.perform
17
63
 
18
- Action.result_class = result_class
64
+ assert_equal 'volmer', result.user
65
+ assert_equal 'The Hobbit', result.article
66
+ assert_empty result.errors
19
67
  end
20
68
 
21
- test '#result returns the Result class from the Action class' do
22
- assert_equal Action.result_class, Action.new.result
69
+ test '#perform returns nil for each exposed instance variable that is not set' do
70
+ result = EmptyAction.new.perform
71
+
72
+ assert_nil result.user
73
+ assert_nil result.article
74
+ assert_empty result.errors
75
+ end
76
+
77
+ test '#perform returns a Result with errors when #failure is called' do
78
+ result = FailedAction.new.perform
79
+
80
+ assert_equal 'volmer', result.user
81
+ assert_equal [:error_1, :error_2], result.errors
82
+ end
83
+
84
+ test '#failure throws a failed Result with the given errors' do
85
+ action = SampleAction.new
86
+
87
+ caught = true
88
+
89
+ result = catch(:failure) do
90
+ action.failure(:error)
91
+ caught = false
92
+ end
93
+
94
+ assert caught
95
+ assert_equal([:error], result.errors)
96
+ assert_nil result.user
97
+ end
98
+
99
+ test '#failure converts Active Model Errors into an Array of Errors' do
100
+ action = SampleAction.new
101
+
102
+ input = SampleInput.new(name: '')
103
+ input.valid?
104
+
105
+ result = catch(:failure) { action.failure(input.errors) }
106
+
107
+ assert_nil result.user
108
+ assert_predicate result.errors, :one?
109
+
110
+ error = result.errors.first
111
+
112
+ assert_equal :blank, error.code
113
+ assert_equal :name, error.attribute
114
+ assert_equal "Name can't be blank", error.message
23
115
  end
24
116
  end
25
117
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ require 'upgrow/actions'
6
+ require 'upgrow/action'
7
+
8
+ class GlobalAction < Upgrow::Action
9
+ end
10
+
11
+ module Upgrow
12
+ class NamespacedAction < Action
13
+ end
14
+
15
+ class ActionsTest < ActiveSupport::TestCase
16
+ test '.[] returns the Action with the given global name' do
17
+ assert_equal GlobalAction, Actions['global']
18
+ end
19
+
20
+ test '.[] returns the Action with the given namespaced name' do
21
+ assert_equal NamespacedAction, Actions['upgrow', 'namespaced']
22
+ end
23
+ end
24
+ end
@@ -2,9 +2,14 @@
2
2
 
3
3
  require 'test_helper'
4
4
 
5
+ require 'upgrow/active_record_adapter'
6
+ require 'upgrow/basic_model'
7
+ require 'upgrow/basic_repository'
8
+ require 'upgrow/input'
9
+
5
10
  module Upgrow
6
11
  class ActiveRecordAdapterTest < ActiveSupport::TestCase
7
- class User < Model
12
+ class User < BasicModel
8
13
  attribute :name
9
14
  end
10
15
 
@@ -19,19 +24,17 @@ module Upgrow
19
24
  class UserRecord; end
20
25
 
21
26
  setup do
22
- freeze_time
23
27
  @base = Minitest::Mock.new
24
- @repository = UserRepository.new(base: @base)
28
+ UserRepository.base = @base
29
+ @repository = UserRepository.new
25
30
  @record = Minitest::Mock.new
26
- @record_attributes = {
27
- name: 'volmer', id: 1, created_at: Time.now, updated_at: Time.now
28
- }
31
+ @record_attributes = { name: 'volmer', id: 1 }
29
32
  @record.expect(:attributes, @record_attributes)
30
33
  end
31
34
 
32
- test '.new sets base to the Active Record Base class according to the Repository name by default' do
33
- repository = UserRepository.new
34
- assert_equal UserRecord, repository.base
35
+ test '.base is the Active Record Base class according to the Repository name by default' do
36
+ UserRepository.base = nil
37
+ assert_equal UserRecord, UserRepository.base
35
38
  end
36
39
 
37
40
  test '#all returns all Records as Models' do
@@ -43,8 +46,6 @@ module Upgrow
43
46
 
44
47
  assert_equal 1, all.first.id
45
48
  assert_equal 'volmer', all.first.name
46
- assert_equal Time.now, all.first.created_at
47
- assert_equal Time.now, all.first.updated_at
48
49
  end
49
50
 
50
51
  test '#find retrieves the Model for the given ID' do
@@ -54,8 +55,6 @@ module Upgrow
54
55
 
55
56
  assert_equal 1, model.id
56
57
  assert_equal 'volmer', model.name
57
- assert_equal Time.now, model.created_at
58
- assert_equal Time.now, model.updated_at
59
58
  end
60
59
 
61
60
  test '#create creates a new Record with the given attributes' do
@@ -67,8 +66,6 @@ module Upgrow
67
66
 
68
67
  assert_equal 1, model.id
69
68
  assert_equal 'volmer', model.name
70
- assert_equal Time.now, model.created_at
71
- assert_equal Time.now, model.updated_at
72
69
  end
73
70
 
74
71
  test '#update changes the existing Record attributes' do
@@ -81,8 +78,6 @@ module Upgrow
81
78
 
82
79
  assert_equal 1, model.id
83
80
  assert_equal 'rafael', model.name
84
- assert_equal Time.now, model.created_at
85
- assert_equal Time.now, model.updated_at
86
81
  end
87
82
 
88
83
  test '#delete deletes the Record with the given ID' do
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Upgrow
6
+ class ActiveRecordSchemaTest < ActiveSupport::TestCase
7
+ class UserRecord
8
+ class << self
9
+ def attribute_names
10
+ ['id', 'email']
11
+ end
12
+
13
+ def reflections
14
+ { 'article_record' => :reflection, 'tag_records' => :reflection }
15
+ end
16
+ end
17
+ end
18
+
19
+ setup do
20
+ @original_schema = ModelSchema.new
21
+ @schema = ActiveRecordSchema.new(
22
+ 'Upgrow::ActiveRecordSchemaTest::UserRecord', @original_schema
23
+ )
24
+ end
25
+
26
+ test '#attribute defines the attribute in the original Schema' do
27
+ @schema.attribute(:name)
28
+
29
+ assert_equal [:name], @original_schema.attribute_names
30
+ end
31
+
32
+ test '#attribute_names returns the Active Record attribute names' do
33
+ assert_equal [:id, :email], @schema.attribute_names
34
+ end
35
+
36
+ test '#attribute_names includes attributes from the original schema' do
37
+ @original_schema.attribute(:phone)
38
+
39
+ assert_equal [:id, :email, :phone], @schema.attribute_names
40
+ end
41
+
42
+ test '#attribute_names ignores duplicates from the original schema' do
43
+ @original_schema.attribute(:email)
44
+ @original_schema.attribute(:phone)
45
+
46
+ assert_equal [:id, :email, :phone], @schema.attribute_names
47
+ end
48
+
49
+ test '#attribute_names raises a Name Error if the Record class is undefined' do
50
+ schema = ActiveRecordSchema.new('NoRecord', Schema.new)
51
+
52
+ error = assert_raises(NameError) do
53
+ schema.attribute_names
54
+ end
55
+
56
+ assert_includes error.message, 'uninitialized constant NoRecord'
57
+ end
58
+
59
+ test '#association defines the association in the original Schema' do
60
+ @schema.association(:user)
61
+
62
+ assert_equal [:user], @original_schema.association_names
63
+ end
64
+
65
+ test '#association_names includes associations from the Active Record reflections' do
66
+ assert_equal [:article, :tags], @schema.association_names
67
+ end
68
+
69
+ test '#association_names includes associations from the original schema' do
70
+ @original_schema.association(:user)
71
+
72
+ assert_equal [:article, :tags, :user], @schema.association_names
73
+ end
74
+
75
+ test '#association_names ignores duplicates from the original schema' do
76
+ @original_schema.association(:article)
77
+ @original_schema.association(:user)
78
+
79
+ assert_equal [:article, :tags, :user], @schema.association_names
80
+ end
81
+
82
+ test '#association_names raises a Name Error if the Record class is undefined' do
83
+ schema = ActiveRecordSchema.new('NoRecord', Schema.new)
84
+
85
+ error = assert_raises(NameError) do
86
+ schema.association_names
87
+ end
88
+
89
+ assert_includes error.message, 'uninitialized constant NoRecord'
90
+ end
91
+ end
92
+ end