Commit 53bb6926 authored by Francisco Javier López's avatar Francisco Javier López Committed by Arturo Herrero

Move IDE routes to Rails instead of Vue

In this commit we move the routing responsibility for the IDE
from the Vue router to Rails. This way we can provide helpful
information instead of requesting it afterward.
parent 7fbb521a
...@@ -5,10 +5,12 @@ class IdeController < ApplicationController ...@@ -5,10 +5,12 @@ class IdeController < ApplicationController
include ClientsidePreviewCSP include ClientsidePreviewCSP
include StaticObjectExternalStorageCSP include StaticObjectExternalStorageCSP
include Gitlab::Utils::StrongMemoize
before_action do before_action do
push_frontend_feature_flag(:build_service_proxy) push_frontend_feature_flag(:build_service_proxy)
push_frontend_feature_flag(:schema_linting) push_frontend_feature_flag(:schema_linting)
define_index_vars
end end
feature_category :web_ide feature_category :web_ide
...@@ -16,4 +18,26 @@ class IdeController < ApplicationController ...@@ -16,4 +18,26 @@ class IdeController < ApplicationController
def index def index
Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count
end end
private
def define_index_vars
return unless project
@branch = params[:branch]
@path = params[:path]
@merge_request = params[:merge_request_id]
unless can?(current_user, :push_code, project)
@forked_project = ForkProjectsFinder.new(project, current_user: current_user).execute.first
end
end
def project
strong_memoize(:project) do
next unless params[:project_id].present?
Project.find_by_full_path(params[:project_id])
end
end
end end
...@@ -3,18 +3,31 @@ ...@@ -3,18 +3,31 @@
module IdeHelper module IdeHelper
def ide_data def ide_data
{ {
"empty-state-svg-path" => image_path('illustrations/multi_file_editor_empty.svg'), 'empty-state-svg-path' => image_path('illustrations/multi_file_editor_empty.svg'),
"no-changes-state-svg-path" => image_path('illustrations/multi-editor_no_changes_empty.svg'), 'no-changes-state-svg-path' => image_path('illustrations/multi-editor_no_changes_empty.svg'),
"committed-state-svg-path" => image_path('illustrations/multi-editor_all_changes_committed_empty.svg'), 'committed-state-svg-path' => image_path('illustrations/multi-editor_all_changes_committed_empty.svg'),
"pipelines-empty-state-svg-path": image_path('illustrations/pipelines_empty.svg'), 'pipelines-empty-state-svg-path': image_path('illustrations/pipelines_empty.svg'),
"promotion-svg-path": image_path('illustrations/web-ide_promotion.svg'), 'promotion-svg-path': image_path('illustrations/web-ide_promotion.svg'),
"ci-help-page-path" => help_page_path('ci/quick_start/README'), 'ci-help-page-path' => help_page_path('ci/quick_start/README'),
"web-ide-help-page-path" => help_page_path('user/project/web_ide/index.md'), 'web-ide-help-page-path' => help_page_path('user/project/web_ide/index.md'),
"clientside-preview-enabled": Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?.to_s, 'clientside-preview-enabled': Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?.to_s,
"render-whitespace-in-code": current_user.render_whitespace_in_code.to_s, 'render-whitespace-in-code': current_user.render_whitespace_in_code.to_s,
"codesandbox-bundler-url": Gitlab::CurrentSettings.web_ide_clientside_preview_bundler_url 'codesandbox-bundler-url': Gitlab::CurrentSettings.web_ide_clientside_preview_bundler_url,
'branch-name' => @branch,
'file-path' => @path,
'merge-request' => @merge_request,
'forked-project' => convert_to_project_entity_json(@forked_project),
'project' => convert_to_project_entity_json(@project)
} }
end end
private
def convert_to_project_entity_json(project)
return unless project
API::Entities::Project.represent(project).to_json
end
end end
::IdeHelper.prepend_if_ee('::EE::IdeHelper') ::IdeHelper.prepend_if_ee('::EE::IdeHelper')
---
title: Move IDE routes to Rails
merge_request: 55597
author:
type: changed
...@@ -132,8 +132,24 @@ Rails.application.routes.draw do ...@@ -132,8 +132,24 @@ Rails.application.routes.draw do
# UserCallouts # UserCallouts
resources :user_callouts, only: [:create] resources :user_callouts, only: [:create]
get 'ide' => 'ide#index' scope :ide, as: :ide, format: false do
get 'ide/*vueroute' => 'ide#index', format: false get '/', to: 'ide#index'
get '/project', to: 'ide#index'
scope path: 'project/:project_id', as: :project, constraints: { project_id: Gitlab::PathRegex.full_namespace_route_regex } do
%w[edit tree blob].each do |action|
get "/#{action}", to: 'ide#index'
get "/#{action}/*branch/-/*path", to: 'ide#index'
get "/#{action}/*branch/-", to: 'ide#index'
get "/#{action}/*branch", to: 'ide#index'
end
get '/merge_requests/:merge_request_id', to: 'ide#index', constraints: { merge_request_id: /\d+/ }
get '/', to: 'ide#index'
end
end
resource :projects
draw :operations draw :operations
draw :jira_connect draw :jira_connect
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe IdeHelper do
describe '#ide_data' do
let_it_be(:project) { create(:project) }
before do
allow(helper).to receive(:current_user).and_return(project.creator)
end
context 'when instance vars are not set' do
it 'returns instance data in the hash as nil' do
expect(helper.ide_data)
.to include(
'branch-name' => nil,
'file-path' => nil,
'merge-request' => nil,
'forked-project' => nil,
'project' => nil
)
end
end
context 'when instance vars are set' do
it 'returns instance data in the hash' do
self.instance_variable_set(:@branch, 'master')
self.instance_variable_set(:@path, 'foo/bar')
self.instance_variable_set(:@merge_request, '1')
self.instance_variable_set(:@forked_project, project)
self.instance_variable_set(:@project, project)
serialized_project = API::Entities::Project.represent(project).to_json
expect(helper.ide_data)
.to include(
'branch-name' => 'master',
'file-path' => 'foo/bar',
'merge-request' => '1',
'forked-project' => serialized_project,
'project' => serialized_project
)
end
end
end
end
...@@ -3,7 +3,11 @@ ...@@ -3,7 +3,11 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe IdeController do RSpec.describe IdeController do
let(:user) { create(:user) } let_it_be(:project) { create(:project, :public) }
let_it_be(:creator) { project.creator }
let_it_be(:other_user) { create(:user) }
let(:user) { creator }
before do before do
sign_in(user) sign_in(user)
...@@ -14,4 +18,172 @@ RSpec.describe IdeController do ...@@ -14,4 +18,172 @@ RSpec.describe IdeController do
get ide_url get ide_url
end end
describe '#index', :aggregate_failures do
subject { get route }
shared_examples 'user cannot push code' do
include ProjectForksHelper
let(:user) { other_user }
context 'when user does not have fork' do
it 'does not instantiate forked_project instance var and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to eq project
expect(assigns(:forked_project)).to be_nil
end
end
context 'when user has have fork' do
let!(:fork) { fork_project(project, user, repository: true) }
it 'instantiates forked_project instance var and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to eq project
expect(assigns(:forked_project)).to eq fork
end
end
end
context '/-/ide' do
let(:route) { '/-/ide' }
it 'does not instantiate any instance var and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to be_nil
expect(assigns(:branch)).to be_nil
expect(assigns(:path)).to be_nil
expect(assigns(:merge_request)).to be_nil
expect(assigns(:forked_project)).to be_nil
end
end
context '/-/ide/project' do
let(:route) { '/-/ide/project' }
it 'does not instantiate any instance var and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to be_nil
expect(assigns(:branch)).to be_nil
expect(assigns(:path)).to be_nil
expect(assigns(:merge_request)).to be_nil
expect(assigns(:forked_project)).to be_nil
end
end
context '/-/ide/project/:project' do
let(:route) { "/-/ide/project/#{project.full_path}" }
it 'instantiates project instance var and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to eq project
expect(assigns(:branch)).to be_nil
expect(assigns(:path)).to be_nil
expect(assigns(:merge_request)).to be_nil
expect(assigns(:forked_project)).to be_nil
end
it_behaves_like 'user cannot push code'
%w(edit blob tree).each do |action|
context "/-/ide/project/:project/#{action}" do
let(:route) { "/-/ide/project/#{project.full_path}/#{action}" }
it 'instantiates project instance var and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to eq project
expect(assigns(:branch)).to be_nil
expect(assigns(:path)).to be_nil
expect(assigns(:merge_request)).to be_nil
expect(assigns(:forked_project)).to be_nil
end
it_behaves_like 'user cannot push code'
context "/-/ide/project/:project/#{action}/:branch" do
let(:route) { "/-/ide/project/#{project.full_path}/#{action}/master" }
it 'instantiates project and branch instance vars and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to eq project
expect(assigns(:branch)).to eq 'master'
expect(assigns(:path)).to be_nil
expect(assigns(:merge_request)).to be_nil
expect(assigns(:forked_project)).to be_nil
end
it_behaves_like 'user cannot push code'
context "/-/ide/project/:project/#{action}/:branch/-" do
let(:route) { "/-/ide/project/#{project.full_path}/#{action}/branch/slash/-" }
it 'instantiates project and branch instance vars and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to eq project
expect(assigns(:branch)).to eq 'branch/slash'
expect(assigns(:path)).to be_nil
expect(assigns(:merge_request)).to be_nil
expect(assigns(:forked_project)).to be_nil
end
it_behaves_like 'user cannot push code'
context "/-/ide/project/:project/#{action}/:branch/-/:path" do
let(:route) { "/-/ide/project/#{project.full_path}/#{action}/master/-/foo/.bar" }
it 'instantiates project, branch, and path instance vars and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to eq project
expect(assigns(:branch)).to eq 'master'
expect(assigns(:path)).to eq 'foo/.bar'
expect(assigns(:merge_request)).to be_nil
expect(assigns(:forked_project)).to be_nil
end
it_behaves_like 'user cannot push code'
end
end
end
end
end
context '/-/ide/project/:project/merge_requests/:merge_request_id' do
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:route) { "/-/ide/project/#{project.full_path}/merge_requests/#{merge_request.id}" }
it 'instantiates project and merge_request instance vars and return 200' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:project)).to eq project
expect(assigns(:branch)).to be_nil
expect(assigns(:path)).to be_nil
expect(assigns(:merge_request)).to eq merge_request.id.to_s
expect(assigns(:forked_project)).to be_nil
end
it_behaves_like 'user cannot push code'
end
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment