-
Notifications
You must be signed in to change notification settings - Fork 9
/
solid-process-4.rb
81 lines (65 loc) · 2.45 KB
/
solid-process-4.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
class User::Registration < Solid::Process
deps do
attribute :token_creation, default: User::Token::Creation
attribute :account_creation, default: Account::Member::OwnerCreation
attribute :mailer, default: -> { User::Adapters.mailer }
attribute :repository, default: -> { User::Adapters.repository }
attribute :temporary_token, default: -> { User::Adapters.temporary_token }
validates :mailer, kind_of: User::Adapters::MailerInterface
validates :repository, kind_of: User::Adapters::RepositoryInterface
validates :temporary_token, kind_of: User::Adapters::TemporaryTokenInterface
end
input do
attribute :uuid, :string, default: -> { ::UUID.generate }
attribute :email, :string
attribute :password, :string
attribute :password_confirmation, :string
before_validation do
self.email = email.downcase.strip
end
with_options presence: true do
validates :uuid, format: ::UUID::REGEXP
validates :email, format: User::Email::REGEXP
validates :password, confirmation: true, length: {minimum: User::Password::MINIMUM_LENGTH}
end
end
def call(attributes)
rollback_on_failure {
Given(attributes)
.and_then(:check_if_email_is_taken)
.and_then(:create_user)
.and_then(:create_user_account)
.and_then(:create_user_token)
}
.and_then(:send_email_confirmation)
.and_expose(:user_registered, [:user, :user_token])
end
private
def check_if_email_is_taken(email:, **)
input.errors.add(:email, "has already been taken") if deps.repository.exists?(email:)
input.errors.any? ? Failure(:invalid_input, input:) : Continue()
end
def create_user(uuid:, email:, password:, password_confirmation:, **)
case deps.repository.create!(uuid:, email:, password:, password_confirmation:)
in Solid::Success(user:) then Continue(user:)
in Solid::Failure(user:)
input.errors.merge!(user.errors)
Failure(:invalid_input, input:)
end
end
def create_user_account(user:, **)
case deps.account_creation.call(uuid: user.uuid)
in Solid::Success then Continue()
end
end
def create_user_token(user:, **)
case deps.token_creation.call(user:)
in Solid::Success(token:) then Continue(user_token: token.value)
end
end
def send_email_confirmation(user:, **)
token = deps.temporary_token.to(:email_confirmation, user)
deps.mailer.send_email_confirmation(token:, email: user.email)
Continue()
end
end