trainmaster 0.1.0

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 (79) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +286 -0
  4. data/Rakefile +38 -0
  5. data/app/controllers/trainmaster/application_controller.rb +9 -0
  6. data/app/controllers/trainmaster/sessions_controller.rb +141 -0
  7. data/app/controllers/trainmaster/users_controller.rb +199 -0
  8. data/app/helpers/trainmaster/application_helper.rb +313 -0
  9. data/app/helpers/trainmaster/sessions_helper.rb +4 -0
  10. data/app/helpers/trainmaster/users_helper.rb +4 -0
  11. data/app/jobs/trainmaster/sessions_cleanup_job.rb +13 -0
  12. data/app/mailers/application_mailer.rb +4 -0
  13. data/app/mailers/trainmaster/user_mailer.rb +14 -0
  14. data/app/models/trainmaster/session.rb +56 -0
  15. data/app/models/trainmaster/user.rb +77 -0
  16. data/app/views/layouts/mailer.html.erb +5 -0
  17. data/app/views/layouts/mailer.text.erb +1 -0
  18. data/app/views/layouts/trainmaster/application.html.erb +14 -0
  19. data/app/views/trainmaster/user_mailer/email_verification.html.erb +12 -0
  20. data/app/views/trainmaster/user_mailer/email_verification.text.erb +13 -0
  21. data/app/views/trainmaster/user_mailer/password_reset.html.erb +14 -0
  22. data/app/views/trainmaster/user_mailer/password_reset.text.erb +15 -0
  23. data/config/routes.rb +10 -0
  24. data/db/migrate/20161120020344_create_trainmaster_users.rb +23 -0
  25. data/db/migrate/20161120020722_create_trainmaster_sessions.rb +11 -0
  26. data/lib/tasks/trainmaster_tasks.rake +4 -0
  27. data/lib/trainmaster.rb +10 -0
  28. data/lib/trainmaster/cache.rb +28 -0
  29. data/lib/trainmaster/engine.rb +9 -0
  30. data/lib/trainmaster/roles.rb +12 -0
  31. data/lib/trainmaster/version.rb +3 -0
  32. data/test/controllers/trainmaster/application_controller_test.rb +106 -0
  33. data/test/controllers/trainmaster/sessions_controller_test.rb +275 -0
  34. data/test/controllers/trainmaster/users_controller_test.rb +335 -0
  35. data/test/dummy/README.rdoc +28 -0
  36. data/test/dummy/Rakefile +6 -0
  37. data/test/dummy/app/assets/javascripts/application.js +13 -0
  38. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  39. data/test/dummy/app/controllers/application_controller.rb +5 -0
  40. data/test/dummy/app/helpers/application_helper.rb +2 -0
  41. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  42. data/test/dummy/bin/bundle +3 -0
  43. data/test/dummy/bin/rails +4 -0
  44. data/test/dummy/bin/rake +4 -0
  45. data/test/dummy/bin/setup +29 -0
  46. data/test/dummy/config.ru +4 -0
  47. data/test/dummy/config/application.rb +34 -0
  48. data/test/dummy/config/boot.rb +5 -0
  49. data/test/dummy/config/database.yml +25 -0
  50. data/test/dummy/config/environment.rb +5 -0
  51. data/test/dummy/config/environments/development.rb +41 -0
  52. data/test/dummy/config/environments/production.rb +79 -0
  53. data/test/dummy/config/environments/test.rb +44 -0
  54. data/test/dummy/config/initializers/assets.rb +11 -0
  55. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  56. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  57. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  58. data/test/dummy/config/initializers/inflections.rb +16 -0
  59. data/test/dummy/config/initializers/mime_types.rb +4 -0
  60. data/test/dummy/config/initializers/session_store.rb +3 -0
  61. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  62. data/test/dummy/config/locales/en.yml +23 -0
  63. data/test/dummy/config/routes.rb +4 -0
  64. data/test/dummy/config/secrets.yml +22 -0
  65. data/test/dummy/public/404.html +67 -0
  66. data/test/dummy/public/422.html +67 -0
  67. data/test/dummy/public/500.html +66 -0
  68. data/test/dummy/public/favicon.ico +0 -0
  69. data/test/fixtures/trainmaster/sessions.yml +36 -0
  70. data/test/fixtures/trainmaster/users.yml +27 -0
  71. data/test/integration/navigation_test.rb +10 -0
  72. data/test/jobs/trainmaster/sessions_cleanup_job_test.rb +9 -0
  73. data/test/mailers/previews/trainmaster/user_mailer_preview.rb +6 -0
  74. data/test/mailers/trainmaster/user_mailer_test.rb +9 -0
  75. data/test/models/trainmaster/session_test.rb +26 -0
  76. data/test/models/trainmaster/user_test.rb +52 -0
  77. data/test/test_helper.rb +33 -0
  78. data/test/trainmaster.rb +12 -0
  79. metadata +327 -0
