okkez-multi_auth 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. data/README +36 -0
  2. data/app/controllers/application_controller.rb +11 -0
  3. data/app/controllers/auth/email_controller.rb +34 -0
  4. data/app/controllers/auth/open_id_controller.rb +43 -0
  5. data/app/controllers/auth_controller.rb +24 -0
  6. data/app/controllers/credentials/email_controller.rb +156 -0
  7. data/app/controllers/credentials/open_id_controller.rb +85 -0
  8. data/app/controllers/credentials_controller.rb +14 -0
  9. data/app/controllers/signup/email_controller.rb +132 -0
  10. data/app/controllers/signup/open_id_controller.rb +62 -0
  11. data/app/controllers/signup_controller.rb +8 -0
  12. data/app/helpers/application_helper.rb +5 -0
  13. data/app/models/activation_mailer.rb +114 -0
  14. data/app/models/email_credential.rb +89 -0
  15. data/app/models/email_credential_edit_form.rb +52 -0
  16. data/app/models/email_login_form.rb +24 -0
  17. data/app/models/email_password_edit_form.rb +36 -0
  18. data/app/models/open_id_credential.rb +33 -0
  19. data/app/models/open_id_login_form.rb +17 -0
  20. data/app/models/session.rb +19 -0
  21. data/app/models/user.rb +37 -0
  22. data/app/views/activation_mailer/complete_for_credential.erb +4 -0
  23. data/app/views/activation_mailer/complete_for_notice.erb +4 -0
  24. data/app/views/activation_mailer/complete_for_signup.erb +4 -0
  25. data/app/views/activation_mailer/request_for_credential.erb +11 -0
  26. data/app/views/activation_mailer/request_for_notice.erb +11 -0
  27. data/app/views/activation_mailer/request_for_signup.erb +11 -0
  28. data/app/views/auth/email/index.html.erb +90 -0
  29. data/app/views/auth/logged_in.html.erb +21 -0
  30. data/app/views/auth/logged_out.html.erb +21 -0
  31. data/app/views/auth/open_id/index.html.erb +16 -0
  32. data/app/views/credentials/email/activated.html.erb +4 -0
  33. data/app/views/credentials/email/activation.html.erb +15 -0
  34. data/app/views/credentials/email/created.html.erb +15 -0
  35. data/app/views/credentials/email/delete.html.erb +20 -0
  36. data/app/views/credentials/email/edit_password.html.erb +31 -0
  37. data/app/views/credentials/email/new.html.erb +36 -0
  38. data/app/views/credentials/index.html.erb +88 -0
  39. data/app/views/credentials/open_id/delete.html.erb +20 -0
  40. data/app/views/credentials/open_id/new.html.erb +26 -0
  41. data/app/views/signup/email/_progress.html.erb +14 -0
  42. data/app/views/signup/email/activated.html.erb +9 -0
  43. data/app/views/signup/email/activation.html.erb +27 -0
  44. data/app/views/signup/email/created.html.erb +14 -0
  45. data/app/views/signup/email/index.html.erb +34 -0
  46. data/app/views/signup/email/validated.html.erb +21 -0
  47. data/app/views/signup/index.html.erb +51 -0
  48. data/app/views/signup/open_id/authenticated.html.erb +15 -0
  49. data/app/views/signup/open_id/created.html.erb +6 -0
  50. data/app/views/signup/open_id/index.html.erb +16 -0
  51. data/config/boot.rb +110 -0
  52. data/config/database.yml +22 -0
  53. data/config/database.yml.sqlite3 +22 -0
  54. data/config/environment.rb +62 -0
  55. data/config/routes.rb +51 -0
  56. data/config/smtp.yml.example +8 -0
  57. data/db/development.sqlite3 +0 -0
  58. data/db/schema.rb +88 -0
  59. data/db/test.sqlite3 +0 -0
  60. data/lib/action_mailer_util.rb +15 -0
  61. data/lib/multi_auth.rb +64 -0
  62. data/lib/multi_auth_helper.rb +98 -0
  63. data/lib/notice_formatter.rb +106 -0
  64. data/lib/open_id_authentication/result.rb +12 -0
  65. data/lib/token_util.rb +18 -0
  66. data/public/404.html +92 -0
  67. data/public/422.html +91 -0
  68. data/public/500.html +92 -0
  69. data/public/503.html +92 -0
  70. data/public/favicon.ico +0 -0
  71. data/public/images/battery/cell.png +0 -0
  72. data/public/images/battery/level-green.png +0 -0
  73. data/public/images/battery/level-orange.png +0 -0
  74. data/public/images/battery/level-red.png +0 -0
  75. data/public/images/battery/level-yellow.png +0 -0
  76. data/public/images/battery/style.html +82 -0
  77. data/public/images/favicons/livedoor.png +0 -0
  78. data/public/images/favicons/mixi.png +0 -0
  79. data/public/images/favicons/yahoo.png +0 -0
  80. data/public/images/h1-back.png +0 -0
  81. data/public/images/icons/fam/add.png +0 -0
  82. data/public/images/icons/fam/bin.png +0 -0
  83. data/public/images/icons/fam/bomb.png +0 -0
  84. data/public/images/icons/fam/cog.png +0 -0
  85. data/public/images/icons/fam/delete.png +0 -0
  86. data/public/images/icons/fam/email-with-desc.png +0 -0
  87. data/public/images/icons/fam/email.png +0 -0
  88. data/public/images/icons/fam/feed.png +0 -0
  89. data/public/images/icons/fam/help.png +0 -0
  90. data/public/images/icons/fam/key-with-desc.png +0 -0
  91. data/public/images/icons/fam/key.png +0 -0
  92. data/public/images/icons/fam/lightning.png +0 -0
  93. data/public/images/icons/fam/plugin.png +0 -0
  94. data/public/images/icons/fam/stop.png +0 -0
  95. data/public/images/icons/fam/table_save.png +0 -0
  96. data/public/images/icons/fam/tick.png +0 -0
  97. data/public/images/icons/fam/user.png +0 -0
  98. data/public/images/icons/fam/vcard.png +0 -0
  99. data/public/images/icons/openid-with-desc.png +0 -0
  100. data/public/images/icons/openid.png +0 -0
  101. data/public/images/logo-back.png +0 -0
  102. data/public/images/logo.png +0 -0
  103. data/public/images/side-column-back.png +0 -0
  104. data/public/javascripts/application.js +2 -0
  105. data/public/javascripts/controls.js +963 -0
  106. data/public/javascripts/dragdrop.js +973 -0
  107. data/public/javascripts/effects.js +1128 -0
  108. data/public/javascripts/prototype.js +4320 -0
  109. data/public/robots.txt +5 -0
  110. data/public/stylesheets/application.css +365 -0
  111. data/public/stylesheets/auth.css +22 -0
  112. data/public/stylesheets/home.css +114 -0
  113. data/rails/init.rb +24 -0
  114. data/test/functional/auth/email_controller_test.rb +102 -0
  115. data/test/functional/auth/open_id_controller_test.rb +76 -0
  116. data/test/functional/auth_controller_test.rb +74 -0
  117. data/test/functional/credentials/email_controller_test.rb +488 -0
  118. data/test/functional/credentials/open_id_controller_test.rb +308 -0
  119. data/test/functional/credentials_controller_test.rb +49 -0
  120. data/test/functional/signup/email_controller_test.rb +369 -0
  121. data/test/functional/signup/open_id_controller_test.rb +44 -0
  122. data/test/functional/signup_controller_test.rb +17 -0
  123. data/test/performance/browsing_test.rb +9 -0
  124. data/test/test_helper.rb +82 -0
  125. data/test/unit/action_mailer_util_test.rb +63 -0
  126. data/test/unit/activation_mailer_test.rb +181 -0
  127. data/test/unit/email_credential_edit_form_test.rb +173 -0
  128. data/test/unit/email_credential_test.rb +324 -0
  129. data/test/unit/email_login_form_test.rb +76 -0
  130. data/test/unit/email_password_edit_form_test.rb +117 -0
  131. data/test/unit/helpers/auth_helper_test.rb +4 -0
  132. data/test/unit/helpers/credentials/email_helper_test.rb +4 -0
  133. data/test/unit/helpers/credentials/open_id_helper_test.rb +4 -0
  134. data/test/unit/helpers/credentials_helper_test.rb +4 -0
  135. data/test/unit/helpers/email_auth_helper_test.rb +4 -0
  136. data/test/unit/helpers/email_signup_helper_test.rb +4 -0
  137. data/test/unit/helpers/open_id_auth_helper_test.rb +4 -0
  138. data/test/unit/helpers/open_id_signup_helper_test.rb +4 -0
  139. data/test/unit/helpers/password_auth_helper_test.rb +4 -0
  140. data/test/unit/helpers/password_signup_helper_test.rb +4 -0
  141. data/test/unit/helpers/signup_helper_test.rb +4 -0
  142. data/test/unit/notice_formatter_test.rb +153 -0
  143. data/test/unit/open_id_credential_test.rb +108 -0
  144. data/test/unit/open_id_login_form_test.rb +57 -0
  145. data/test/unit/session_test.rb +53 -0
  146. data/test/unit/token_util_test.rb +51 -0
  147. data/test/unit/user_test.rb +177 -0
  148. metadata +220 -0
@@ -0,0 +1,181 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+
5
+ class ActivationMailerTest < ActionMailer::TestCase
6
+ def setup
7
+ @klass = ActivationMailer
8
+ end
9
+
10
+ #
11
+ # クラスメソッド
12
+ #
13
+
14
+ test "self.create_request_for_signup_params" do
15
+ options = {
16
+ :recipients => "recipients@example.jp",
17
+ :activation_url => "http://activation/url",
18
+ }
19
+ expected = {
20
+ :subject => "[#{MultiAuth.application_name}] ユーザ登録",
21
+ :from => @klass::FromAddress,
22
+ :recipients => "recipients@example.jp",
23
+ :body => {:activation_url => "http://activation/url"},
24
+ }
25
+ assert_equal(expected, @klass.create_request_for_signup_params(options))
26
+ end
27
+
28
+ test "self.create_request_for_signup_params, invalid parameter" do
29
+ options = {:recipients => "", :activation_url => ""}
30
+ assert_nothing_raised { @klass.create_request_for_signup_params(options) }
31
+ assert_raise(ArgumentError) { @klass.create_request_for_signup_params(options.merge(:recipients => nil)) }
32
+ assert_raise(ArgumentError) { @klass.create_request_for_signup_params(options.merge(:activation_url => nil)) }
33
+ assert_raise(ArgumentError) { @klass.create_request_for_signup_params(options.merge(:invalid => true)) }
34
+ end
35
+
36
+ test "self.create_complete_for_signup_params" do
37
+ options = {
38
+ :recipients => "recipients@example.jp",
39
+ }
40
+ expected = {
41
+ :subject => "[#{MultiAuth.application_name}] ユーザ登録完了",
42
+ :from => @klass::FromAddress,
43
+ :recipients => "recipients@example.jp",
44
+ :body => {},
45
+ }
46
+ assert_equal(expected, @klass.create_complete_for_signup_params(options))
47
+ end
48
+
49
+ test "self.create_complete_for_signup_params, invalid parameter" do
50
+ options = {:recipients => ""}
51
+ assert_nothing_raised { @klass.create_complete_for_signup_params(options) }
52
+ assert_raise(ArgumentError) { @klass.create_complete_for_signup_params(options.merge(:recipients => nil)) }
53
+ assert_raise(ArgumentError) { @klass.create_complete_for_signup_params(options.merge(:invalid => true)) }
54
+ end
55
+
56
+ test "self.create_request_for_credential_params" do
57
+ options = {
58
+ :recipients => "recipients@example.jp",
59
+ :activation_url => "http://activation/url",
60
+ }
61
+ expected = {
62
+ :subject => "[#{MultiAuth.application_name}] メールアドレス認証登録",
63
+ :from => @klass::FromAddress,
64
+ :recipients => "recipients@example.jp",
65
+ :body => {:activation_url => "http://activation/url"},
66
+ }
67
+ assert_equal(expected, @klass.create_request_for_credential_params(options))
68
+ end
69
+
70
+ test "self.create_request_for_credential_params, invalid parameter" do
71
+ options = {:recipients => "", :activation_url => ""}
72
+ assert_nothing_raised { @klass.create_request_for_credential_params(options) }
73
+ assert_raise(ArgumentError) { @klass.create_request_for_credential_params(options.merge(:recipients => nil)) }
74
+ assert_raise(ArgumentError) { @klass.create_request_for_credential_params(options.merge(:activation_url => nil)) }
75
+ assert_raise(ArgumentError) { @klass.create_request_for_credential_params(options.merge(:invalid => true)) }
76
+ end
77
+
78
+ test "self.create_complete_for_credential_params" do
79
+ options = {
80
+ :recipients => "recipients@example.jp",
81
+ }
82
+ expected = {
83
+ :subject => "[#{MultiAuth.application_name}] メールアドレス認証登録完了",
84
+ :from => @klass::FromAddress,
85
+ :recipients => "recipients@example.jp",
86
+ :body => {},
87
+ }
88
+ assert_equal(expected, @klass.create_complete_for_credential_params(options))
89
+ end
90
+
91
+ test "self.create_complete_for_credential_params, invalid parameter" do
92
+ options = {:recipients => ""}
93
+ assert_nothing_raised { @klass.create_complete_for_credential_params(options) }
94
+ assert_raise(ArgumentError) { @klass.create_complete_for_credential_params(options.merge(:recipients => nil)) }
95
+ assert_raise(ArgumentError) { @klass.create_complete_for_credential_params(options.merge(:invalid => true)) }
96
+ end
97
+
98
+ test "self.create_request_for_notice_params" do
99
+ options = {
100
+ :recipients => "recipients@example.jp",
101
+ :activation_url => "http://activation/url",
102
+ }
103
+ expected = {
104
+ :subject => "[#{MultiAuth.application_name}] 通知先メールアドレス登録",
105
+ :from => @klass::FromAddress,
106
+ :recipients => "recipients@example.jp",
107
+ :body => {:activation_url => "http://activation/url"},
108
+ }
109
+ assert_equal(expected, @klass.create_request_for_notice_params(options))
110
+ end
111
+
112
+ test "self.create_request_for_notice_params, invalid parameter" do
113
+ options = {:recipients => "", :activation_url => ""}
114
+ assert_nothing_raised { @klass.create_request_for_notice_params(options) }
115
+ assert_raise(ArgumentError) { @klass.create_request_for_notice_params(options.merge(:recipients => nil)) }
116
+ assert_raise(ArgumentError) { @klass.create_request_for_notice_params(options.merge(:activation_url => nil)) }
117
+ assert_raise(ArgumentError) { @klass.create_request_for_notice_params(options.merge(:invalid => true)) }
118
+ end
119
+
120
+ test "self.create_complete_for_notice_params" do
121
+ options = {
122
+ :recipients => "recipients@example.jp",
123
+ }
124
+ expected = {
125
+ :subject => "[#{MultiAuth.application_name}] 通知先メールアドレス登録完了",
126
+ :from => @klass::FromAddress,
127
+ :recipients => "recipients@example.jp",
128
+ :body => {},
129
+ }
130
+ assert_equal(expected, @klass.create_complete_for_notice_params(options))
131
+ end
132
+
133
+ test "self.create_complete_for_notice_params, invalid parameter" do
134
+ options = {:recipients => ""}
135
+ assert_nothing_raised { @klass.create_complete_for_notice_params(options) }
136
+ assert_raise(ArgumentError) { @klass.create_complete_for_notice_params(options.merge(:recipients => nil)) }
137
+ assert_raise(ArgumentError) { @klass.create_complete_for_notice_params(options.merge(:invalid => true)) }
138
+ end
139
+
140
+ #
141
+ # インスタンスメソッド
142
+ #
143
+
144
+ test "request_for_signup" do
145
+ options = {
146
+ :recipients => email_credentials(:yuya_nayutaya).email,
147
+ :activation_url => "http://activation/url/" + email_credentials(:yuya_nayutaya).activation_token,
148
+ }
149
+ assert_nothing_raised {
150
+ @klass.create_request_for_signup(options).encoded
151
+ }
152
+ end
153
+
154
+ test "complete_for_signup" do
155
+ options = {
156
+ :recipients => email_credentials(:yuya_nayutaya).email,
157
+ }
158
+ assert_nothing_raised {
159
+ @klass.create_complete_for_signup(options).encoded
160
+ }
161
+ end
162
+
163
+ test "request_for_credential" do
164
+ options = {
165
+ :recipients => email_credentials(:yuya_nayutaya).email,
166
+ :activation_url => "http://activation/url/" + email_credentials(:yuya_nayutaya).activation_token,
167
+ }
168
+ assert_nothing_raised {
169
+ @klass.create_request_for_credential(options).encoded
170
+ }
171
+ end
172
+
173
+ test "complete_for_credential" do
174
+ options = {
175
+ :recipients => email_credentials(:yuya_nayutaya).email,
176
+ }
177
+ assert_nothing_raised {
178
+ @klass.create_complete_for_credential(options).encoded
179
+ }
180
+ end
181
+ end
@@ -0,0 +1,173 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+
5
+ class EmailCredentialEditFormTest < ActiveSupport::TestCase
6
+ def setup
7
+ @klass = EmailCredentialEditForm
8
+ @form = @klass.new
9
+ @basic = @klass.new(
10
+ :email => "email@example.jp",
11
+ :password => "password",
12
+ :password_confirmation => "password")
13
+ end
14
+
15
+ #
16
+ # 基底クラス
17
+ #
18
+
19
+ test "superclass" do
20
+ assert_equal(ActiveForm, @klass.superclass)
21
+ end
22
+
23
+ #
24
+ # カラム
25
+ #
26
+
27
+ test "columns" do
28
+ [
29
+ [:email, nil, "str", "str"],
30
+ [:password, nil, "str", "str"],
31
+ [:password_confirmation, nil, "str", "str"],
32
+ ].each { |name, default, set_value, get_value|
33
+ form = @klass.new
34
+ assert_equal(default, form.__send__(name))
35
+ form.__send__("#{name}=", set_value)
36
+ assert_equal(get_value, form.__send__(name))
37
+ }
38
+ end
39
+
40
+ #
41
+ # 検証
42
+ #
43
+
44
+ test "basic is valid" do
45
+ assert_equal(true, @basic.valid?)
46
+ end
47
+
48
+ test "validates_presence_of :email" do
49
+ @basic.email = nil
50
+ assert_equal(false, @basic.valid?)
51
+ end
52
+
53
+ test "validates_presence_of :password" do
54
+ @basic.password = nil
55
+ assert_equal(false, @basic.valid?)
56
+ end
57
+
58
+ test "validates_presence_of :password_confirmation" do
59
+ @basic.password_confirmation = nil
60
+ assert_equal(false, @basic.valid?)
61
+ end
62
+
63
+ test "validates_length_of :email" do
64
+ # MEMO: 下記の制約を満たしつつ、文字列長の検証のテストを行う
65
+ # * ローカルパートは64文字以内
66
+ # * ドメインパートは255文字以内
67
+ # * ドメインパートのドットで区切られたパートは63文字以内
68
+
69
+ [
70
+ ["a@b.cd.ef.com", 13, true ],
71
+ [["a" * 64 + "@" + "b" * 63, "c" * 63, "d" * 3, "com"].join("."), 200, true ],
72
+ [["a" * 64 + "@" + "b" * 63, "c" * 63, "d" * 4, "com"].join("."), 201, false],
73
+ ].each { |value, length, expected|
74
+ assert_equal(length, value.size)
75
+ @basic.email = value
76
+ assert_equal(expected, @basic.valid?)
77
+ }
78
+ end
79
+
80
+ test "validates_length_of :password" do
81
+ [
82
+ ["a" * 3, false],
83
+ ["a" * 4, true ],
84
+ ["a" * 20, true ],
85
+ ["a" * 21, false],
86
+ ].each { |value, expected|
87
+ @basic.password = value
88
+ @basic.password_confirmation = value
89
+ assert_equal(expected, @basic.valid?)
90
+ }
91
+ end
92
+
93
+ test "validates_format_of :password" do
94
+ valid_chars = (0x21..0x7E).map { |c| c.chr }.join
95
+
96
+ [
97
+ [valid_chars.slice!(0, 20), true ],
98
+ [valid_chars.slice!(0, 20), true ],
99
+ [valid_chars.slice!(0, 20), true ],
100
+ [valid_chars.slice!(0, 20), true ],
101
+ [valid_chars.slice!(0, 20), true ],
102
+ ["aaaa", true ],
103
+ ["aaa ", false],
104
+ ["日本語", false],
105
+ ].each { |value, expected|
106
+ @basic.password = value
107
+ @basic.password_confirmation = value
108
+ assert_equal(expected, @basic.valid?)
109
+ }
110
+
111
+ assert_equal(true, valid_chars.empty?)
112
+ end
113
+
114
+ test "validates_email_format_of :email" do
115
+ [
116
+ ["foo@example.com", true ],
117
+ ["foo@example.co.jp", true ],
118
+ ["foo@example", false],
119
+ ].each { |value, expected|
120
+ @basic.email = value
121
+ assert_equal(
122
+ {:in => value, :out => expected},
123
+ {:in => value, :out => @basic.valid?})
124
+ }
125
+ end
126
+
127
+ test "validates_each, password" do
128
+ @basic.password = "aaaa"
129
+ @basic.password_confirmation = "aaaa"
130
+ assert_equal(true, @basic.valid?)
131
+
132
+ @basic.password = "aaaa"
133
+ @basic.password_confirmation = "AAAA"
134
+ assert_equal(false, @basic.valid?)
135
+ end
136
+
137
+ #
138
+ # インスタンスメソッド
139
+ #
140
+
141
+ test "masked_password" do
142
+ @form.password = nil
143
+ assert_equal("", @form.masked_password)
144
+
145
+ @form.password = "a"
146
+ assert_equal("*", @form.masked_password)
147
+
148
+ @form.password = "abc"
149
+ assert_equal("***", @form.masked_password)
150
+ end
151
+
152
+ test "to_email_credential_hash, empty" do
153
+ hash = @form.to_email_credential_hash
154
+ assert_equal(
155
+ [:email, :hashed_password].map(&:to_s).sort,
156
+ hash.keys.map(&:to_s).sort)
157
+ assert_equal(nil, hash[:email])
158
+ assert_equal(true, EmailCredential.compare_hashed_password("", hash[:hashed_password]))
159
+ end
160
+
161
+ test "to_email_credential_hash, full" do
162
+ @form.attributes = {
163
+ :email => "foo@example.com",
164
+ :password => "foo",
165
+ }
166
+ hash = @form.to_email_credential_hash
167
+ assert_equal(
168
+ [:email, :hashed_password].map(&:to_s).sort,
169
+ hash.keys.map(&:to_s).sort)
170
+ assert_equal(@form.email, hash[:email])
171
+ assert_equal(true, EmailCredential.compare_hashed_password(@form.password, hash[:hashed_password]))
172
+ end
173
+ end
@@ -0,0 +1,324 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+
5
+ class EmailCredentialTest < ActiveSupport::TestCase
6
+ def setup
7
+ @klass = EmailCredential
8
+ @basic = @klass.new(
9
+ :activation_token => "0" * @klass::TokenLength,
10
+ :user_id => users(:yuya).id,
11
+ :email => "foo@example.com",
12
+ :hashed_password => ("0" * 8) + ":" + ("0" * 64))
13
+
14
+ @yuya_gmail = email_credentials(:yuya_gmail)
15
+ @risa_example = email_credentials(:risa_example)
16
+ end
17
+
18
+ #
19
+ # 関連
20
+ #
21
+
22
+ test "belongs_to :user" do
23
+ assert_equal(
24
+ users(:yuya),
25
+ @yuya_gmail.user)
26
+
27
+ assert_equal(
28
+ users(:risa),
29
+ @risa_example.user)
30
+ end
31
+
32
+ #
33
+ # 検証
34
+ #
35
+
36
+ test "all fixtures are valid" do
37
+ assert_equal(true, @klass.all.all?(&:valid?))
38
+ end
39
+
40
+ test "basic is valid" do
41
+ assert_equal(true, @basic.valid?)
42
+ end
43
+
44
+ test "validates_presence_of :email" do
45
+ @basic.email = nil
46
+ assert_equal(false, @basic.valid?)
47
+ end
48
+
49
+ =begin MEMO: before_validation_on_createによりテスト不可
50
+ test "validates_presence_of :activation_token" do
51
+ @basic.activation_token = ""
52
+ assert_equal(false, @basic.valid?)
53
+ end
54
+ =end
55
+
56
+ test "validates_presence_of :hashed_password" do
57
+ @basic.hashed_password = nil
58
+ assert_equal(false, @basic.valid?)
59
+ end
60
+
61
+ test "validates_length_of :email" do
62
+ # MEMO: 下記の制約を満たしつつ、文字列長の検証のテストを行う
63
+ # * ローカルパートは64文字以内
64
+ # * ドメインパートは255文字以内
65
+ # * ドメインパートのドットで区切られたパートは63文字以内
66
+
67
+ [
68
+ ["a@b.cd.ef.com", 13, true ],
69
+ [["a" * 64 + "@" + "b" * 63, "c" * 63, "d" * 3, "com"].join("."), 200, true ],
70
+ [["a" * 64 + "@" + "b" * 63, "c" * 63, "d" * 4, "com"].join("."), 201, false],
71
+ ].each { |value, length, expected|
72
+ assert_equal(length, value.size)
73
+ @basic.email = value
74
+ assert_equal(expected, @basic.valid?)
75
+ }
76
+ end
77
+
78
+ test "validates_format_of :activation_token" do
79
+ [
80
+ ["0123456789abcdef0000", true ],
81
+ ["0" * 19, false],
82
+ ["0" * 20, true ],
83
+ ["0" * 21, false],
84
+ ["0" * 19 + "A", false],
85
+ ["0" * 19 + "g", false],
86
+ ].each { |value, expected|
87
+ @basic.activation_token = value
88
+ assert_equal(expected, @basic.valid?, value)
89
+ }
90
+ end
91
+
92
+ test "validates_format_of :hashed_password" do
93
+ [
94
+ # ソルト値部分
95
+ ["01234567" + ":" + "0" * 64, true ],
96
+ ["89abcdef" + ":" + "0" * 64, true ],
97
+ ["0000000" + ":" + "0" * 64, false],
98
+ ["00000000" + ":" + "0" * 64, true ],
99
+ ["000000000" + ":" + "0" * 64, false],
100
+ ["0000000A" + ":" + "0" * 64, false],
101
+ ["0000000g" + ":" + "0" * 64, false],
102
+ # ハッシュ値部分
103
+ ["00000000" + ":" + "0123456789abcdef" + "0" * (64 - 16), true ],
104
+ ["00000000" + ":" + "0" * (64 - 1), false],
105
+ ["00000000" + ":" + "0" * 64, true ],
106
+ ["00000000" + ":" + "0" * (64 + 1), false],
107
+ ["00000000" + ":" + "0" * (64 - 1) + "A", false],
108
+ ["00000000" + ":" + "0" * (64 - 1) + "g", false],
109
+ ].each { |value, expected|
110
+ @basic.hashed_password = value
111
+ assert_equal(expected, @basic.valid?, value)
112
+ }
113
+ end
114
+
115
+ test "validates_email_format_of :email" do
116
+ [
117
+ ["foo@example.com", true ],
118
+ ["foo@example.co.jp", true ],
119
+ ["foo@example", false],
120
+ ].each { |value, expected|
121
+ @basic.email = value
122
+ assert_equal(
123
+ {:in => value, :out => expected},
124
+ {:in => value, :out => @basic.valid?})
125
+ }
126
+ end
127
+
128
+ test "validates_uniqueness_of :email, on create" do
129
+ @basic.email = @yuya_gmail.email
130
+ assert_equal(false, @basic.valid?)
131
+ end
132
+
133
+ test "validates_uniqueness_of :email, on update" do
134
+ @yuya_gmail.email = @risa_example.email
135
+ assert_equal(false, @yuya_gmail.valid?)
136
+ end
137
+
138
+ test "validates_each :user_id" do
139
+ srand(0)
140
+ user = users(:yuya)
141
+ create_record = proc {
142
+ user.email_credentials.create!(
143
+ :activation_token => @klass.create_unique_activation_token,
144
+ :email => "email#{rand(1000)}@example.com",
145
+ :hashed_password => ("0" * 8) + ":" + ("0" * 64))
146
+ }
147
+
148
+ assert_nothing_raised {
149
+ (10 - user.email_credentials.size).times {
150
+ record = create_record[]
151
+ record.save!
152
+ }
153
+ }
154
+ assert_raise(ActiveRecord::RecordInvalid) {
155
+ create_record[]
156
+ }
157
+ end
158
+
159
+ #
160
+ # フック
161
+ #
162
+
163
+ test "before_validation_on_create, nil" do
164
+ token = "9" * @klass::TokenLength
165
+
166
+ record = @klass.new(@basic.attributes)
167
+ record.activation_token = nil
168
+
169
+ Kagemusha.new(@klass).
170
+ defs(:create_unique_activation_token) { token }.
171
+ swap {
172
+ record.save!
173
+ }
174
+
175
+ assert_equal(token, record.reload.activation_token)
176
+ end
177
+
178
+ test "before_validation_on_create, empty string" do
179
+ token = "9" * @klass::TokenLength
180
+
181
+ record = @klass.new(@basic.attributes)
182
+ record.activation_token = ""
183
+
184
+ Kagemusha.new(@klass).
185
+ defs(:create_unique_activation_token) { token }.
186
+ swap {
187
+ record.save!
188
+ }
189
+
190
+ assert_equal(token, record.reload.activation_token)
191
+ end
192
+
193
+ test "before_validation_on_create, already setting" do
194
+ token = "9" * @klass::TokenLength
195
+
196
+ record = @klass.new(@basic.attributes)
197
+ record.activation_token = token
198
+ record.save!
199
+
200
+ assert_equal(token, record.reload.activation_token)
201
+ end
202
+
203
+ #
204
+ # クラスメソッド
205
+ #
206
+
207
+ test "self.create_unique_activation_token, pattern" do
208
+ assert_match(
209
+ @klass::TokenPattern,
210
+ @klass.create_unique_activation_token)
211
+ end
212
+
213
+ test "self.create_unique_activation_token, duplication" do
214
+ dup_token1 = @yuya_gmail.activation_token
215
+ dup_token2 = @risa_example.activation_token
216
+ uniq_token = "f" * @klass::TokenLength
217
+ tokens = [dup_token1, dup_token2, uniq_token]
218
+
219
+ musha = Kagemusha.new(TokenUtil)
220
+ musha.defs(:create_token) { tokens.shift }
221
+ musha.swap {
222
+ assert_equal(
223
+ uniq_token,
224
+ @klass.create_unique_activation_token)
225
+ }
226
+ end
227
+
228
+ test "self.create_hashed_password" do
229
+ assert_match(
230
+ /\A[0-9a-f]{8}:[0-9a-f]{64}\z/,
231
+ @klass.create_hashed_password("a"))
232
+
233
+ # 異なるパスワードでは、異なる値になること
234
+ assert_not_equal(
235
+ @klass.create_hashed_password("a"),
236
+ @klass.create_hashed_password("b"))
237
+
238
+ # 同一のパスワードでも、異なる値になること
239
+ assert_not_equal(
240
+ @klass.create_hashed_password("a"),
241
+ @klass.create_hashed_password("a"))
242
+ end
243
+
244
+ test "self.compare_hashed_password" do
245
+ # ソルト、パスワードが一致
246
+ assert_equal(
247
+ true,
248
+ @klass.compare_hashed_password(
249
+ "password",
250
+ "00000000:" + Digest::SHA256.hexdigest("00000000:password")))
251
+
252
+ # ソルトが不一致、パスワードが一致
253
+ assert_equal(
254
+ false,
255
+ @klass.compare_hashed_password(
256
+ "password",
257
+ "00000000:" + Digest::SHA256.hexdigest("11111111:password")))
258
+
259
+ # ソルトが一致、パスワードが不一致
260
+ assert_equal(
261
+ false,
262
+ @klass.compare_hashed_password(
263
+ "password",
264
+ "00000000:" + Digest::SHA256.hexdigest("00000000:PASSWORD")))
265
+ end
266
+
267
+ test "self.authenticate" do
268
+ assert_equal(
269
+ email_credentials(:yuya_gmail),
270
+ @klass.authenticate(email_credentials(:yuya_gmail).email, "yuya_gmail"))
271
+
272
+ assert_equal(
273
+ nil,
274
+ @klass.authenticate(email_credentials(:yuya_gmail).email, "YUYA_GMAIL"))
275
+
276
+ assert_equal(
277
+ nil,
278
+ @klass.authenticate(nil, nil))
279
+ end
280
+
281
+ #
282
+ # インスタンスメソッド
283
+ #
284
+
285
+ test "authenticated?" do
286
+ assert_equal(true, email_credentials(:yuya_gmail).authenticated?("yuya_gmail"))
287
+ assert_equal(false, email_credentials(:yuya_gmail).authenticated?("YUYA_GMAIL"))
288
+ assert_equal(false, email_credentials(:yuya_nayutaya).authenticated?("yuya_nayutaya"))
289
+ end
290
+
291
+ test "activated?" do
292
+ assert_equal(true, email_credentials(:yuya_gmail).activated?)
293
+ assert_equal(false, email_credentials(:yuya_nayutaya).activated?)
294
+ end
295
+
296
+ test "activate!" do
297
+ credential = email_credentials(:yuya_nayutaya)
298
+ time = Time.local(2010, 1, 1)
299
+
300
+ assert_equal(false, credential.activated?)
301
+ assert_equal(true, Kagemusha::DateTime.at(time) { credential.activate! })
302
+ credential.reload
303
+ assert_equal(true, credential.activated?)
304
+ assert_equal(time, credential.activated_at)
305
+ end
306
+
307
+ test "activate!, already activated" do
308
+ credential = email_credentials(:yuya_gmail)
309
+ time = credential.activated_at
310
+
311
+ assert_equal(true, credential.activated?)
312
+ assert_equal(false, credential.activate!)
313
+ credential.reload
314
+ assert_equal(true, credential.activated?)
315
+ assert_equal(time, credential.activated_at)
316
+ end
317
+
318
+ test "login!" do
319
+ time = Time.local(2010, 1, 1)
320
+ assert_equal(nil, @risa_example.loggedin_at)
321
+ Kagemusha::DateTime.at(time) { @risa_example.login! }
322
+ assert_equal(time, @risa_example.reload.loggedin_at)
323
+ end
324
+ end