require "rails_helper" 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(:ok) expect(json["code"]).to be_present expect(json["user"]["role"]).to eq("guest") end end describe "POST /users/code/renew" do it "returns 401 when not logged in" do sign_out post "/users/code/renew" expect(response).to have_http_status(:unauthorized) end end describe "PUT /users/:id" do let(:user) { create(:user, name: "old-name", role: "guest") } 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: " " } 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" } expect(response).to have_http_status(:created) expect(json["id"]).to eq(user.id) expect(json["name"]).to eq("new-name") user.reload expect(user.name).to eq("new-name") end end 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) end it "creates IpAddress and UserIp, and returns valid:true with user slice" do user = create(:user, inheritance_code: SecureRandom.uuid, role: "guest") # request.remote_ip を固定 allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return("203.0.113.10") 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) 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 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") post "/users/verify", params: { code: user.inheritance_code } expect(response).to have_http_status(:ok) expect { 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) end end 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 } 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") end end end