require 'rails_helper'

RSpec.describe VersionRecorder do
  let(:member) { create(:user, :member) }

  let(:post_record) do
    Post.create!(
        title: 'version recorder post',
        url: 'https://example.com/version-recorder-post')
  end

  it 'updates record version_no when creating the first version' do
    version =
        PostVersionRecorder.record!(
            post: post_record,
            event_type: :create,
            created_by_user: member)

    expect(version.version_no).to eq(1)
    expect(post_record.reload.version_no).to eq(1)
  end

  it 'updates record version_no when creating the next version' do
    PostVersionRecorder.record!(
        post: post_record,
        event_type: :create,
        created_by_user: member)

    post_record.update!(title: 'updated version recorder post')

    version =
        PostVersionRecorder.record!(
            post: post_record.reload,
            event_type: :update,
            created_by_user: member)

    expect(version.version_no).to eq(2)
    expect(post_record.reload.version_no).to eq(2)
  end

  it 'does not create a new version or advance version_no when snapshot is unchanged' do
    first =
        PostVersionRecorder.record!(
            post: post_record,
            event_type: :create,
            created_by_user: member)

    expect {
      version =
          PostVersionRecorder.record!(
              post: post_record.reload,
              event_type: :update,
              created_by_user: member)

      expect(version).to eq(first)
    }.not_to change(PostVersion, :count)

    expect(post_record.reload.version_no).to eq(1)
  end

  it 'raises when record version_no is older than the latest version' do
    PostVersionRecorder.record!(
        post: post_record,
        event_type: :create,
        created_by_user: member)

    post_record.update!(title: 'updated once')

    PostVersionRecorder.record!(
        post: post_record.reload,
        event_type: :update,
        created_by_user: member)

    post_record.update_columns(version_no: 1)

    post_record.update!(title: 'updated with stale version_no')

    expect {
      PostVersionRecorder.record!(
          post: post_record.reload,
          event_type: :update,
          created_by_user: member)
    }.to raise_error(RuntimeError, /version_no/)
  end
end
