# typed: false
require "rails_helper"

RSpec.describe Domain::Post::E621Post, type: :model do
  describe "validations" do
    let(:post) { build(:domain_post_e621_post) }

    it "requires e621_id" do
      post.e621_id = nil
      expect(post).not_to be_valid
      expect(post.errors[:e621_id]).to include("can't be blank")
    end

    it "requires state" do
      post.state = nil
      expect(post).not_to be_valid
      expect(post.errors[:state]).to include("is not included in the list")
    end

    it "validates state inclusion" do
      %w[ok removed scan_error file_error].each do |state|
        post.state = state
        expect(post).to be_valid
      end
      post.state = "invalid_state"
      expect(post).not_to be_valid
      expect(post.errors[:state]).to include("is not included in the list")
    end

    it "validates rating inclusion" do
      %w[s q e].each do |rating|
        post.rating = rating
        expect(post).to be_valid
      end
      post.rating = "invalid_rating"
      expect(post).not_to be_valid
      expect(post.errors[:rating]).to include("is not included in the list")
    end
  end

  describe "initialization" do
    let(:post) { described_class.new }

    it "sets default values" do
      expect(post.state).to eq("ok")
      expect(post.flags_array).to eq([])
      expect(post.pools_array).to eq([])
      expect(post.sources_array).to eq([])
      expect(post.artists_array).to eq([])
    end
  end

  describe "attributes" do
    it "can be queried using generated scopes" do
      post1 = create(:domain_post_e621_post)
      post2 = create(:domain_post_e621_post, scan_error: "an error")
      post3 = create(:domain_post_e621_post, scan_error: nil)

      expect(described_class.where.not(scan_error: nil)).to match_array([post2])
      expect(described_class.where(scan_error: nil)).to match_array(
        [post1, post3],
      )

      post2.scan_error = nil
      post2.save!
      expect(described_class.where(scan_error: nil)).to match_array(
        [post1, post2, post3],
      )
    end

    it "can be counted with generated scopes" do
      create(:domain_post_e621_post)
      post2 = create(:domain_post_e621_post)
      create(:domain_post_e621_post, parent_post: post2)

      expect(described_class.where(parent_post_e621_id: nil).count).to eq(2)
      expect(described_class.where(parent_post: nil).count).to eq(2)
    end
  end

  describe "associations" do
    it "belongs to parent_e621" do
      parent = create(:domain_post_e621_post)
      post = create(:domain_post_e621_post)
      post.parent_post = parent
      post.save!

      expect(post.parent_post).to eq(parent)
    end

    it "has one file" do
      post = create(:domain_post_e621_post)
      file = create(:domain_post_file, post: post)
      post.reload
      expect(post.file).to eq(file)
    end

    it "belongs to last_index_page" do
      post = create(:domain_post_e621_post)
      log_entry = create(:http_log_entry)
      post.last_index_page = log_entry
      post.save!
      expect(post.last_index_page).to eq(log_entry)
    end

    it "has an uploader" do
      user = create(:domain_user_e621_user)
      post = create(:domain_post_e621_post, uploader_user: user)
      expect(post.uploader_user).to eq(user)
      expect(user.uploaded_posts).to eq([post])
    end
  end

  describe "#to_param" do
    let(:post) { build(:domain_post_e621_post, e621_id: 12_345) }

    it "returns nil when e621_id is not present" do
      post.e621_id = nil
      expect(post.to_param).to be_nil
    end

    it "returns formatted string when e621_id is present" do
      expect(post.to_param).to eq("e621@12345")
    end
  end
end
