environment_status_spec.rb 6.34 KB
Newer Older
1 2 3
require 'spec_helper'

describe EnvironmentStatus do
4 5
  include ProjectForksHelper

6
  let(:deployment)    { create(:deployment, :succeed, :review_app) }
7
  let(:environment)   { deployment.environment }
8 9
  let(:project)       { deployment.project }
  let(:merge_request) { create(:merge_request, :deployed_review_app, deployment: deployment) }
10
  let(:sha)           { deployment.sha }
11

12
  subject(:environment_status) { described_class.new(environment, merge_request, sha) }
13 14 15 16

  it { is_expected.to delegate_method(:id).to(:environment) }
  it { is_expected.to delegate_method(:name).to(:environment) }
  it { is_expected.to delegate_method(:project).to(:environment) }
17
  it { is_expected.to delegate_method(:deployed_at).to(:deployment) }
18
  it { is_expected.to delegate_method(:status).to(:deployment) }
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

  describe '#project' do
    subject { environment_status.project }

    it { is_expected.to eq(project) }
  end

  describe '#merge_request' do
    subject { environment_status.merge_request }

    it { is_expected.to eq(merge_request) }
  end

  describe '#deployment' do
    subject { environment_status.deployment }

    it { is_expected.to eq(deployment) }
  end
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

  # $ git diff --stat pages-deploy-target...pages-deploy
  # .gitlab/route-map.yml              |  5 +++++
  # files/html/500.html                | 13 -------------
  # files/html/page.html               |  3 +++
  # files/js/application.js            |  3 +++
  # files/markdown/ruby-style-guide.md |  4 ++++
  # pages-deploy.txt                   |  1 +
  #
  # $ cat .gitlab/route-map.yml
  # - source: /files\/markdown\/(.+)\.md$/
  #   public: '\1.html'
  #
  # - source: /files\/(.+)/
  #   public: '\1'
  describe '#changes' do
    it 'contains only added and modified public pages' do
      expect(environment_status.changes).to contain_exactly(
        {
          path: 'ruby-style-guide.html',
          external_url: "#{environment.external_url}/ruby-style-guide.html"
        }, {
          path: 'html/page.html',
          external_url: "#{environment.external_url}/html/page.html"
        }
      )
    end
  end
65 66 67 68 69

  describe '.for_merge_request' do
    let(:admin)    { create(:admin) }
    let(:pipeline) { create(:ci_pipeline, sha: sha) }

70 71 72
    it 'is based on merge_request.diff_head_sha' do
      expect(merge_request).to receive(:diff_head_sha)
      expect(merge_request).not_to receive(:merge_commit_sha)
73 74 75 76 77 78 79 80 81 82 83 84 85

      described_class.for_merge_request(merge_request, admin)
    end
  end

  describe '.after_merge_request' do
    let(:admin)    { create(:admin) }
    let(:pipeline) { create(:ci_pipeline, sha: sha) }

    before do
      merge_request.mark_as_merged!
    end

86 87 88
    it 'is based on merge_request.merge_commit_sha' do
      expect(merge_request).to receive(:merge_commit_sha)
      expect(merge_request).not_to receive(:diff_head_sha)
89 90 91 92

      described_class.after_merge_request(merge_request, admin)
    end
  end
93 94

  describe '.build_environments_status' do
95
    subject { described_class.send(:build_environments_status, merge_request, user, pipeline) }
96 97 98 99 100 101 102 103 104 105 106 107

    let!(:build) { create(:ci_build, :deploy_to_production, pipeline: pipeline) }
    let(:environment) { build.deployment.environment }
    let(:user) { project.owner }

    context 'when environment is created on a forked project' do
      let(:project) { create(:project, :repository) }
      let(:forked) { fork_project(project, user, repository: true) }
      let(:sha) { forked.commit.sha }
      let(:pipeline) { create(:ci_pipeline, sha: sha, project: forked) }

      let(:merge_request) do
Shinya Maeda's avatar
Shinya Maeda committed
108 109 110 111 112
        create(:merge_request,
               source_project: forked,
               target_project: project,
               target_branch: 'master',
               head_pipeline: pipeline)
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
      end

      it 'returns environment status' do
        expect(subject.count).to eq(1)
        expect(subject[0].environment).to eq(environment)
        expect(subject[0].merge_request).to eq(merge_request)
        expect(subject[0].sha).to eq(sha)
      end
    end

    context 'when environment is created on a target project' do
      let(:project) { create(:project, :repository) }
      let(:sha) { project.commit.sha }
      let(:pipeline) { create(:ci_pipeline, sha: sha, project: project) }

      let(:merge_request) do
Shinya Maeda's avatar
Shinya Maeda committed
129 130 131 132 133 134
        create(:merge_request,
               source_project: project,
               source_branch: 'feature',
               target_project: project,
               target_branch: 'master',
               head_pipeline: pipeline)
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
      end

      it 'returns environment status' do
        expect(subject.count).to eq(1)
        expect(subject[0].environment).to eq(environment)
        expect(subject[0].merge_request).to eq(merge_request)
        expect(subject[0].sha).to eq(sha)
      end

      context 'when the build stops an environment' do
        let!(:build) { create(:ci_build, :stop_review_app, pipeline: pipeline) }

        it 'does not return environment status' do
          expect(subject.count).to eq(0)
        end
      end

      context 'when user does not have a permission to see the environment' do
        let(:user) { create(:user) }

        it 'does not return environment status' do
          expect(subject.count).to eq(0)
        end
      end
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

      context 'when multiple deployments with the same SHA in different environments' do
        let(:pipeline2) { create(:ci_pipeline, sha: sha, project: project) }
        let!(:build2) { create(:ci_build, :start_review_app, pipeline: pipeline2) }

        it 'returns deployments related to the head pipeline' do
          expect(subject.count).to eq(1)
          expect(subject[0].environment).to eq(environment)
          expect(subject[0].merge_request).to eq(merge_request)
          expect(subject[0].sha).to eq(sha)
        end
      end

      context 'when multiple deployments in the same pipeline for the same environments' do
        let!(:build2) { create(:ci_build, :deploy_to_production, pipeline: pipeline) }

        it 'returns unique entries' do
          expect(subject.count).to eq(1)
          expect(subject[0].environment).to eq(environment)
          expect(subject[0].merge_request).to eq(merge_request)
          expect(subject[0].sha).to eq(sha)
        end
      end

      context 'when environment is stopped' do
        before do
          environment.stop!
        end

        it 'does not return environment status' do
          expect(subject.count).to eq(0)
        end
      end
192 193
    end
  end
194
end