githubish_import_controller_shared_examples.rb 7.92 KB
Newer Older
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 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 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
# Specifications for behavior common to all objects with an email attribute.
# Takes a list of email-format attributes and requires:
# - subject { "the object with a attribute= setter"  }
#   Note: You have access to `email_value` which is the email address value
#         being currently tested).

shared_examples 'a GitHub-ish import controller: POST personal_access_token' do
  let(:status_import_url) { public_send("status_import_#{provider}_url") }

  it "updates access token" do
    token = 'asdfasdf9876'

    allow_any_instance_of(Gitlab::GithubImport::Client).
      to receive(:user).and_return(true)

    post :personal_access_token, personal_access_token: token

    expect(session[:access_token]).to eq(token)
    expect(controller).to redirect_to(status_import_url)
  end
end

shared_examples 'a GitHub-ish import controller: GET new' do
  let(:status_import_url) { public_send("status_import_#{provider}_url") }

  it "redirects to status if we already have a token" do
    assign_session_token
    allow(controller).to receive(:logged_in_with_provider?).and_return(false)

    get :new

    expect(controller).to redirect_to(status_import_url)
  end

  it "renders the :new page if no token is present in session" do
    get :new

    expect(response).to render_template(:new)
  end
end

shared_examples 'a GitHub-ish import controller: GET status' do
  let(:new_import_url) { public_send("new_import_#{provider}_url") }
  let(:user) { create(:user) }
  let(:repo) { OpenStruct.new(login: 'vim', full_name: 'asd/vim') }
  let(:org) { OpenStruct.new(login: 'company') }
  let(:org_repo) { OpenStruct.new(login: 'company', full_name: 'company/repo') }
  let(:extra_assign_expectations) { {} }

  before do
    assign_session_token
  end

  it "assigns variables" do
    project = create(:empty_project, import_type: provider, creator_id: user.id)
    stub_client(repos: [repo, org_repo], orgs: [org], org_repos: [org_repo])

    get :status

    expect(assigns(:already_added_projects)).to eq([project])
    expect(assigns(:repos)).to eq([repo, org_repo])
    extra_assign_expectations.each do |key, value|
      expect(assigns(key)).to eq(value)
    end
  end

  it "does not show already added project" do
    project = create(:empty_project, import_type: provider, creator_id: user.id, import_source: 'asd/vim')
    stub_client(repos: [repo], orgs: [])

    get :status

    expect(assigns(:already_added_projects)).to eq([project])
    expect(assigns(:repos)).to eq([])
  end

  it "handles an invalid access token" do
    allow_any_instance_of(Gitlab::GithubImport::Client).
      to receive(:repos).and_raise(Octokit::Unauthorized)

    get :status

    expect(session[:access_token]).to eq(nil)
    expect(controller).to redirect_to(new_import_url)
    expect(flash[:alert]).to eq("Access denied to your #{Gitlab::ImportSources.options.key(provider.to_s)} account.")
  end
end

shared_examples 'a GitHub-ish import controller: POST create' do
  let(:user) { create(:user) }
  let(:provider_username) { user.username }
  let(:provider_user) { OpenStruct.new(login: provider_username) }
  let(:provider_repo) do
    OpenStruct.new(
      name: 'vim',
      full_name: "#{provider_username}/vim",
      owner: OpenStruct.new(login: provider_username)
    )
  end

  before do
    stub_client(user: provider_user, repo: provider_repo)
    assign_session_token
  end

  context "when the repository owner is the Gitea user" do
    context "when the Gitea user and GitLab user's usernames match" do
      it "takes the current user's namespace" do
        expect(Gitlab::GithubImport::ProjectCreator).
          to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider).
            and_return(double(execute: true))

        post :create, format: :js
      end
    end

    context "when the Gitea user and GitLab user's usernames don't match" do
      let(:provider_username) { "someone_else" }

      it "takes the current user's namespace" do
        expect(Gitlab::GithubImport::ProjectCreator).
          to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider).
            and_return(double(execute: true))

        post :create, format: :js
      end
    end
  end

  context "when the repository owner is not the Gitea user" do
    let(:other_username) { "someone_else" }

    before do
      provider_repo.owner = OpenStruct.new(login: other_username)
      assign_session_token
    end

    context "when a namespace with the Gitea user's username already exists" do
      let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) }

      context "when the namespace is owned by the GitLab user" do
        it "takes the existing namespace" do
          expect(Gitlab::GithubImport::ProjectCreator).
            to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider).
              and_return(double(execute: true))

          post :create, format: :js
        end
      end

      context "when the namespace is not owned by the GitLab user" do
        before do
          existing_namespace.owner = create(:user)
          existing_namespace.save
        end

        it "creates a project using user's namespace" do
          expect(Gitlab::GithubImport::ProjectCreator).
            to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider).
              and_return(double(execute: true))

          post :create, format: :js
        end
      end
    end

    context "when a namespace with the Gitea user's username doesn't exist" do
      context "when current user can create namespaces" do
        it "creates the namespace" do
          expect(Gitlab::GithubImport::ProjectCreator).
            to receive(:new).and_return(double(execute: true))

          expect { post :create, target_namespace: provider_repo.name, format: :js }.to change(Namespace, :count).by(1)
        end

        it "takes the new namespace" do
          expect(Gitlab::GithubImport::ProjectCreator).
            to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider).
            and_return(double(execute: true))

          post :create, target_namespace: provider_repo.name, format: :js
        end
      end

      context "when current user can't create namespaces" do
        before do
          user.update_attribute(:can_create_group, false)
        end

        it "doesn't create the namespace" do
          expect(Gitlab::GithubImport::ProjectCreator).
            to receive(:new).and_return(double(execute: true))

          expect { post :create, format: :js }.not_to change(Namespace, :count)
        end

        it "takes the current user's namespace" do
          expect(Gitlab::GithubImport::ProjectCreator).
            to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider).
            and_return(double(execute: true))

          post :create, format: :js
        end
      end
    end

    context 'user has chosen a namespace and name for the project' do
      let(:test_namespace) { create(:namespace, name: 'test_namespace', owner: user) }
      let(:test_name) { 'test_name' }

      it 'takes the selected namespace and name' do
        expect(Gitlab::GithubImport::ProjectCreator).
          to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider).
            and_return(double(execute: true))

        post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :js }
      end

      it 'takes the selected name and default namespace' do
        expect(Gitlab::GithubImport::ProjectCreator).
          to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider).
            and_return(double(execute: true))

        post :create, { new_name: test_name, format: :js }
      end
    end
  end
end