require "spec_helper"

describe 'HyperMapper::Persistence' do

  before do
    @client = stub_client
  end

  describe "save" do
    
    it "should send all the attributes on fresh object" do
      stub_put 'users', 'goggin', {email: 'matt@example.com'}
      user = User.new username: 'goggin', email: 'matt@example.com'
      user.save
    end

    it "should only save the changed attributes on an already persisted object" do
      stub_get 'users', 'goggin', {username: 'goggin', email: 'matt@example.com'}
      user = User.find('goggin')
      user.email = 'george@example.com'
      stub_put 'users', 'goggin', {email: 'george@example.com'}
      user.save
      user.email.should == 'george@example.com'
    end

    describe "with autogenerated keys" do
      
      before :all do
        class TestClass 
          include HyperMapper::Document
          attr_accessible :testKey, :test
          key :testKey, autogenerate: true
          attribute :test
        end
      end
      
      after :all do
        Object.send(:remove_const, :TestClass)
      end

      it "should allow you to set the key yourself" do
        instance = TestClass.new testKey: 1, test: "hello"
        stub_put 'test_classes', 1, {test: 'hello'}
        instance.save 
      end

      it "should provide an autogenerated key if you omit the key" do
        instance = TestClass.new test: "hello"
        @client.should_receive(:put) do |arg1, arg2, arg3|
          arg1.should == 'test_classes'
          arg2.length.should == 47
          arg3.should == {test: 'hello'}
        end
        instance.save
      end
      
      it "should not try to create a new key for an instance loaded via find" do
        stub_get 'test_classes', 'a_valid_id', {test: 'hello'}
        instance = TestClass.find('a_valid_id')
        instance.test = 'goodbye'
        stub_put 'test_classes', 'a_valid_id', {test: 'goodbye'}
        instance.save
      end
    end
  end

  describe "persisted?" do
    
    before do
      @user = User.new username: 'goggin', email: 'matt@example.com'
    end

    it "should return false for a new object" do
      @user.should_not be_persisted
    end

    it "should return false after a failed save attempt" do
      @user.should_not be_persisted
    end

    it "should return true after being saved successfully" do
      stub_put 'users', 'goggin', {email: 'matt@example.com'}
      @user.save
      @user.should be_persisted
    end

    it "should return true after being loaded" do
      stub_get 'users', 'goggin', {email: 'matt@example.com'}
      (User.find 'goggin').should be_persisted
    end
  end
end
