<commit_before>require "spec_helper"
require "heroku/command/pgbackups"

module Heroku::Command
  describe Pgbackups do
    before do
      @pgbackups = prepare_command(Pgbackups)
      @pgbackups.stub!(:config_vars).and_return({
        "PGBACKUPS_URL" => "https://ip:password@pgbackups.heroku.com/client"
      })
      @pgbackups.heroku.stub!(:info).and_return({})
    end

    it "requests a pgbackups transfer list for the index command" do
      fake_client = mock("pgbackups_client")
      fake_client.should_receive(:get_transfers).and_return([])
      @pgbackups.stub!(:no_backups_error!)
      @pgbackups.should_receive(:pgbackup_client).with.and_return(fake_client)

      @pgbackups.index
    end

    describe "single backup" do
      it "gets the url for the latest backup if nothing is specified" do
        latest_backup_url= "http://latest/backup.dump"
        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:get_latest_backup).and_return({'public_url' => latest_backup_url })
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client)
        @pgbackups.should_receive(:display).with('"'+latest_backup_url+'"')

        old_stdout_isatty = STDOUT.isatty
        STDOUT.stub!(:isatty).and_return(true)
        @pgbackups.url
        STDOUT.stub!(:isatty).and_return(old_stdout_isatty)
      end

      it "gets the url for the named backup if a name is specified" do
        backup_name = "b001"
        named_url = "http://latest/backup.dump"
        @pgbackups.stub!(:args).and_return([backup_name])

        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:get_backup).with(backup_name).and_return({'public_url' => named_url })
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client)

        @pgbackups.should_receive(:display).with('"'+named_url+'"')

        old_stdout_isatty = STDOUT.isatty
        STDOUT.stub!(:isatty).and_return(true)
        @pgbackups.url
        STDOUT.stub!(:isatty).and_return(old_stdout_isatty)
      end

      it "should capture a backup when requested" do
        from_url = "postgres://from/bar"
        from_name = "FROM_NAME"
        backup_obj = {'to_url' => "s3://bucket/userid/b001.dump"}

        @pgbackups.stub!(:resolve_db).and_return( {:url => from_url, :name => from_name} )
        @pgbackups.stub!(:poll_transfer!).with(backup_obj).and_return(backup_obj)

        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:create_transfer).with(from_url, from_name, nil, "BACKUP", {:expire => nil}).and_return(backup_obj)
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client)

        @pgbackups.capture
      end

      it "should send expiration flag to client if specified on args" do
        from_url = "postgres://from/bar"
        from_name = "FROM_NAME"
        backup_obj = {'to_url' => "s3://bucket/userid/b001.dump"}

        @pgbackups.stub!(:resolve_db).and_return( {:url => from_url, :name => from_name} )
        @pgbackups.stub!(:poll_transfer!).with(backup_obj).and_return(backup_obj)
        @pgbackups.stub!(:options).and_return(:expire => true)

        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:create_transfer).with(from_url, from_name, nil, "BACKUP", {:expire => true}).and_return(backup_obj)
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client)

        @pgbackups.capture
      end

      it "destroys no backup without a name" do
        @pgbackups.stub!(:args).and_return([])

        fake_client = mock("pgbackups_client")
        fake_client.should_not_receive(:delete_backup)
        @pgbackups.should_not_receive(:pgbackup_client).and_return(fake_client)

        @pgbackups.stub!(:abort).and_raise(SystemExit)

        lambda { @pgbackups.destroy }.should raise_error SystemExit
      end

      it "destroys a backup on request if confirmed" do
        name = "b001"
        @pgbackups.stub!(:args).and_return([name])

        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:get_backup).with(name).and_return({})
        fake_client.should_receive(:delete_backup).with(name).and_return({})
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client, fake_client)

        @pgbackups.destroy
      end

      it "aborts if no database addon is present" do
        STDERR.should_receive(:puts).with(" !    Your app has no databases.")
        lambda { @pgbackups.capture }.should raise_error SystemExit
      end

      context "on errors" do
        def stub_failed_capture(log)
          backup_obj = {
            "error_at" => Time.now.to_s,
            "log" => log,
            'to_url' => 'postgres://from/bar'
          }
          @pgbackups.stub!(:transfer!).and_return(backup_obj)
          @pgbackups.stub!(:poll_transfer!).with(backup_obj).and_return(backup_obj)
        end

        before(:each) do
          @pgbackups.stub!(:resolve_db).and_return({})
        end

        it 'aborts on a generic error' do
          stub_failed_capture "something generic"
          @pgbackups.should_receive(:error).with("An error occurred and your backup did not finish.")
          @pgbackups.capture
        end

        it 'aborts and informs when the database isnt up yet' do
          stub_failed_capture 'could not translate host name "ec2-42-42-42-42.compute-1.amazonaws.com" to address: Name or service not known'<commit_msg>fix specs which was intermitently writing 'failed' to STDOUT<commit_after>require "spec_helper"
require "heroku/command/pgbackups"

