upgrow 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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