|
|
|
@@ -1,109 +1,266 @@ |
|
|
|
require "rails_helper" |
|
|
|
require 'rails_helper' |
|
|
|
|
|
|
|
RSpec.describe 'Users', type: :request do |
|
|
|
let(:remote_ip) { '203.0.113.10' } |
|
|
|
|
|
|
|
before do |
|
|
|
allow_any_instance_of(ActionDispatch::Request) |
|
|
|
.to receive(:remote_ip) |
|
|
|
.and_return(remote_ip) |
|
|
|
end |
|
|
|
|
|
|
|
def auth_headers(user) |
|
|
|
{ 'X-Transfer-Code' => user.inheritance_code } |
|
|
|
end |
|
|
|
|
|
|
|
describe 'POST /users' do |
|
|
|
it 'creates guest user, IpAddress and UserIp, and returns code' do |
|
|
|
expect { |
|
|
|
post '/users' |
|
|
|
}.to change(User, :count).by(1) |
|
|
|
.and change(IpAddress, :count).by(1) |
|
|
|
.and change(UserIp, :count).by(1) |
|
|
|
|
|
|
|
RSpec.describe "Users", type: :request do |
|
|
|
describe "POST /users" do |
|
|
|
it "creates guest user and returns code" do |
|
|
|
post "/users" |
|
|
|
expect(response).to have_http_status(:created) |
|
|
|
expect(json["code"]).to be_present |
|
|
|
expect(json["user"]["role"]).to eq("guest") |
|
|
|
expect(json['code']).to be_present |
|
|
|
expect(json['user']['role']).to eq('guest') |
|
|
|
|
|
|
|
user = User.last |
|
|
|
ip_address = IpAddress.find_by(ip_address: IPAddr.new(remote_ip).hton) |
|
|
|
|
|
|
|
expect(user.role).to eq('guest') |
|
|
|
expect(ip_address).to be_present |
|
|
|
expect(UserIp.exists?(user:, ip_address:)).to eq(true) |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns 403 and does not create user when current IP address is banned' do |
|
|
|
IpAddress.create!( |
|
|
|
ip_address: IPAddr.new(remote_ip).hton, |
|
|
|
banned_at: Time.current |
|
|
|
) |
|
|
|
|
|
|
|
expect { |
|
|
|
post '/users' |
|
|
|
}.not_to change(User, :count) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden) |
|
|
|
expect(UserIp.count).to eq(0) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
describe "POST /users/code/renew" do |
|
|
|
it "returns 401 when not logged in" do |
|
|
|
sign_out |
|
|
|
post "/users/code/renew" |
|
|
|
describe 'POST /users/code/renew' do |
|
|
|
it 'returns 401 when not logged in' do |
|
|
|
post '/users/code/renew' |
|
|
|
|
|
|
|
expect(response).to have_http_status(:unauthorized) |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns 403 when current user is banned' do |
|
|
|
user = create(:user, :banned) |
|
|
|
|
|
|
|
post '/users/code/renew', headers: auth_headers(user) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden) |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns 403 when current IP address is banned' do |
|
|
|
user = create(:user) |
|
|
|
|
|
|
|
IpAddress.create!( |
|
|
|
ip_address: IPAddr.new(remote_ip).hton, |
|
|
|
banned_at: Time.current |
|
|
|
) |
|
|
|
|
|
|
|
post '/users/code/renew', headers: auth_headers(user) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
describe "PUT /users/:id" do |
|
|
|
let(:user) { create(:user, name: "old-name", role: "guest") } |
|
|
|
describe 'PUT /users/:id' do |
|
|
|
let(:user) { create(:user, name: 'old-name', role: 'guest') } |
|
|
|
|
|
|
|
it 'returns 401 when current_user id mismatch' do |
|
|
|
other_user = create(:user) |
|
|
|
|
|
|
|
put "/users/#{user.id}", |
|
|
|
params: { name: 'new-name' }, |
|
|
|
headers: auth_headers(other_user) |
|
|
|
|
|
|
|
it "returns 401 when current_user id mismatch" do |
|
|
|
sign_in_as(create(:user)) |
|
|
|
put "/users/#{user.id}", params: { name: "new-name" } |
|
|
|
expect(response).to have_http_status(:unauthorized) |
|
|
|
end |
|
|
|
|
|
|
|
it "returns 400 when name is blank" do |
|
|
|
sign_in_as(user) |
|
|
|
put "/users/#{user.id}", params: { name: " " } |
|
|
|
it 'returns 400 when name is blank' do |
|
|
|
put "/users/#{user.id}", |
|
|
|
params: { name: ' ' }, |
|
|
|
headers: auth_headers(user) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:bad_request) |
|
|
|
end |
|
|
|
|
|
|
|
it "updates name and returns 201 with user slice" do |
|
|
|
sign_in_as(user) |
|
|
|
put "/users/#{user.id}", params: { name: "new-name" } |
|
|
|
it 'updates name and returns user slice' do |
|
|
|
put "/users/#{user.id}", |
|
|
|
params: { name: 'new-name' }, |
|
|
|
headers: auth_headers(user) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
expect(json["id"]).to eq(user.id) |
|
|
|
expect(json["name"]).to eq("new-name") |
|
|
|
expect(json['id']).to eq(user.id) |
|
|
|
expect(json['name']).to eq('new-name') |
|
|
|
|
|
|
|
user.reload |
|
|
|
expect(user.name).to eq("new-name") |
|
|
|
expect(user.name).to eq('new-name') |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns 403 when current user is banned' do |
|
|
|
user.update!(banned_at: Time.current) |
|
|
|
|
|
|
|
put "/users/#{user.id}", |
|
|
|
params: { name: 'new-name' }, |
|
|
|
headers: auth_headers(user) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden) |
|
|
|
|
|
|
|
user.reload |
|
|
|
expect(user.name).to eq('old-name') |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns 403 when current IP address is banned' do |
|
|
|
IpAddress.create!( |
|
|
|
ip_address: IPAddr.new(remote_ip).hton, |
|
|
|
banned_at: Time.current |
|
|
|
) |
|
|
|
|
|
|
|
put "/users/#{user.id}", |
|
|
|
params: { name: 'new-name' }, |
|
|
|
headers: auth_headers(user) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden) |
|
|
|
|
|
|
|
user.reload |
|
|
|
expect(user.name).to eq('old-name') |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
describe "POST /users/verify" do |
|
|
|
it "returns valid:false when code not found" do |
|
|
|
post "/users/verify", params: { code: "nope" } |
|
|
|
describe 'POST /users/verify' do |
|
|
|
it 'returns valid:false when code not found' do |
|
|
|
post '/users/verify', params: { code: 'nope' } |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
expect(json["valid"]).to eq(false) |
|
|
|
expect(json['valid']).to eq(false) |
|
|
|
end |
|
|
|
|
|
|
|
it "creates IpAddress and UserIp, and returns valid:true with user slice" do |
|
|
|
user = create(:user, inheritance_code: SecureRandom.uuid, role: "guest") |
|
|
|
it 'returns 403 when current IP address is banned' do |
|
|
|
user = create(:user, inheritance_code: SecureRandom.uuid, role: 'guest') |
|
|
|
|
|
|
|
IpAddress.create!( |
|
|
|
ip_address: IPAddr.new(remote_ip).hton, |
|
|
|
banned_at: Time.current |
|
|
|
) |
|
|
|
|
|
|
|
expect { |
|
|
|
post '/users/verify', params: { code: user.inheritance_code } |
|
|
|
}.not_to change(UserIp, :count) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden) |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns 403 when verified user is banned' do |
|
|
|
user = create( |
|
|
|
:user, |
|
|
|
:banned, |
|
|
|
inheritance_code: SecureRandom.uuid, |
|
|
|
role: 'guest' |
|
|
|
) |
|
|
|
|
|
|
|
expect { |
|
|
|
post '/users/verify', params: { code: user.inheritance_code } |
|
|
|
}.not_to change(UserIp, :count) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden) |
|
|
|
end |
|
|
|
|
|
|
|
# request.remote_ip を固定 |
|
|
|
allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return("203.0.113.10") |
|
|
|
it 'creates IpAddress and UserIp, and returns valid:true with user slice' do |
|
|
|
user = create(:user, inheritance_code: SecureRandom.uuid, role: 'guest') |
|
|
|
|
|
|
|
expect { |
|
|
|
post "/users/verify", params: { code: user.inheritance_code } |
|
|
|
post '/users/verify', params: { code: user.inheritance_code } |
|
|
|
}.to change(UserIp, :count).by(1) |
|
|
|
.and change(IpAddress, :count).by(1) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
expect(json["valid"]).to eq(true) |
|
|
|
expect(json["user"]["id"]).to eq(user.id) |
|
|
|
expect(json["user"]["inheritance_code"]).to eq(user.inheritance_code) |
|
|
|
expect(json["user"]["role"]).to eq("guest") |
|
|
|
expect(json['valid']).to eq(true) |
|
|
|
expect(json['user']['id']).to eq(user.id) |
|
|
|
expect(json['user']['inheritance_code']).to eq(user.inheritance_code) |
|
|
|
expect(json['user']['role']).to eq('guest') |
|
|
|
|
|
|
|
# ついでに IpAddress もできてることを確認(ipの保存形式がバイナリでも count で見れる) |
|
|
|
expect(IpAddress.count).to be >= 1 |
|
|
|
ip_address = IpAddress.find_by(ip_address: IPAddr.new(remote_ip).hton) |
|
|
|
expect(ip_address).to be_present |
|
|
|
expect(UserIp.exists?(user:, ip_address:)).to eq(true) |
|
|
|
end |
|
|
|
|
|
|
|
it "is idempotent for same user+ip (does not create duplicate UserIp)" do |
|
|
|
user = create(:user, inheritance_code: SecureRandom.uuid, role: "guest") |
|
|
|
allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return("203.0.113.10") |
|
|
|
it 'is idempotent for same user and same IP address' do |
|
|
|
user = create(:user, inheritance_code: SecureRandom.uuid, role: 'guest') |
|
|
|
|
|
|
|
post "/users/verify", params: { code: user.inheritance_code } |
|
|
|
post '/users/verify', params: { code: user.inheritance_code } |
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
|
|
|
|
expect { |
|
|
|
post "/users/verify", params: { code: user.inheritance_code } |
|
|
|
post '/users/verify', params: { code: user.inheritance_code } |
|
|
|
}.not_to change(UserIp, :count) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
expect(json["valid"]).to eq(true) |
|
|
|
expect(json['valid']).to eq(true) |
|
|
|
end |
|
|
|
|
|
|
|
it 'creates another UserIp for same user and different IP address' do |
|
|
|
user = create(:user, inheritance_code: SecureRandom.uuid, role: 'guest') |
|
|
|
|
|
|
|
post '/users/verify', params: { code: user.inheritance_code } |
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
|
|
|
|
allow_any_instance_of(ActionDispatch::Request) |
|
|
|
.to receive(:remote_ip) |
|
|
|
.and_return('203.0.113.11') |
|
|
|
|
|
|
|
expect { |
|
|
|
post '/users/verify', params: { code: user.inheritance_code } |
|
|
|
}.to change(UserIp, :count).by(1) |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
expect(json['valid']).to eq(true) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
describe "GET /users/me" do |
|
|
|
it "returns 404 when code not found" do |
|
|
|
get "/users/me", params: { code: "nope" } |
|
|
|
describe 'GET /users/me' do |
|
|
|
it 'returns 404 when code not found' do |
|
|
|
get '/users/me', params: { code: 'nope' } |
|
|
|
|
|
|
|
expect(response).to have_http_status(:not_found) |
|
|
|
end |
|
|
|
|
|
|
|
it "returns user slice when found" do |
|
|
|
user = create(:user, inheritance_code: SecureRandom.uuid, name: "me", role: "guest") |
|
|
|
get "/users/me", params: { code: user.inheritance_code } |
|
|
|
it 'returns user slice when found' do |
|
|
|
user = create(:user, inheritance_code: SecureRandom.uuid, name: 'me', role: 'guest') |
|
|
|
|
|
|
|
get '/users/me', params: { code: user.inheritance_code } |
|
|
|
|
|
|
|
expect(response).to have_http_status(:ok) |
|
|
|
expect(json["id"]).to eq(user.id) |
|
|
|
expect(json["name"]).to eq("me") |
|
|
|
expect(json["inheritance_code"]).to eq(user.inheritance_code) |
|
|
|
expect(json["role"]).to eq("guest") |
|
|
|
expect(json['id']).to eq(user.id) |
|
|
|
expect(json['name']).to eq('me') |
|
|
|
expect(json['inheritance_code']).to eq(user.inheritance_code) |
|
|
|
expect(json['role']).to eq('guest') |
|
|
|
end |
|
|
|
|
|
|
|
it 'returns 403 when current IP address is banned' do |
|
|
|
user = create(:user, inheritance_code: SecureRandom.uuid) |
|
|
|
|
|
|
|
IpAddress.create!( |
|
|
|
ip_address: IPAddr.new(remote_ip).hton, |
|
|
|
banned_at: Time.current |
|
|
|
) |
|
|
|
|
|
|
|
get '/users/me', params: { code: user.inheritance_code } |
|
|
|
|
|
|
|
expect(response).to have_http_status(:forbidden) |
|
|
|
end |
|
|
|
end |
|
|
|
end |