module Heroku::Command
  describe Pgbackups do
    before do
      @pgbackups = prepare_command(Pgbackups)
      @pgbackups.stub!(:config_vars).and_return({
        "PGBACKUPS_URL" => "https://ip:password@pgbackups.heroku.com/client"
      })
      @pgbackups.heroku.stub!(:info).and_return({})
    end

    it "requests a pgbackups transfer list for the index command" do
      fake_client = mock("pgbackups_client")
      fake_client.should_receive(:get_transfers).and_return([])
      @pgbackups.stub!(:no_backups_error!)
      @pgbackups.should_receive(:pgbackup_client).with.and_return(fake_client)

      @pgbackups.index
    end

    describe "single backup" do
      it "gets the url for the latest backup if nothing is specified" do
        latest_backup_url= "http://latest/backup.dump"
        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:get_latest_backup).and_return({'public_url' => latest_backup_url })
        @pgbackups.stub!(:args).and_return([])
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client)
        @pgbackups.should_receive(:display).with('"'+latest_backup_url+'"')

        old_stdout_isatty = STDOUT.isatty
        STDOUT.stub!(:isatty).and_return(true)
        @pgbackups.url
        STDOUT.stub!(:isatty).and_return(old_stdout_isatty)
      end

      it "gets the url for the named backup if a name is specified" do
        backup_name = "b001"
        named_url = "http://latest/backup.dump"
        @pgbackups.stub!(:args).and_return([backup_name])

        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:get_backup).with(backup_name).and_return({'public_url' => named_url })
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client)

        @pgbackups.should_receive(:display).with('"'+named_url+'"')

        old_stdout_isatty = STDOUT.isatty
        STDOUT.stub!(:isatty).and_return(true)
        @pgbackups.url
        STDOUT.stub!(:isatty).and_return(old_stdout_isatty)
      end

      it "should capture a backup when requested" do
        from_url = "postgres://from/bar"
        from_name = "FROM_NAME"
        backup_obj = {'to_url' => "s3://bucket/userid/b001.dump"}

        @pgbackups.stub!(:args).and_return([])
        @pgbackups.stub!(:resolve_db).and_return( {:url => from_url, :name => from_name} )
        @pgbackups.stub!(:poll_transfer!).with(backup_obj).and_return(backup_obj)

        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:create_transfer).with(from_url, from_name, nil, "BACKUP", {:expire => nil}).and_return(backup_obj)
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client)

        @pgbackups.capture
      end

      it "should send expiration flag to client if specified on args" do
        from_url = "postgres://from/bar"
        from_name = "FROM_NAME"
        backup_obj = {'to_url' => "s3://bucket/userid/b001.dump"}

        @pgbackups.stub!(:resolve_db).and_return( {:url => from_url, :name => from_name} )
        @pgbackups.stub!(:poll_transfer!).with(backup_obj).and_return(backup_obj)
        @pgbackups.stub!(:options).and_return(:expire => true)

        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:create_transfer).with(from_url, from_name, nil, "BACKUP", {:expire => true}).and_return(backup_obj)
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client)

        @pgbackups.capture
      end

      it "destroys no backup without a name" do
        @pgbackups.stub!(:args).and_return([])

        fake_client = mock("pgbackups_client")
        fake_client.should_not_receive(:delete_backup)
        @pgbackups.should_not_receive(:pgbackup_client).and_return(fake_client)

        @pgbackups.stub!(:abort).and_raise(SystemExit)

        lambda { @pgbackups.destroy }.should raise_error SystemExit
      end

      it "destroys a backup on request if confirmed" do
        name = "b001"
        @pgbackups.stub!(:args).and_return([name])

        fake_client = mock("pgbackups_client")
        fake_client.should_receive(:get_backup).with(name).and_return({})
        fake_client.should_receive(:delete_backup).with(name).and_return({})
        @pgbackups.should_receive(:pgbackup_client).and_return(fake_client, fake_client)

        @pgbackups.destroy
      end

      it "aborts if no database addon is present" do
        # FIXME: occasionally outputs failed, depending on test run order
        STDOUT.stub!(:puts)
        STDERR.should_receive(:puts).with(" !    Your app has no databases.")
        lambda { @pgbackups.capture }.should raise_error SystemExit
      end

      context "on errors" do
        def stub_failed_capture(log)
          backup_obj = {
            "error_at" => Time.now.to_s,
            "log" => log,
            'to_url' => 'postgres://from/bar'
          }
          @pgbackups.stub!(:transfer!).and_return(backup_obj)
          @pgbackups.stub!(:poll_transfer!).with(backup_obj).and_return(backup_obj)
        end

        before(:each) do
          @pgbackups.stub!(:resolve_db).and_return({})
        end

        it 'aborts on a generic error' do
          stub_failed_capture "something generic"
          @pgbackups.should_receive(:error).with("An error occurred and your backup did not finish.")
          @pgbackups.capture
        end

        it 'aborts and informs when the database isnt up yet' do
          stub_failed_capture 'could not translate host name "ec2-42-42-42-42.compute-1.amazonaws.com" to address: Name or service not known'
{'fraction_non_alphanumeric': 0.1219883564711151, 'fraction_numerical': 0.0042991491267353335, 'mean_word_length': 3.1930153961697334, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 33, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '394779', 'n_tokens_mistral': 3678, 'n_tokens_neox': 3575, 'n_words': 609}