require "rails_helper" RSpec.describe JwtService do describe ".encode" do it "returns a JWT string" do token = described_class.encode(user_id: 1) expect(token).to be_a(String) expect(token.split(".").size).to eq(3) end it "sets a default expiration about 7 days in the future" do token = described_class.encode(user_id: 1) payload = JWT.decode(token, described_class::SECRET_KEY, true, algorithm: described_class::ALGORITHM).first expect(payload["exp"]).to be_within(60).of(7.days.from_now.to_i) end it "keeps a custom expiration if provided" do custom_exp = 1.hour.from_now.to_i token = described_class.encode(user_id: 1, exp: custom_exp) payload = JWT.decode(token, described_class::SECRET_KEY, true, algorithm: described_class::ALGORITHM).first expect(payload["exp"]).to eq(custom_exp) end end describe ".decode" do it "round-trips the user_id" do token = described_class.encode(user_id: 42) expect(described_class.decode(token)[:user_id]).to eq(42) end it "returns nil for a tampered token" do token = described_class.encode(user_id: 42) expect(described_class.decode(token + "x")).to be_nil end it "returns nil for a token signed with a different secret" do token = JWT.encode({ user_id: 42 }, "wrong-secret", "HS256") expect(described_class.decode(token)).to be_nil end it "returns nil for an expired token" do token = described_class.encode(user_id: 42, exp: 1.minute.ago.to_i) expect(described_class.decode(token)).to be_nil end it "returns nil for garbage input" do expect(described_class.decode("not-a-token")).to be_nil end end end