Wednesday, July 15, 2026 3:57:05 AM
> log_spec.rb
# frozen_string_literal: true

require "timecop"

RSpec.describe ESM::Log do
  let!(:community) { create(:community) }
  let!(:server) { create(:server, :with_setting, community: community) }
  let!(:user) { create(:user) }

  describe "scopes" do
    describe ".expired" do
      it "returns logs with expires_at in the past" do
        expired_log = create(:log, server: server, user: user)
        expired_log.update_column(:expires_at, 2.days.ago)

        active_log = create(:log, server: server, user: user)

        expect(described_class.expired).to include(expired_log)
        expect(described_class.expired).not_to include(active_log)
      end
    end

    describe ".active" do
      it "returns logs with expires_at in the future" do
        active_log = create(:log, server: server, user: user)

        expired_log = create(:log, server: server, user: user)
        expired_log.update_column(:expires_at, 2.days.ago)

        expect(described_class.active).to include(active_log)
        expect(described_class.active).not_to include(expired_log)
      end
    end
  end

  describe "callbacks" do
    describe "before_create :generate_uuid" do
      it "generates a UUID public_id on create" do
        log = create(:log, server: server, user: user)

        expect(log.public_id).to be_present
        expect(log.public_id).to match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/)
      end

      it "always generates a new UUID (overwrites any provided value)" do
        # Note: The callback always regenerates the UUID - this is by design
        existing_id = SecureRandom.uuid
        log = create(:log, server: server, user: user, public_id: existing_id)

        expect(log.public_id).to be_present
        expect(log.public_id).not_to eq(existing_id)
      end
    end

    describe "before_create :set_expiration_date" do
      it "sets expires_at to 1 day from now" do
        Timecop.freeze do
          log = create(:log, server: server, user: user)
          expected = 1.day.from_now.utc

          expect(log.expires_at).to be_within(1.second).of(expected)
        end
      end
    end
  end

  describe "#link" do
    let(:log) { create(:log, server: server, user: user) }

    it "returns localhost URL in test environment" do
      link = log.link

      expect(link).to include("localhost:3000")
      expect(link).to include(community.public_id)
      expect(link).to include(log.public_id)
    end

    it "includes community public_id in path" do
      expect(log.link).to include("/communities/#{community.public_id}/")
    end

    it "includes log public_id in path" do
      expect(log.link).to include("/logs/#{log.public_id}")
    end

    it "memoizes the result" do
      first_call = log.link
      second_call = log.link

      expect(first_call.object_id).to eq(second_call.object_id)
    end
  end

  describe "associations" do
    it "belongs to a server" do
      log = create(:log, server: server, user: user)
      expect(log.server).to eq(server)
    end

    it "stores requestors_user_id as discord_id" do
      # Note: The user association uses discord_id as the foreign key value
      # but the association definition expects id lookup, so direct .user
      # access requires the consuming app to configure primary_key
      log = create(:log, server: server, user: user)
      expect(log.requestors_user_id).to eq(user.discord_id)
    end
  end
end
All opinions represented herein are my own
- © 2024 - 2026 itsthedevman
- build 43aa0d7