ぼざクリタグ広場 https://hub.nizika.monster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

267 lines
7.5 KiB

  1. require 'rails_helper'
  2. RSpec.describe 'Users', type: :request do
  3. let(:remote_ip) { '203.0.113.10' }
  4. before do
  5. allow_any_instance_of(ActionDispatch::Request)
  6. .to receive(:remote_ip)
  7. .and_return(remote_ip)
  8. end
  9. def auth_headers(user)
  10. { 'X-Transfer-Code' => user.inheritance_code }
  11. end
  12. describe 'POST /users' do
  13. it 'creates guest user, IpAddress and UserIp, and returns code' do
  14. expect {
  15. post '/users'
  16. }.to change(User, :count).by(1)
  17. .and change(IpAddress, :count).by(1)
  18. .and change(UserIp, :count).by(1)
  19. expect(response).to have_http_status(:created)
  20. expect(json['code']).to be_present
  21. expect(json['user']['role']).to eq('guest')
  22. user = User.last
  23. ip_address = IpAddress.find_by(ip_address: IPAddr.new(remote_ip).hton)
  24. expect(user.role).to eq('guest')
  25. expect(ip_address).to be_present
  26. expect(UserIp.exists?(user:, ip_address:)).to eq(true)
  27. end
  28. it 'returns 403 and does not create user when current IP address is banned' do
  29. IpAddress.create!(
  30. ip_address: IPAddr.new(remote_ip).hton,
  31. banned_at: Time.current
  32. )
  33. expect {
  34. post '/users'
  35. }.not_to change(User, :count)
  36. expect(response).to have_http_status(:forbidden)
  37. expect(UserIp.count).to eq(0)
  38. end
  39. end
  40. describe 'POST /users/code/renew' do
  41. it 'returns 401 when not logged in' do
  42. post '/users/code/renew'
  43. expect(response).to have_http_status(:unauthorized)
  44. end
  45. it 'returns 403 when current user is banned' do
  46. user = create(:user, :banned)
  47. post '/users/code/renew', headers: auth_headers(user)
  48. expect(response).to have_http_status(:forbidden)
  49. end
  50. it 'returns 403 when current IP address is banned' do
  51. user = create(:user)
  52. IpAddress.create!(
  53. ip_address: IPAddr.new(remote_ip).hton,
  54. banned_at: Time.current
  55. )
  56. post '/users/code/renew', headers: auth_headers(user)
  57. expect(response).to have_http_status(:forbidden)
  58. end
  59. end
  60. describe 'PUT /users/:id' do
  61. let(:user) { create(:user, name: 'old-name', role: 'guest') }
  62. it 'returns 401 when current_user id mismatch' do
  63. other_user = create(:user)
  64. put "/users/#{user.id}",
  65. params: { name: 'new-name' },
  66. headers: auth_headers(other_user)
  67. expect(response).to have_http_status(:unauthorized)
  68. end
  69. it 'returns 400 when name is blank' do
  70. put "/users/#{user.id}",
  71. params: { name: ' ' },
  72. headers: auth_headers(user)
  73. expect(response).to have_http_status(:bad_request)
  74. end
  75. it 'updates name and returns user slice' do
  76. put "/users/#{user.id}",
  77. params: { name: 'new-name' },
  78. headers: auth_headers(user)
  79. expect(response).to have_http_status(:ok)
  80. expect(json['id']).to eq(user.id)
  81. expect(json['name']).to eq('new-name')
  82. user.reload
  83. expect(user.name).to eq('new-name')
  84. end
  85. it 'returns 403 when current user is banned' do
  86. user.update!(banned_at: Time.current)
  87. put "/users/#{user.id}",
  88. params: { name: 'new-name' },
  89. headers: auth_headers(user)
  90. expect(response).to have_http_status(:forbidden)
  91. user.reload
  92. expect(user.name).to eq('old-name')
  93. end
  94. it 'returns 403 when current IP address is banned' do
  95. IpAddress.create!(
  96. ip_address: IPAddr.new(remote_ip).hton,
  97. banned_at: Time.current
  98. )
  99. put "/users/#{user.id}",
  100. params: { name: 'new-name' },
  101. headers: auth_headers(user)
  102. expect(response).to have_http_status(:forbidden)
  103. user.reload
  104. expect(user.name).to eq('old-name')
  105. end
  106. end
  107. describe 'POST /users/verify' do
  108. it 'returns valid:false when code not found' do
  109. post '/users/verify', params: { code: 'nope' }
  110. expect(response).to have_http_status(:ok)
  111. expect(json['valid']).to eq(false)
  112. end
  113. it 'returns 403 when current IP address is banned' do
  114. user = create(:user, inheritance_code: SecureRandom.uuid, role: 'guest')
  115. IpAddress.create!(
  116. ip_address: IPAddr.new(remote_ip).hton,
  117. banned_at: Time.current
  118. )
  119. expect {
  120. post '/users/verify', params: { code: user.inheritance_code }
  121. }.not_to change(UserIp, :count)
  122. expect(response).to have_http_status(:forbidden)
  123. end
  124. it 'returns 403 when verified user is banned' do
  125. user = create(
  126. :user,
  127. :banned,
  128. inheritance_code: SecureRandom.uuid,
  129. role: 'guest'
  130. )
  131. expect {
  132. post '/users/verify', params: { code: user.inheritance_code }
  133. }.not_to change(UserIp, :count)
  134. expect(response).to have_http_status(:forbidden)
  135. end
  136. it 'creates IpAddress and UserIp, and returns valid:true with user slice' do
  137. user = create(:user, inheritance_code: SecureRandom.uuid, role: 'guest')
  138. expect {
  139. post '/users/verify', params: { code: user.inheritance_code }
  140. }.to change(UserIp, :count).by(1)
  141. .and change(IpAddress, :count).by(1)
  142. expect(response).to have_http_status(:ok)
  143. expect(json['valid']).to eq(true)
  144. expect(json['user']['id']).to eq(user.id)
  145. expect(json['user']['inheritance_code']).to eq(user.inheritance_code)
  146. expect(json['user']['role']).to eq('guest')
  147. ip_address = IpAddress.find_by(ip_address: IPAddr.new(remote_ip).hton)
  148. expect(ip_address).to be_present
  149. expect(UserIp.exists?(user:, ip_address:)).to eq(true)
  150. end
  151. it 'is idempotent for same user and same IP address' do
  152. user = create(:user, inheritance_code: SecureRandom.uuid, role: 'guest')
  153. post '/users/verify', params: { code: user.inheritance_code }
  154. expect(response).to have_http_status(:ok)
  155. expect {
  156. post '/users/verify', params: { code: user.inheritance_code }
  157. }.not_to change(UserIp, :count)
  158. expect(response).to have_http_status(:ok)
  159. expect(json['valid']).to eq(true)
  160. end
  161. it 'creates another UserIp for same user and different IP address' do
  162. user = create(:user, inheritance_code: SecureRandom.uuid, role: 'guest')
  163. post '/users/verify', params: { code: user.inheritance_code }
  164. expect(response).to have_http_status(:ok)
  165. allow_any_instance_of(ActionDispatch::Request)
  166. .to receive(:remote_ip)
  167. .and_return('203.0.113.11')
  168. expect {
  169. post '/users/verify', params: { code: user.inheritance_code }
  170. }.to change(UserIp, :count).by(1)
  171. expect(response).to have_http_status(:ok)
  172. expect(json['valid']).to eq(true)
  173. end
  174. end
  175. describe 'GET /users/me' do
  176. it 'returns 404 when code not found' do
  177. get '/users/me', params: { code: 'nope' }
  178. expect(response).to have_http_status(:not_found)
  179. end
  180. it 'returns user slice when found' do
  181. user = create(:user, inheritance_code: SecureRandom.uuid, name: 'me', role: 'guest')
  182. get '/users/me', params: { code: user.inheritance_code }
  183. expect(response).to have_http_status(:ok)
  184. expect(json['id']).to eq(user.id)
  185. expect(json['name']).to eq('me')
  186. expect(json['inheritance_code']).to eq(user.inheritance_code)
  187. expect(json['role']).to eq('guest')
  188. end
  189. it 'returns 403 when current IP address is banned' do
  190. user = create(:user, inheritance_code: SecureRandom.uuid)
  191. IpAddress.create!(
  192. ip_address: IPAddr.new(remote_ip).hton,
  193. banned_at: Time.current
  194. )
  195. get '/users/me', params: { code: user.inheritance_code }
  196. expect(response).to have_http_status(:forbidden)
  197. end
  198. end
  199. end