@@ -0,0 +1,275 @@
1
+ require 'test_helper'
2
+
3
+ module Trainmaster
4
+ class SessionsControllerTest < ActionController::TestCase
5
+ setup do
6
+ Rails.cache.clear # always clear cache first
7
+ @routes = Engine.routes
8
+ @session = trainmaster_sessions(:one)
9
+ @token = @session.token
10
+ @api_key = trainmaster_users(:one).api_key
11
+ end
12
+
13
+ test "public can see options" do
14
+ get :options
15
+ assert_response :success
16
+ end
17
+
18
+ test "user cannot list sessions with invalid token" do
19
+ get :index, params: { token: "invalidtoken" }
20
+ assert_response 401
21
+ end
22
+
23
+ test "user can list all his sessions" do
24
+ get :index, params: { token: @token }
25
+ assert_response :success
26
+ sessions = assigns(:sessions)
27
+ assert_not_nil sessions
28
+ all_his_sessions = Session.where(user: @session.user)
29
+ assert_equal sessions.length, all_his_sessions.length
30
+ sessions.each do |session|
31
+ assert session.user == @session.user
32
+ end
33
+ end
34
+
35
+ test "user can list all his sessions with api key" do
36
+ get :index, params: { api_key: @api_key }
37
+ assert_response :success
38
+ sessions = assigns(:sessions)
39
+ assert_not_nil sessions
40
+ all_his_sessions = Session.where(user: @session.user)
41
+ assert_equal sessions.length, all_his_sessions.length
42
+ sessions.each do |session|
43
+ assert session.user == @session.user
44
+ end
45
+ end
46
+
47
+ test "user can list all his sessions using user id in routing" do
48
+ get :index, params: { user_id: @session.user.uuid, token: @token }
49
+ assert_response :success
50
+ sessions = assigns(:sessions)
51
+ assert_not_nil sessions
52
+ all_his_sessions = Session.where(user: @session.user)
53
+ assert_equal sessions.length, all_his_sessions.length
54
+ sessions.each do |session|
55
+ assert session.user == @session.user
56
+ end
57
+ end
58
+
59
+ test "user cannot list expired session" do
60
+ session = Session.new(user: @session.user, seconds: -1)
61
+ session.save()
62
+ get :index, params: { user_id: session.user.uuid, token: @token }
63
+ assert_response :success
64
+ json = JSON.parse(@response.body)
65
+ assert_equal 1, json.length
66
+ end
67
+
68
+ test "user cannot list other's sessions" do
69
+ get :index, params: { user_id: trainmaster_users(:two), token: @token }
70
+ assert_response 401
71
+ end
72
+
73
+ test "user cannot list other's sessions with api key" do
74
+ get :index, params: { user_id: trainmaster_users(:two), api_key: @api_key }
75
+ assert_response 401
76
+ end
77
+
78
+ test "public cannot list sessions" do
79
+ get :index
80
+ assert_response 401
81
+ end
82
+
83
+ test "create a session" do
84
+ user = trainmaster_users(:one)
85
+ post :create, params: { username: user.username, password: "password" }
86
+ assert_response :success
87
+ session = assigns(:session)
88
+ assert_not_nil session
89
+ json = JSON.parse(@response.body)
90
+ assert json.has_key?("token")
91
+ assert !json.has_key?("secret")
92
+ end
93
+
94
+ test "cannot create a session if not verified" do
95
+ user = trainmaster_users(:one)
96
+ user.verified = false
97
+ user.save()
98
+ post :create, params: { username: user.username, password: "password" }
99
+ assert_response 401
100
+ end
101
+
102
+ test "cannot create a session with non-existent username" do
103
+ post :create, params: { username: 'idontexist', password: "secret" }
104
+ assert_response 401
105
+ json = JSON.parse(@response.body)
106
+ assert json["errors"].length == 1
107
+ end
108
+
109
+ test "cannot create a session without username" do
110
+ post :create, params: { password: "secret" }
111
+ assert_response 401
112
+ json = JSON.parse(@response.body)
113
+ assert json["errors"].length == 1
114
+ end
115
+
116
+ test "cannot create a session without a password" do
117
+ post :create, params: { username: trainmaster_users(:one).username }
118
+ assert_response 401
119
+ json = JSON.parse(@response.body)
120
+ assert json["errors"].length == 1
121
+ end
122
+
123
+ test "cannot create a session with a wrong password" do
124
+ post :create, params: { username: trainmaster_users(:one).username, password: "notsecret" }
125
+ assert_response 401
126
+ json = JSON.parse(@response.body)
127
+ assert json["errors"].length == 1
128
+ end
129
+
130
+ test "user can create session using existing auth" do
131
+ post :create, params: { token: @token }
132
+ assert_response 201
133
+ end
134
+
135
+ test "user can create session using oauth" do
136
+ auth_hash = OmniAuth::AuthHash.new()
137
+ auth_hash.provider = "someauthprovider"
138
+ auth_hash.uid = "someuniqueid"
139
+ auth_hash.info = OmniAuth::AuthHash::InfoHash.new()
140
+ auth_hash.info.name = "someusername"
141
+ Credentials = Struct.new("Credentials", :token, :expires_at)
142
+ auth_hash.credentials = Credentials.new("sometoken", Time.now.to_i)
143
+ @request.env["omniauth.auth"] = auth_hash
144
+ post :create
145
+ assert_response 302
146
+ user = User.find_by_oauth_provider_and_oauth_uid("someauthprovider", "someuniqueid")
147
+ session = Session.find_by_user_uuid(user.uuid)
148
+ assert_includes @response.location, session.token
149
+ end
150
+
151
+ test "user can show session" do
152
+ get :show, params: { id: 1, token: @token }
153
+ assert_response 200
154
+ json = JSON.parse(@response.body)
155
+ assert_equal @token, json["token"]
156
+ # Do a quick cache check
157
+ session = Cache.get(kind: :session, token: json["token"])
158
+ assert_not_nil session
159
+ assert_equal @token, session.token
160
+ end
161
+
162
+ test "user can show session using api key" do
163
+ get :show, params: { id: 1, api_key: @api_key }
164
+ assert_response 200
165
+ json = JSON.parse(@response.body)
166
+ assert_equal @token, json["token"]
167
+ end
168
+
169
+ test "user can show current session" do
170
+ get :show, params: { id: "current", token: @token }
171
+ assert_response 200
172
+ json = JSON.parse(@response.body)
173
+ assert_equal @token, json["token"]
174
+ end
175
+
176
+ test "user cannot show current session with api key" do
177
+ get :show, params: { id: "current", api_key: @api_key }
178
+ assert_response 404
179
+ end
180
+
181
+ test "user cannot show other's session" do
182
+ get :show, params: { id: 2, token: @token }
183
+ assert_response 401
184
+ end
185
+
186
+ test "user cannot show other's session with api key" do
187
+ get :show, params: { id: 2, api_key: @api_key }
188
+ assert_response 401
189
+ end
190
+
191
+ test "user cannot show expired session" do
192
+ session = Session.new(user: @session.user, seconds: -1)
193
+ session.save()
194
+ get :show, params: { id: session.uuid, token: @token }
195
+ assert_response 404
196
+ end
197
+
198
+ test "user cannot show expired session with api key" do
199
+ session = Session.new(user: @session.user, seconds: -1)
200
+ session.save()
201
+ get :show, params: { id: session.uuid, api_key: @api_key }
202
+ assert_response 404
203
+ end
204
+
205
+ test "public cannot show session" do
206
+ get :show, params: { id:1 }
207
+ assert_response 401
208
+ end
209
+
210
+ test "admin can show other's session" do
211
+ @session = trainmaster_sessions(:admin_one)
212
+ @token = @session.token
213
+ get :show, params: { id: 1, token: @token }
214
+ assert_response :success
215
+ json = JSON.parse(@response.body)
216
+ session = trainmaster_sessions(:one)
217
+ assert_equal session.token, json["token"]
218
+ end
219
+
220
+ test "admin can show other's session with api key" do
221
+ @session = trainmaster_sessions(:admin_one)
222
+ @token = @session.token
223
+ get :show, params: { id: 1, api_key: @api_key }
224
+ assert_response :success
225
+ json = JSON.parse(@response.body)
226
+ session = trainmaster_sessions(:one)
227
+ assert_equal session.token, json["token"]
228
+ end
229
+
230
+ test "user cannot show nonexisting session" do
231
+ get :show, params: { id: 999, token: @token }
232
+ assert_response 404
233
+ json = JSON.parse(@response.body)
234
+ assert json["errors"].length == 1
235
+ end
236
+
237
+ test "user can delete session" do
238
+ delete :destroy, params: { id: 1, token: @token }
239
+ assert_response 204
240
+ end
241
+
242
+ test "user can delete session with api key" do
243
+ delete :destroy, params: { id: 1, api_key: @api_key }
244
+ assert_response 204
245
+ end
246
+
247
+ test "user can delete a current session" do
248
+ delete :destroy, params: { id: "current", token: @token }
249
+ assert_response 204
250
+ end
251
+
252
+ test "user cannot delete a current session with api key" do
253
+ delete :destroy, params: { id: "current", api_key: @api_key }
254
+ assert_response 404
255
+ end
256
+
257
+ test "user cannot delete a non-existent session" do
258
+ delete :destroy, params: { id: 999, token: @token }
259
+ assert_response 404
260
+ end
261
+
262
+ test "user cannot delete other's session" do
263
+ delete :destroy, params: { id: 2, token: @token }
264
+ assert_response 401
265
+ end
266
+
267
+ test "admin can delete other's session" do
268
+ @session = trainmaster_sessions(:admin_one)
269
+ @token = @session.token
270
+ delete :destroy, params: { id: 1, token: @token }
271
+ assert_response :success
272
+ end
273
+
274
+ end
275
+ end
@@ -0,0 +1,335 @@
1
+ require 'json'
2
+ require 'test_helper'
3
+
4
+ module Trainmaster
5
+ class UsersControllerTest < ActionController::TestCase
6
+
7
+ setup do
8
+ Rails.cache.clear
9
+ @routes = Engine.routes
10
+ @session = trainmaster_sessions(:one)
11
+ @token = @session.token
12
+ @api_key = trainmaster_users(:one).api_key
13
+ end
14
+
15
+ test "public can see options" do
16
+ @request.headers["Access-Control-Request-Headers"] = "GET"
17
+ get :options
18
+ assert_response :success
19
+ assert_equal "GET", @response.headers["Access-Control-Allow-Headers"]
20
+ end
21
+
22
+ test "admin can list all users" do
23
+ @session = trainmaster_sessions(:admin_one)
24
+ @token = @session.token
25
+ get :index, params: { token: @token }
26
+ assert_response :success
27
+ users = assigns(:users)
28
+ assert_not_nil users
29
+ assert_equal Session.count, users.length
30
+ end
31
+
32
+ test "non-admin cannot list users" do
33
+ get :index, params: { token: @token }
34
+ assert_response 401
35
+ end
36
+
37
+ test "create a user" do
38
+ post :create, params: {
39
+ username: "foo@example.com", password: "secret",
40
+ password_confirmation: "secret"
41
+ }
42
+ assert_response :success
43
+ user = assigns(:user)
44
+ assert_not_nil user
45
+ assert user.username = "foo@example.com"
46
+ json = JSON.parse(@response.body)
47
+ assert_equal "foo@example.com", json["username"]
48
+ assert_not json.has_key?("password_digest")
49
+ end
50
+
51
+ test "user can create another user" do
52
+ post :create, params: {
53
+ username: "foo@example.com", password: "secret",
54
+ password_confirmation: "secret", token: @token
55
+ }
56
+ assert_response :success
57
+ end
58
+
59
+ test "user can create another user with api key" do
60
+ post :create, params: {
61
+ username: "foo@example.com", password: "secret",
62
+ password_confirmation: "secret", api_key: @api_key
63
+ }
64
+ assert_response :success
65
+ end
66
+
67
+ test "user cannot create an admin user" do
68
+ post :create, params: {
69
+ username: "foo@example.com", password: "secret",
70
+ password_confirmation: "secret", role: Roles::ADMIN
71
+ }
72
+ assert_response :success
73
+ user = assigns(:user)
74
+ assert_not_nil user
75
+ assert_equal Roles::USER, user.role
76
+ end
77
+
78
+ test "admin can create an admin user" do
79
+ @session = trainmaster_sessions(:admin_one)
80
+ @token = @session.token
81
+ post :create, params: {
82
+ username: "foo@example.com", password: "secret",
83
+ password_confirmation: "secret", role: Roles::ADMIN, token: @token
84
+ }
85
+ assert_response :success
86
+ user = assigns(:user)
87
+ assert_not_nil user
88
+ assert_equal Roles::ADMIN, user.role
89
+ end
90
+
91
+ test "cannot create a user without username" do
92
+ post :create, params: {
93
+ password: "secret",
94
+ password_confirmation: "secret"
95
+ }
96
+ assert_response 400
97
+ json = JSON.parse(@response.body)
98
+ assert 0 < json["errors"].length
99
+ end
100
+
101
+ test "cannot create a user without a password" do
102
+ post :create, params: { username: "foo@example.com" }
103
+ assert_response 400
104
+ json = JSON.parse(@response.body)
105
+ assert_equal 1, json["errors"].length
106
+ end
107
+
108
+ test "show a user" do
109
+ get :show, params: { id: 1, token: @token }
110
+ assert_response 200
111
+ json = JSON.parse(@response.body)
112
+ assert_equal trainmaster_users(:one).username, json["username"]
113
+ end
114
+
115
+ test "show a current user" do
116
+ get :show, params: { id: "current", token: @token }
117
+ assert_response 200
118
+ json = JSON.parse(@response.body)
119
+ assert_equal trainmaster_users(:one).username, json["username"]
120
+ end
121
+
122
+ test "cannot show other user" do
123
+ get :show, params: { id: 2, token: @token }
124
+ assert_response 401
125
+ end
126
+
127
+ test "public cannot show a user" do
128
+ get :show, params: { id: 1 }
129
+ assert_response 401
130
+ end
131
+
132
+ test "admin can show other user" do
133
+ @session = trainmaster_sessions(:admin_one)
134
+ @token = @session.token
135
+ get :show, params: { id: 1, token: @token }
136
+ assert_response :success
137
+ end
138
+
139
+ test "cannot show a nonexisting user" do
140
+ get :show, params: { id: 999, token: @token }
141
+ assert_response 404
142
+ json = JSON.parse(@response.body)
143
+ assert_equal 1, json["errors"].length
144
+ end
145
+
146
+ test "cannot show using well-formed but non-existing token" do
147
+ iat = Time.now.to_i
148
+ payload = {
149
+ user_uuid: @session.user_uuid,
150
+ session_uuid: @session.uuid,
151
+ role: @session.user.role,
152
+ iat: iat,
153
+ exp: iat + 60
154
+ }
155
+ secret = UUIDTools::UUID.random_create
156
+ token = JWT.encode(payload, secret, 'HS256')
157
+ get :show, params: { id: 1, token: token }
158
+ assert_response 401
159
+ end
160
+
161
+ test "cannot show using ill-formed" do
162
+ iat = Time.now.to_i
163
+ payload = {
164
+ session_uuid: @session.uuid,
165
+ role: @session.user.role,
166
+ iat: iat,
167
+ exp: iat + 60
168
+ }
169
+ secret = UUIDTools::UUID.random_create
170
+ token = JWT.encode(payload, secret, 'HS256')
171
+ get :show, params: { id: 1, token: token }
172
+ assert_response 401
173
+ end
174
+
175
+ test "cannot show using well-formed but bogus payload" do
176
+ iat = Time.now.to_i
177
+ payload = {
178
+ user_uuid: @session.user_uuid,
179
+ session_uuid: "doesnotexist",
180
+ role: @session.user.role,
181
+ iat: iat,
182
+ exp: iat + 60
183
+ }
184
+ secret = UUIDTools::UUID.random_create
185
+ token = JWT.encode(payload, secret, 'HS256')
186
+ get :show, params: { id: 1, token: token }
187
+ assert_response 401
188
+ end
189
+
190
+ test "cannot show using no token payload" do
191
+ secret = UUIDTools::UUID.random_create
192
+ token = JWT.encode({}, secret, 'HS256')
193
+ get :show, params: { id: 1, token: token }
194
+ assert_response 401
195
+ end
196
+
197
+ test "update a user" do
198
+ user = trainmaster_users(:one)
199
+ old_password_digest = user.password_digest
200
+ patch :update, params: { id: 1, username: 'foo@example.com', token: @token }
201
+ assert_response 200
202
+ json = JSON.parse(@response.body)
203
+ assert_equal "foo@example.com", json["username"]
204
+ user = trainmaster_users(:one)
205
+ assert_equal old_password_digest, user.password_digest
206
+ end
207
+
208
+ test "update a user with a new password using old password" do
209
+ user = trainmaster_users(:one)
210
+ old_password_digest = user.password_digest
211
+ patch :update, params: {
212
+ id: 1, old_password: "password", password: "newpassword", password_confirmation: "newpassword" , token: @token
213
+ }
214
+ assert_response 200
215
+ user = User.find_by_uuid(user.uuid)
216
+ assert_not_equal old_password_digest, user.password_digest
217
+ end
218
+
219
+ test "cannot update password with a invalid token" do
220
+ patch :update, params: {
221
+ id: 1, old_password: "wrongpassword", password: "newpassword", password_confirmation: "newpassword" , token: @token
222
+ }
223
+ assert_response 401
224
+ end
225
+
226
+ test "update current user" do
227
+ patch :update, params: {
228
+ id: "current", username: 'foo@example.com', token: @token
229
+ }
230
+ assert_response 200
231
+ json = JSON.parse(@response.body)
232
+ assert_equal "foo@example.com", json["username"]
233
+ end
234
+
235
+ test "update (issue) a new reset token" do
236
+ patch :update, params: { id: "current", issue_reset_token: true, username: @session.user.username }
237
+ assert_response 204
238
+ user = User.find_by_uuid(trainmaster_users(:one))
239
+ new_reset_token = user.reset_token
240
+ assert_not_nil new_reset_token
241
+ patch :update, params: { id: 1, username: "foo@example.com", token: @token }
242
+ assert_response 200
243
+ json = JSON.parse(@response.body)
244
+ assert_equal "foo@example.com", json["username"]
245
+ end
246
+
247
+ test "cannot update (issue) a new reset token without username" do
248
+ patch :update, params: { id: "current", issue_reset_token: true }
249
+ assert_response 404
250
+ end
251
+
252
+ test "cannot update (issue) a new reset token with invalid username" do
253
+ patch :update, params: { id: "current", issue_reset_token: true, username: "doesnotexist@example.com" }
254
+ assert_response 404
255
+ end
256
+
257
+ test "update password using reset token" do
258
+ user = trainmaster_users(:one)
259
+ old_password_digest = user.password_digest
260
+ patch :update, params: { id: "current", issue_reset_token: true, username: @session.user.username }
261
+ user = User.find_by_uuid(user.uuid)
262
+ new_reset_token = user.reset_token
263
+ assert_not_nil new_reset_token
264
+
265
+ # use reset token to update password
266
+ patch :update, params: { id: 1, password: "newsecret", password_confirmation: "newsecret", token: new_reset_token }
267
+ assert_response 200
268
+
269
+ user = User.find_by_uuid(user.uuid)
270
+ assert_not_equal old_password_digest, user.password_digest
271
+ end
272
+
273
+ test "cannot update password with non-reset token" do
274
+ patch :update, params: { id: 1, password: "newsecret", password_confirmation: "newsecret", token: @token }
275
+ assert_response 401
276
+ end
277
+
278
+ test "update (reissue) a verification token" do
279
+ user = User.find_by_uuid(trainmaster_users(:one))
280
+ old_verification_token = user.verification_token
281
+ patch :update, params: { id: "current", issue_verification_token: true, username: @session.user.username }
282
+ assert_response 204
283
+ user = User.find_by_uuid(trainmaster_users(:one))
284
+ new_verification_token = user.verification_token
285
+ assert_not_equal old_verification_token, new_verification_token
286
+ patch :update, params: { id: "current", verified: true, token: new_verification_token }
287
+ assert_response 200
288
+ json = JSON.parse(@response.body)
289
+ assert_equal true, json["verified"]
290
+ end
291
+
292
+ test "cannot update (reissue) a verification reset token without username" do
293
+ patch :update, params: { id: "current", issue_verification_token: true }
294
+ assert_response 404
295
+ end
296
+
297
+ test "cannot update (reissue) a verification token with invalid username" do
298
+ patch :update, params: { id: "current", issue_verification_token: true, username: "doesnotexist@example.com" }
299
+ assert_response 404
300
+ end
301
+
302
+ test "cannot update invalid email" do
303
+ patch :update, params: { id: 1, username: 'foobar', token: @token }
304
+ assert_response 400
305
+ end
306
+
307
+ test "cannot update another user" do
308
+ patch :update, params: { id: 2, username: 'foo@example.com', token: @token }
309
+ assert_response 401
310
+ end
311
+
312
+ test "delete a user" do
313
+ delete :destroy, params: { id: 1, token: @token }
314
+ assert_response 204
315
+ end
316
+
317
+ test "delete current user" do
318
+ delete :destroy, params: { id: "current", token: @token }
319
+ assert_response 204
320
+ end
321
+
322
+ test "cannot delete another user" do
323
+ delete :destroy, params: { id: 2, token: @token }
324
+ assert_response 401
325
+ end
326
+
327
+ test "admin can delete other user" do
328
+ @session = trainmaster_sessions(:admin_one)
329
+ @token = @session.token
330
+ delete :destroy, params: { id: 1, token: @token }
331
+ assert_response :success
332
+ end
333
+
334
+ end
335
+ end