summaryrefslogtreecommitdiff
path: root/qa/spec/git/repository_spec.rb
blob: fd77681797f79194ed2df7a5ee8c221ee5d2d411 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# frozen_string_literal: true

describe QA::Git::Repository do
  include Helpers::StubENV

  shared_context 'git directory' do
    let(:repository) { described_class.new }
    let(:tmp_git_dir) { Dir.mktmpdir }
    let(:tmp_netrc_dir) { Dir.mktmpdir }

    before do
      stub_env('GITLAB_USERNAME', 'root')
      cd_empty_temp_directory
      set_bad_uri

      allow(repository).to receive(:tmp_home_dir).and_return(tmp_netrc_dir)
    end

    after do
      # Switch to a safe dir before deleting tmp dirs to avoid dir access errors
      FileUtils.cd __dir__
      FileUtils.remove_entry_secure(tmp_git_dir, true)
      FileUtils.remove_entry_secure(tmp_netrc_dir, true)
    end

    def cd_empty_temp_directory
      FileUtils.cd tmp_git_dir
    end

    def set_bad_uri
      repository.uri = 'http://foo/bar.git'
    end
  end

  context 'with default credentials' do
    include_context 'git directory' do
      before do
        repository.use_default_credentials
      end
    end

    describe '#clone' do
      it 'is unable to resolve host' do
        expect { repository.clone }.to raise_error(described_class::RepositoryCommandError, /The command .* failed \(128\) with the following output/)
      end
    end

    describe '#push_changes' do
      before do
        `git init` # need a repo to push from
      end

      it 'fails to push changes' do
        expect { repository.push_changes }.to raise_error(described_class::RepositoryCommandError, /The command .* failed \(1\) with the following output/)
      end
    end

    describe '#git_protocol=' do
      [0, 1, 2].each do |version|
        it "configures git to use protocol version #{version}" do
          expect(repository).to receive(:run).with("git config protocol.version #{version}")
          repository.git_protocol = version
        end
      end

      it 'raises an error if the version is unsupported' do
        expect { repository.git_protocol = 'foo' }.to raise_error(ArgumentError, "Please specify the protocol you would like to use: 0, 1, or 2")
      end
    end

    describe '#fetch_supported_git_protocol' do
      it "reports the detected version" do
        expect(repository).to receive(:run).and_return("packet: git< version 2")
        expect(repository.fetch_supported_git_protocol).to eq('2')
      end

      it 'reports unknown if version is unknown' do
        expect(repository).to receive(:run).and_return("packet: git< version -1")
        expect(repository.fetch_supported_git_protocol).to eq('unknown')
      end

      it 'reports unknown if content does not identify a version' do
        expect(repository).to receive(:run).and_return("foo")
        expect(repository.fetch_supported_git_protocol).to eq('unknown')
      end
    end

    describe '#use_default_credentials' do
      it 'adds credentials to .netrc' do
        expect(File.read(File.join(tmp_netrc_dir, '.netrc')))
          .to eq("machine foo login #{QA::Runtime::User.default_username} password #{QA::Runtime::User.default_password}\n")
      end
    end
  end

  context 'with specific credentials' do
    include_context 'git directory'

    context 'before setting credentials' do
      it 'does not add credentials to .netrc' do
        expect(repository).not_to receive(:save_netrc_content)
      end
    end

    describe '#password=' do
      it 'raises an error if no username was given' do
        expect { repository.password = 'foo' }
          .to raise_error(QA::Git::Repository::InvalidCredentialsError,
            "Please provide a username when setting a password")
      end

      it 'adds credentials to .netrc' do
        repository.username = 'user'
        repository.password = 'foo'

        expect(File.read(File.join(tmp_netrc_dir, '.netrc')))
          .to eq("machine foo login user password foo\n")
      end

      it 'adds credentials with special characters' do
        password = %q(!"#$%&'()*+,-./:;<=>?)
        repository.username = 'user'
        repository.password = password

        expect(File.read(File.join(tmp_netrc_dir, '.netrc')))
          .to eq("machine foo login user password #{password}\n")
      end
    end
  end
end