# frozen_string_literal: true

require 'test_helper'

module Upgrow
  class ActiveRecordSchemaTest < ActiveSupport::TestCase
    class UserRecord
      class << self
        def attribute_names
          ['id', 'email']
        end

        def reflections
          { 'article' => :reflection, 'tags' => :reflection }
        end
      end
    end

    setup do
      @original_schema = ModelSchema.new
      @schema = ActiveRecordSchema.new(
        'Upgrow::ActiveRecordSchemaTest::UserRecord', @original_schema
      )
    end

    test '#attribute defines the attribute in the original Schema' do
      @schema.attribute(:name)

      assert_equal [:name], @original_schema.attribute_names
    end

    test '#attribute_names returns the Active Record attribute names' do
      assert_equal [:id, :email], @schema.attribute_names
    end

    test '#attribute_names includes attributes from the original schema' do
      @original_schema.attribute(:phone)

      assert_equal [:id, :email, :phone], @schema.attribute_names
    end

    test '#attribute_names ignores duplicates from the original schema' do
      @original_schema.attribute(:email)
      @original_schema.attribute(:phone)

      assert_equal [:id, :email, :phone], @schema.attribute_names
    end

    test '#attribute_names raises a Name Error if the Record class is undefined' do
      schema = ActiveRecordSchema.new('NoRecord', Schema.new)

      error = assert_raises(NameError) do
        schema.attribute_names
      end

      assert_includes error.message, 'uninitialized constant NoRecord'
    end

    test '#association defines the association in the original Schema' do
      @schema.association(:user)

      assert_equal [:user], @original_schema.association_names
    end

    test '#association_names includes associations from the Active Record reflections' do
      assert_equal [:article, :tags], @schema.association_names
    end

    test '#association_names includes associations from the original schema' do
      @original_schema.association(:user)

      assert_equal [:article, :tags, :user], @schema.association_names
    end

    test '#association_names ignores duplicates from the original schema' do
      @original_schema.association(:article)
      @original_schema.association(:user)

      assert_equal [:article, :tags, :user], @schema.association_names
    end

    test '#association_names raises a Name Error if the Record class is undefined' do
      schema = ActiveRecordSchema.new('NoRecord', Schema.new)

      error = assert_raises(NameError) do
        schema.association_names
      end

      assert_includes error.message, 'uninitialized constant NoRecord'
    end
  end
end