Commit 6683fdcf authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Add nested groups support to the routing

Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parent b1b5060d
...@@ -49,6 +49,14 @@ class ApplicationController < ActionController::Base ...@@ -49,6 +49,14 @@ class ApplicationController < ActionController::Base
render_404 render_404
end end
def route_not_found
if current_user
not_found
else
redirect_to new_user_session_path
end
end
protected protected
# This filter handles both private tokens and personal access tokens # This filter handles both private tokens and personal access tokens
......
...@@ -174,6 +174,7 @@ class Project < ActiveRecord::Base ...@@ -174,6 +174,7 @@ class Project < ActiveRecord::Base
message: Gitlab::Regex.project_name_regex_message } message: Gitlab::Regex.project_name_regex_message }
validates :path, validates :path,
presence: true, presence: true,
project_path: true,
length: { within: 0..255 }, length: { within: 0..255 },
format: { with: Gitlab::Regex.project_path_regex, format: { with: Gitlab::Regex.project_path_regex,
message: Gitlab::Regex.project_path_regex_message } message: Gitlab::Regex.project_path_regex_message }
......
...@@ -291,8 +291,12 @@ class User < ActiveRecord::Base ...@@ -291,8 +291,12 @@ class User < ActiveRecord::Base
end end
end end
def find_by_username(username)
iwhere(username: username).take
end
def find_by_username!(username) def find_by_username!(username)
find_by!('lower(username) = ?', username.downcase) iwhere(username: username).take!
end end
def find_by_personal_access_token(token_string) def find_by_personal_access_token(token_string)
......
...@@ -35,8 +35,22 @@ class NamespaceValidator < ActiveModel::EachValidator ...@@ -35,8 +35,22 @@ class NamespaceValidator < ActiveModel::EachValidator
users users
].freeze ].freeze
def self.valid?(value)
!reserved?(value) && follow_format?(value)
end
def self.reserved?(value)
RESERVED.include?(value)
end
def self.follow_format?(value)
value =~ Gitlab::Regex.namespace_regex
end
delegate :reserved?, :follow_format?, to: :class
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
unless value =~ Gitlab::Regex.namespace_regex unless follow_format?(value)
record.errors.add(attribute, Gitlab::Regex.namespace_regex_message) record.errors.add(attribute, Gitlab::Regex.namespace_regex_message)
end end
...@@ -44,10 +58,4 @@ class NamespaceValidator < ActiveModel::EachValidator ...@@ -44,10 +58,4 @@ class NamespaceValidator < ActiveModel::EachValidator
record.errors.add(attribute, "#{value} is a reserved name") record.errors.add(attribute, "#{value} is a reserved name")
end end
end end
private
def reserved?(value)
RESERVED.include?(value)
end
end end
# ProjectPathValidator
#
# Custom validator for GitLab project path values.
#
# Values are checked for formatting and exclusion from a list of reserved path
# names.
class ProjectPathValidator < ActiveModel::EachValidator
# All project routes with wildcard argument must be listed here.
# Otherwise it can lead to routing issues when route considered as project name.
#
# Example:
# /group/project/tree/deploy_keys
#
# without tree as reserved name routing can match 'group/project' as group name,
# 'tree' as project name and 'deploy_keys' as route.
#
RESERVED = (NamespaceValidator::RESERVED +
%w[tree commits wikis new edit create update logs_tree
preview blob blame raw files create_dir find_file]).freeze
def self.valid?(value)
!reserved?(value)
end
def self.reserved?(value)
RESERVED.include?(value)
end
delegate :reserved?, to: :class
def validate_each(record, attribute, value)
if reserved?(value)
record.errors.add(attribute, "#{value} is a reserved name")
end
end
end
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
= link_to 'Home', namespace_project_wiki_path(@project.namespace, @project, :home) = link_to 'Home', namespace_project_wiki_path(@project.namespace, @project, :home)
= nav_link(path: 'wikis#pages') do = nav_link(path: 'wikis#pages') do
= link_to 'Pages', namespace_project_wiki_pages_path(@project.namespace, @project) = link_to 'Pages', namespace_project_wikis_pages_path(@project.namespace, @project)
= nav_link(path: 'wikis#git_access') do = nav_link(path: 'wikis#git_access') do
= link_to namespace_project_wikis_git_access_path(@project.namespace, @project) do = link_to namespace_project_wikis_git_access_path(@project.namespace, @project) do
......
---
title: Add nested groups support to the routing
merge_request: 7459
author:
require 'sidekiq/web' require 'sidekiq/web'
require 'sidekiq/cron/web' require 'sidekiq/cron/web'
require 'api/api' require 'api/api'
require 'constraints/group_url_constrainer'
Rails.application.routes.draw do Rails.application.routes.draw do
concern :access_requestable do concern :access_requestable do
...@@ -78,10 +79,21 @@ Rails.application.routes.draw do ...@@ -78,10 +79,21 @@ Rails.application.routes.draw do
draw :user draw :user
draw :project draw :project
# Get all keys of user
get ':username.keys' => 'profiles/keys#get_keys', constraints: { username: /.*/ }
root to: "root#index" root to: "root#index"
get '*unmatched_route', to: 'application#not_found' # Since group show page is wildcard routing
# we want all other routing to be checked before matching this one
constraints(GroupUrlConstrainer.new) do
scope(path: '*id',
as: :group,
constraints: { id: Gitlab::Regex.namespace_route_regex, format: /(html|json|atom)/ },
controller: :groups) do
get '/', action: :show
patch '/', action: :update
put '/', action: :update
delete '/', action: :destroy
end
end
get '*unmatched_route', to: 'application#route_not_found'
end end
scope constraints: { id: /.+\.git/, format: nil } do scope(path: '*namespace_id/:project_id', constraints: { format: nil }) do
# Git HTTP clients ('git clone' etc.) scope(constraints: { project_id: Gitlab::Regex.project_git_route_regex }, module: :projects) do
get '/info/refs', to: 'git_http#info_refs' # Git HTTP clients ('git clone' etc.)
post '/git-upload-pack', to: 'git_http#git_upload_pack' scope(controller: :git_http) do
post '/git-receive-pack', to: 'git_http#git_receive_pack' get '/info/refs', action: :info_refs
post '/git-upload-pack', action: :git_upload_pack
post '/git-receive-pack', action: :git_receive_pack
end
# Git LFS API (metadata) # Git LFS API (metadata)
post '/info/lfs/objects/batch', to: 'lfs_api#batch' scope(path: 'info/lfs/objects', controller: :lfs_api) do
post '/info/lfs/objects', to: 'lfs_api#deprecated' post :batch
get '/info/lfs/objects/*oid', to: 'lfs_api#deprecated' post '/', action: :deprecated
get '/*oid', action: :deprecated
end
# GitLab LFS object storage # GitLab LFS object storage
scope constraints: { oid: /[a-f0-9]{64}/ } do scope(path: 'gitlab-lfs/objects/*oid', controller: :lfs_storage, constraints: { oid: /[a-f0-9]{64}/ }) do
get '/gitlab-lfs/objects/*oid', to: 'lfs_storage#download' get '/', action: :download
scope constraints: { size: /[0-9]+/ } do scope constraints: { size: /[0-9]+/ } do
put '/gitlab-lfs/objects/*oid/*size/authorize', to: 'lfs_storage#upload_authorize' put '/*size/authorize', action: :upload_authorize
put '/gitlab-lfs/objects/*oid/*size', to: 'lfs_storage#upload_finalize' put '/*size', action: :upload_finalize
end
end end
end end
end
# Allow /info/refs, /info/refs?service=git-upload-pack, and # Redirect /group/project/info/refs to /group/project.git/info/refs
# /info/refs?service=git-receive-pack, but nothing else. scope(constraints: { project_id: Gitlab::Regex.project_route_regex }) do
# # Allow /info/refs, /info/refs?service=git-upload-pack, and
git_http_handshake = lambda do |request| # /info/refs?service=git-receive-pack, but nothing else.
request.query_string.blank? || #
request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/) git_http_handshake = lambda do |request|
end ProjectUrlConstrainer.new.matches?(request) &&
(request.query_string.blank? ||
request.query_string.match(/\Aservice=git-(upload|receive)-pack\z/))
end
ref_redirect = redirect do |params, request| ref_redirect = redirect do |params, request|
path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs" path = "#{params[:namespace_id]}/#{params[:project_id]}.git/info/refs"
path << "?#{request.query_string}" unless request.query_string.blank? path << "?#{request.query_string}" unless request.query_string.blank?
path path
end end
get '/info/refs', constraints: git_http_handshake, to: ref_redirect get '/info/refs', constraints: git_http_handshake, to: ref_redirect
end
end
require 'constraints/group_url_constrainer'
constraints(GroupUrlConstrainer.new) do
scope(path: ':id',
as: :group,
constraints: { id: Gitlab::Regex.namespace_route_regex },
controller: :groups) do
get '/', action: :show
patch '/', action: :update
put '/', action: :update
delete '/', action: :destroy
end
end
resources :groups, only: [:index, :new, :create] resources :groups, only: [:index, :new, :create]
scope(path: 'groups/:id', scope(path: 'groups/*id',
controller: :groups, controller: :groups,
constraints: { id: Gitlab::Regex.namespace_route_regex }) do constraints: { id: Gitlab::Regex.namespace_route_regex }) do
get :edit, as: :edit_group get :edit, as: :edit_group
...@@ -24,7 +10,7 @@ scope(path: 'groups/:id', ...@@ -24,7 +10,7 @@ scope(path: 'groups/:id',
get :activity, as: :activity_group get :activity, as: :activity_group
end end
scope(path: 'groups/:group_id', scope(path: 'groups/*group_id',
module: :groups, module: :groups,
as: :group, as: :group,
constraints: { group_id: Gitlab::Regex.namespace_route_regex }) do constraints: { group_id: Gitlab::Regex.namespace_route_regex }) do
...@@ -42,4 +28,4 @@ scope(path: 'groups/:group_id', ...@@ -42,4 +28,4 @@ scope(path: 'groups/:group_id',
end end
# Must be last route in this file # Must be last route in this file
get 'groups/:id' => 'groups#show', as: :group_canonical, constraints: { id: Gitlab::Regex.namespace_route_regex } get 'groups/*id' => 'groups#show', as: :group_canonical, constraints: { id: Gitlab::Regex.namespace_route_regex }
resources :projects, constraints: { id: /[^\/]+/ }, only: [:index, :new, :create] require 'constraints/project_url_constrainer'
resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do resources :projects, only: [:index, :new, :create]
resources(:projects, constraints: { id: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }, except:
[:new, :create, :index], path: "/") do draw :git_http
member do
put :transfer
delete :remove_fork
post :archive
post :unarchive
post :housekeeping
post :toggle_star
post :preview_markdown
post :export
post :remove_export
post :generate_new_export
get :download_export
get :autocomplete_sources
get :activity
get :refs
put :new_issue_address
end
scope module: :projects do constraints(ProjectUrlConstrainer.new) do
draw :git_http scope(path: '*namespace_id', as: :namespace) do
scope(path: ':project_id',
constraints: { project_id: Gitlab::Regex.project_route_regex },
module: :projects,
as: :project) do
# #
# Templates # Templates
...@@ -311,5 +298,28 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: ...@@ -311,5 +298,28 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only:
draw :wiki draw :wiki
draw :repository draw :repository
end end
resources(:projects,
path: '/',
constraints: { id: Gitlab::Regex.project_route_regex },
only: [:edit, :show, :update, :destroy]) do
member do
put :transfer
delete :remove_fork
post :archive
post :unarchive
post :housekeeping
post :toggle_star
post :preview_markdown
post :export
post :remove_export
post :generate_new_export
get :download_export
get :autocomplete_sources
get :activity
get :refs
put :new_issue_address
end
end
end end
end end
...@@ -29,82 +29,60 @@ get '/edit/*id', to: 'blob#edit', constraints: { id: /.+/ }, as: 'edit_blob' ...@@ -29,82 +29,60 @@ get '/edit/*id', to: 'blob#edit', constraints: { id: /.+/ }, as: 'edit_blob'
put '/update/*id', to: 'blob#update', constraints: { id: /.+/ }, as: 'update_blob' put '/update/*id', to: 'blob#update', constraints: { id: /.+/ }, as: 'update_blob'
post '/preview/*id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob' post '/preview/*id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob'
scope do scope('/blob/*id', as: :blob, controller: :blob, constraints: { id: /.+/, format: false }) do
get( get :diff
'/blob/*id/diff', get '/', action: :show
to: 'blob#diff', delete '/', action: :destroy
constraints: { id: /.+/, format: false }, post '/', action: :create
as: :blob_diff put '/', action: :update
) end
get(
'/blob/*id',
to: 'blob#show',
constraints: { id: /.+/, format: false },
as: :blob
)
delete(
'/blob/*id',
to: 'blob#destroy',
constraints: { id: /.+/, format: false }
)
put(
'/blob/*id',
to: 'blob#update',
constraints: { id: /.+/, format: false }
)
post(
'/blob/*id',
to: 'blob#create',
constraints: { id: /.+/, format: false }
)
get( get(
'/raw/*id', '/raw/*id',
to: 'raw#show', to: 'raw#show',
constraints: { id: /.+/, format: /(html|js)/ }, constraints: { id: /.+/, format: /(html|js)/ },
as: :raw as: :raw
) )
get( get(
'/tree/*id', '/tree/*id',
to: 'tree#show', to: 'tree#show',
constraints: { id: /.+/, format: /(html|js)/ }, constraints: { id: /.+/, format: /(html|js)/ },
as: :tree as: :tree
) )
get( get(
'/find_file/*id', '/find_file/*id',
to: 'find_file#show', to: 'find_file#show',
constraints: { id: /.+/, format: /html/ }, constraints: { id: /.+/, format: /html/ },
as: :find_file as: :find_file
) )
get( get(
'/files/*id', '/files/*id',
to: 'find_file#list', to: 'find_file#list',
constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ }, constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ },
as: :files as: :files
) )
post( post(
'/create_dir/*id', '/create_dir/*id',
to: 'tree#create_dir', to: 'tree#create_dir',
constraints: { id: /.+/ }, constraints: { id: /.+/ },
as: 'create_dir' as: 'create_dir'
) )
get( get(
'/blame/*id', '/blame/*id',
to: 'blame#show', to: 'blame#show',
constraints: { id: /.+/, format: /(html|js)/ }, constraints: { id: /.+/, format: /(html|js)/ },
as: :blame as: :blame
) )
# File/dir history # File/dir history
get( get(
'/commits/*id', '/commits/*id',
to: 'commits#show', to: 'commits#show',
constraints: { id: /.+/, format: false }, constraints: { id: /.+/, format: false },
as: :commits as: :commits
) )
end
...@@ -12,6 +12,9 @@ devise_scope :user do ...@@ -12,6 +12,9 @@ devise_scope :user do
end end
constraints(UserUrlConstrainer.new) do constraints(UserUrlConstrainer.new) do
# Get all keys of user
get ':username.keys' => 'profiles/keys#get_keys', constraints: { username: Gitlab::Regex.namespace_route_regex }
scope(path: ':username', scope(path: ':username',
as: :user, as: :user,
constraints: { username: Gitlab::Regex.namespace_route_regex }, constraints: { username: Gitlab::Regex.namespace_route_regex },
......
WIKI_SLUG_ID = { id: /\S+/ } unless defined? WIKI_SLUG_ID WIKI_SLUG_ID = { id: /\S+/ } unless defined? WIKI_SLUG_ID
scope do scope(controller: :wikis) do
# Order matters to give priority to these matches scope(path: 'wikis', as: :wikis) do
get '/wikis/git_access', to: 'wikis#git_access' get :git_access
get '/wikis/pages', to: 'wikis#pages', as: 'wiki_pages' get :pages
post '/wikis', to: 'wikis#create' get '/', to: redirect('/%{namespace_id}/%{project_id}/wikis/home')
post '/', to: 'wikis#create'
end
get '/wikis/*id/history', to: 'wikis#history', as: 'wiki_history', constraints: WIKI_SLUG_ID scope(path: 'wikis/*id', as: :wiki, constraints: WIKI_SLUG_ID, format: false) do
get '/wikis/*id/edit', to: 'wikis#edit', as: 'wiki_edit', constraints: WIKI_SLUG_ID get :edit
get :history
get '/wikis/*id', to: 'wikis#show', as: 'wiki', constraints: WIKI_SLUG_ID post :preview_markdown
delete '/wikis/*id', to: 'wikis#destroy', constraints: WIKI_SLUG_ID get '/', action: :show
put '/wikis/*id', to: 'wikis#update', constraints: WIKI_SLUG_ID put '/', action: :update
post '/wikis/*id/preview_markdown', to: 'wikis#preview_markdown', constraints: WIKI_SLUG_ID, as: 'wiki_preview_markdown' delete '/', action: :destroy
end
end end
...@@ -2,9 +2,7 @@ class Spinach::Features::Labels < Spinach::FeatureSteps ...@@ -2,9 +2,7 @@ class Spinach::Features::Labels < Spinach::FeatureSteps
include SharedAuthentication include SharedAuthentication
include SharedIssuable include SharedIssuable
include SharedProject include SharedProject
include SharedNote
include SharedPaths include SharedPaths
include SharedMarkdown
step 'And I visit project "Shop" labels page' do step 'And I visit project "Shop" labels page' do
visit namespace_project_labels_path(project.namespace, project) visit namespace_project_labels_path(project.namespace, project)
......
module SharedDiffNote module SharedDiffNote
include Spinach::DSL include Spinach::DSL
include RepoHelpers include RepoHelpers
include WaitForAjax
after do
wait_for_ajax if javascript_test?
end
step 'I cancel the diff comment' do step 'I cancel the diff comment' do
page.within(diff_file_selector) do page.within(diff_file_selector) do
......
...@@ -2,6 +2,10 @@ module SharedNote ...@@ -2,6 +2,10 @@ module SharedNote
include Spinach::DSL include Spinach::DSL
include WaitForAjax include WaitForAjax
after do
wait_for_ajax if javascript_test?
end
step 'I delete a comment' do step 'I delete a comment' do
page.within('.main-notes-list') do page.within('.main-notes-list') do
find('.note').hover find('.note').hover
......
module ConstrainerHelper
def extract_resource_path(path)
id = path.dup
id.sub!(/\A#{relative_url_root}/, '') if relative_url_root
id.sub(/\A\/+/, '').sub(/\/+\z/, '').sub(/.atom\z/, '')
end
private
def relative_url_root
if defined?(Gitlab::Application.config.relative_url_root)
Gitlab::Application.config.relative_url_root
end
end
end
require_relative 'constrainer_helper'
class GroupUrlConstrainer class GroupUrlConstrainer
include ConstrainerHelper
def matches?(request) def matches?(request)
id = extract_resource_path(request.path) id = request.params[:id]
return false unless valid?(id)
Group.find_by(path: id).present?
end
private
if id =~ Gitlab::Regex.namespace_regex def valid?(id)
Group.find_by(path: id).present? id.split('/').all? do |namespace|
else NamespaceValidator.valid?(namespace)
false
end end
end end
end end
class ProjectUrlConstrainer
def matches?(request)
namespace_path = request.params[:namespace_id]
project_path = request.params[:project_id] || request.params[:id]
full_path = namespace_path + '/' + project_path
unless ProjectPathValidator.valid?(project_path)
return false
end
Project.find_with_namespace(full_path).present?
end
end
require_relative 'constrainer_helper'
class UserUrlConstrainer class UserUrlConstrainer
include ConstrainerHelper
def matches?(request) def matches?(request)
id = extract_resource_path(request.path) User.find_by_username(request.params[:username]).present?
if id =~ Gitlab::Regex.namespace_regex
User.find_by('lower(username) = ?', id.downcase).present?
else
false
end
end end
end end
...@@ -8,8 +8,10 @@ module Gitlab ...@@ -8,8 +8,10 @@ module Gitlab
# allow non-regex validatiions, etc), `NAMESPACE_REGEX_STR_SIMPLE` serves as a Javascript-compatible version of # allow non-regex validatiions, etc), `NAMESPACE_REGEX_STR_SIMPLE` serves as a Javascript-compatible version of
# `NAMESPACE_REGEX_STR`, with the negative lookbehind assertion removed. This means that the client-side validation # `NAMESPACE_REGEX_STR`, with the negative lookbehind assertion removed. This means that the client-side validation
# will pass for usernames ending in `.atom` and `.git`, but will be caught by the server-side validation. # will pass for usernames ending in `.atom` and `.git`, but will be caught by the server-side validation.
NAMESPACE_REGEX_STR_SIMPLE = '[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze PATH_REGEX_STR = '[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*'.freeze
NAMESPACE_REGEX_STR_SIMPLE = PATH_REGEX_STR + '[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze
NAMESPACE_REGEX_STR = '(?:' + NAMESPACE_REGEX_STR_SIMPLE + ')(?<!\.git|\.atom)'.freeze NAMESPACE_REGEX_STR = '(?:' + NAMESPACE_REGEX_STR_SIMPLE + ')(?<!\.git|\.atom)'.freeze
PROJECT_REGEX_STR = PATH_REGEX_STR + '(?<!\.git|\.atom)'.freeze
def namespace_regex def namespace_regex
@namespace_regex ||= /\A#{NAMESPACE_REGEX_STR}\z/.freeze @namespace_regex ||= /\A#{NAMESPACE_REGEX_STR}\z/.freeze
...@@ -42,7 +44,15 @@ module Gitlab ...@@ -42,7 +44,15 @@ module Gitlab
end end
def project_path_regex def project_path_regex
@project_path_regex ||= /\A[a-zA-Z0-9_.][a-zA-Z0-9_\-\.]*(?<!\.git|\.atom)\z/.freeze @project_path_regex ||= /\A#{PROJECT_REGEX_STR}\z/.freeze
end
def project_route_regex
@project_route_regex ||= /#{PROJECT_REGEX_STR}/.freeze
end
def project_git_route_regex
@project_route_git_regex ||= /#{PATH_REGEX_STR}\.git/.freeze
end end
def project_path_regex_message def project_path_regex_message
......
require 'spec_helper' require 'spec_helper'
describe ApplicationController do describe ApplicationController do
let(:user) { create(:user) }
describe '#check_password_expiration' do describe '#check_password_expiration' do
let(:user) { create(:user) }
let(:controller) { ApplicationController.new } let(:controller) { ApplicationController.new }
it 'redirects if the user is over their password expiry' do it 'redirects if the user is over their password expiry' do
...@@ -39,8 +40,6 @@ describe ApplicationController do ...@@ -39,8 +40,6 @@ describe ApplicationController do
end end
end end
let(:user) { create(:user) }
context "when the 'private_token' param is populated with the private token" do context "when the 'private_token' param is populated with the private token" do
it "logs the user in" do it "logs the user in" do
get :index, private_token: user.private_token get :index, private_token: user.private_token
...@@ -73,7 +72,6 @@ describe ApplicationController do ...@@ -73,7 +72,6 @@ describe ApplicationController do
end end
end end
let(:user) { create(:user) }
let(:personal_access_token) { create(:personal_access_token, user: user) } let(:personal_access_token) { create(:personal_access_token, user: user) }
context "when the 'personal_access_token' param is populated with the personal access token" do context "when the 'personal_access_token' param is populated with the personal access token" do
...@@ -100,4 +98,21 @@ describe ApplicationController do ...@@ -100,4 +98,21 @@ describe ApplicationController do
end end
end end
end end
describe '#route_not_found' do
let(:controller) { ApplicationController.new }
it 'renders 404 if authenticated' do
allow(controller).to receive(:current_user).and_return(user)
expect(controller).to receive(:not_found)
controller.send(:route_not_found)
end
it 'does redirect to login page if not authenticated' do
allow(controller).to receive(:current_user).and_return(nil)
expect(controller).to receive(:redirect_to)
expect(controller).to receive(:new_user_session_path)
controller.send(:route_not_found)
end
end
end end
require 'spec_helper'
describe ConstrainerHelper, lib: true do
include ConstrainerHelper
describe '#extract_resource_path' do
it { expect(extract_resource_path('/gitlab/')).to eq('gitlab') }
it { expect(extract_resource_path('///gitlab//')).to eq('gitlab') }
it { expect(extract_resource_path('/gitlab.atom')).to eq('gitlab') }
context 'relative url' do
before do
allow(Gitlab::Application.config).to receive(:relative_url_root) { '/gitlab' }
end
it { expect(extract_resource_path('/gitlab/foo')).to eq('foo') }
it { expect(extract_resource_path('/foo/bar')).to eq('foo/bar') }
end
end
end
...@@ -4,16 +4,20 @@ describe GroupUrlConstrainer, lib: true do ...@@ -4,16 +4,20 @@ describe GroupUrlConstrainer, lib: true do
let!(:group) { create(:group, path: 'gitlab') } let!(:group) { create(:group, path: 'gitlab') }
describe '#matches?' do describe '#matches?' do
context 'root group' do context 'valid request' do
it { expect(subject.matches?(request '/gitlab')).to be_truthy } let(:request) { build_request(group.path) }
it { expect(subject.matches?(request '/gitlab.atom')).to be_truthy }
it { expect(subject.matches?(request '/gitlab/edit')).to be_falsey } it { expect(subject.matches?(request)).to be_truthy }
it { expect(subject.matches?(request '/gitlab-ce')).to be_falsey } end
it { expect(subject.matches?(request '/.gitlab')).to be_falsey }
context 'invalid request' do
let(:request) { build_request('foo') }
it { expect(subject.matches?(request)).to be_falsey }
end end
end end
def request(path) def build_request(path)
double(:request, path: path) double(:request, params: { id: path })
end end
end end
require 'spec_helper'
describe ProjectUrlConstrainer, lib: true do
let!(:project) { create(:project) }
let!(:namespace) { project.namespace }
describe '#matches?' do
context 'valid request' do
let(:request) { build_request(namespace.path, project.path) }
it { expect(subject.matches?(request)).to be_truthy }
end
context 'invalid request' do
context "non-existing project" do
let(:request) { build_request('foo', 'bar') }
it { expect(subject.matches?(request)).to be_falsey }
end
context "project id ending with .git" do
let(:request) { build_request(namespace.path, project.path + '.git') }
it { expect(subject.matches?(request)).to be_falsey }
end
end
end
def build_request(namespace, project)
double(:request, params: { namespace_id: namespace, id: project })
end
end
require 'spec_helper' require 'spec_helper'
describe UserUrlConstrainer, lib: true do describe UserUrlConstrainer, lib: true do
let!(:username) { create(:user, username: 'dz') } let!(:user) { create(:user, username: 'dz') }
describe '#matches?' do describe '#matches?' do
it { expect(subject.matches?(request '/dz')).to be_truthy } context 'valid request' do
it { expect(subject.matches?(request '/dz.atom')).to be_truthy } let(:request) { build_request(user.username) }
it { expect(subject.matches?(request '/dz/projects')).to be_falsey }
it { expect(subject.matches?(request '/gitlab')).to be_falsey } it { expect(subject.matches?(request)).to be_truthy }
end
context 'invalid request' do
let(:request) { build_request('foo') }
it { expect(subject.matches?(request)).to be_falsey }
end
end end
def request(path) def build_request(username)
double(:request, path: path) double(:request, params: { username: username })
end end
end end
...@@ -752,6 +752,17 @@ describe User, models: true do ...@@ -752,6 +752,17 @@ describe User, models: true do
end end
end end
describe '.find_by_username' do
it 'returns nil if not found' do
expect(described_class.find_by_username('JohnDoe')).to be_nil
end
it 'is case-insensitive' do
user = create(:user, username: 'JohnDoe')
expect(described_class.find_by_username('JOHNDOE')).to eq user
end
end
describe '.find_by_username!' do describe '.find_by_username!' do
it 'raises RecordNotFound' do it 'raises RecordNotFound' do
expect { described_class.find_by_username!('JohnDoe') }. expect { described_class.find_by_username!('JohnDoe') }.
......
require 'spec_helper' require 'spec_helper'
# Shared examples for a resource inside a Project describe 'project routing' do
# before do
# By default it tests all the default REST actions: index, create, new, edit, allow(Project).to receive(:find_with_namespace).and_return(false)
# show, update, and destroy. You can remove actions by customizing the allow(Project).to receive(:find_with_namespace).with('gitlab/gitlabhq').and_return(true)
# `actions` variable. end
#
# It also expects a `controller` variable to be available which defines both # Shared examples for a resource inside a Project
# the path to the resource as well as the controller name. #
# # By default it tests all the default REST actions: index, create, new, edit,
# Examples # show, update, and destroy. You can remove actions by customizing the
# # `actions` variable.
# # Default behavior #
# it_behaves_like 'RESTful project resources' do # It also expects a `controller` variable to be available which defines both
# let(:controller) { 'issues' } # the path to the resource as well as the controller name.
# end #
# # Examples
# # Customizing actions #
# it_behaves_like 'RESTful project resources' do # # Default behavior
# let(:actions) { [:index] } # it_behaves_like 'RESTful project resources' do
# let(:controller) { 'issues' } # let(:controller) { 'issues' }
# end # end
shared_examples 'RESTful project resources' do #
let(:actions) { [:index, :create, :new, :edit, :show, :update, :destroy] } # # Customizing actions
# it_behaves_like 'RESTful project resources' do
it 'to #index' do # let(:actions) { [:index] }
expect(get("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#index", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:index) # let(:controller) { 'issues' }
end # end
shared_examples 'RESTful project resources' do
it 'to #create' do let(:actions) { [:index, :create, :new, :edit, :show, :update, :destroy] }
expect(post("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#create", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:create)
end it 'to #index' do
expect(get("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#index", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:index)
it 'to #new' do end
expect(get("/gitlab/gitlabhq/#{controller}/new")).to route_to("projects/#{controller}#new", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:new)
end it 'to #create' do
expect(post("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#create", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:create)
it 'to #edit' do end
expect(get("/gitlab/gitlabhq/#{controller}/1/edit")).to route_to("projects/#{controller}#edit", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:edit)
end it 'to #new' do
expect(get("/gitlab/gitlabhq/#{controller}/new")).to route_to("projects/#{controller}#new", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:new)
it 'to #show' do end
expect(get("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#show", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:show)
end it 'to #edit' do
expect(get("/gitlab/gitlabhq/#{controller}/1/edit")).to route_to("projects/#{controller}#edit", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:edit)
it 'to #update' do end
expect(put("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#update", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:update)
end it 'to #show' do
expect(get("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#show", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:show)
it 'to #destroy' do end
expect(delete("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#destroy", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:destroy)
end it 'to #update' do
end expect(put("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#update", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:update)
end
# projects POST /projects(.:format) projects#create
# new_project GET /projects/new(.:format) projects#new it 'to #destroy' do
# files_project GET /:id/files(.:format) projects#files expect(delete("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#destroy", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:destroy)
# edit_project GET /:id/edit(.:format) projects#edit end
# project GET /:id(.:format) projects#show end
# PUT /:id(.:format) projects#update
# DELETE /:id(.:format) projects#destroy # projects POST /projects(.:format) projects#create
# preview_markdown_project POST /:id/preview_markdown(.:format) projects#preview_markdown # new_project GET /projects/new(.:format) projects#new
describe ProjectsController, 'routing' do # files_project GET /:id/files(.:format) projects#files
it 'to #create' do # edit_project GET /:id/edit(.:format) projects#edit
expect(post('/projects')).to route_to('projects#create') # project GET /:id(.:format) projects#show
end # PUT /:id(.:format) projects#update
# DELETE /:id(.:format) projects#destroy
it 'to #new' do # preview_markdown_project POST /:id/preview_markdown(.:format) projects#preview_markdown
expect(get('/projects/new')).to route_to('projects#new') describe ProjectsController, 'routing' do
end it 'to #create' do
expect(post('/projects')).to route_to('projects#create')
it 'to #edit' do end
expect(get('/gitlab/gitlabhq/edit')).to route_to('projects#edit', namespace_id: 'gitlab', id: 'gitlabhq')
end it 'to #new' do
expect(get('/projects/new')).to route_to('projects#new')
it 'to #autocomplete_sources' do end
expect(get('/gitlab/gitlabhq/autocomplete_sources')).to route_to('projects#autocomplete_sources', namespace_id: 'gitlab', id: 'gitlabhq')
end it 'to #edit' do
expect(get('/gitlab/gitlabhq/edit')).to route_to('projects#edit', namespace_id: 'gitlab', id: 'gitlabhq')
it 'to #show' do end
expect(get('/gitlab/gitlabhq')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq')
expect(get('/gitlab/gitlabhq.keys')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq.keys') it 'to #autocomplete_sources' do
end expect(get('/gitlab/gitlabhq/autocomplete_sources')).to route_to('projects#autocomplete_sources', namespace_id: 'gitlab', id: 'gitlabhq')
end
it 'to #update' do
expect(put('/gitlab/gitlabhq')).to route_to('projects#update', namespace_id: 'gitlab', id: 'gitlabhq') describe 'to #show' do
end context 'regular name' do
it { expect(get('/gitlab/gitlabhq')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq') }
it 'to #destroy' do end
expect(delete('/gitlab/gitlabhq')).to route_to('projects#destroy', namespace_id: 'gitlab', id: 'gitlabhq')
end context 'name with dot' do
before { allow(Project).to receive(:find_with_namespace).with('gitlab/gitlabhq.keys').and_return(true) }
it 'to #preview_markdown' do
expect(post('/gitlab/gitlabhq/preview_markdown')).to( it { expect(get('/gitlab/gitlabhq.keys')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq.keys') }
route_to('projects#preview_markdown', namespace_id: 'gitlab', id: 'gitlabhq') end
)
end context 'with nested group' do
end before { allow(Project).to receive(:find_with_namespace).with('gitlab/subgroup/gitlabhq').and_return(true) }
# pages_project_wikis GET /:project_id/wikis/pages(.:format) projects/wikis#pages it { expect(get('/gitlab/subgroup/gitlabhq')).to route_to('projects#show', namespace_id: 'gitlab/subgroup', id: 'gitlabhq') }
# history_project_wiki GET /:project_id/wikis/:id/history(.:format) projects/wikis#history end
# project_wikis POST /:project_id/wikis(.:format) projects/wikis#create end
# edit_project_wiki GET /:project_id/wikis/:id/edit(.:format) projects/wikis#edit
# project_wiki GET /:project_id/wikis/:id(.:format) projects/wikis#show it 'to #update' do
# DELETE /:project_id/wikis/:id(.:format) projects/wikis#destroy expect(put('/gitlab/gitlabhq')).to route_to('projects#update', namespace_id: 'gitlab', id: 'gitlabhq')
describe Projects::WikisController, 'routing' do end
it 'to #pages' do
expect(get('/gitlab/gitlabhq/wikis/pages')).to route_to('projects/wikis#pages', namespace_id: 'gitlab', project_id: 'gitlabhq') it 'to #destroy' do
end expect(delete('/gitlab/gitlabhq')).to route_to('projects#destroy', namespace_id: 'gitlab', id: 'gitlabhq')
end
it 'to #history' do
expect(get('/gitlab/gitlabhq/wikis/1/history')).to route_to('projects/wikis#history', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') it 'to #preview_markdown' do
end expect(post('/gitlab/gitlabhq/preview_markdown')).to(
route_to('projects#preview_markdown', namespace_id: 'gitlab', id: 'gitlabhq')
it_behaves_like 'RESTful project resources' do )
let(:actions) { [:create, :edit, :show, :destroy] } end
let(:controller) { 'wikis' } end
end
end # pages_project_wikis GET /:project_id/wikis/pages(.:format) projects/wikis#pages
# history_project_wiki GET /:project_id/wikis/:id/history(.:format) projects/wikis#history
# branches_project_repository GET /:project_id/repository/branches(.:format) projects/repositories#branches # project_wikis POST /:project_id/wikis(.:format) projects/wikis#create
# tags_project_repository GET /:project_id/repository/tags(.:format) projects/repositories#tags # edit_project_wiki GET /:project_id/wikis/:id/edit(.:format) projects/wikis#edit
# archive_project_repository GET /:project_id/repository/archive(.:format) projects/repositories#archive # project_wiki GET /:project_id/wikis/:id(.:format) projects/wikis#show
# edit_project_repository GET /:project_id/repository/edit(.:format) projects/repositories#edit # DELETE /:project_id/wikis/:id(.:format) projects/wikis#destroy
describe Projects::RepositoriesController, 'routing' do describe Projects::WikisController, 'routing' do
it 'to #archive' do it 'to #pages' do
expect(get('/gitlab/gitlabhq/repository/archive')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq') expect(get('/gitlab/gitlabhq/wikis/pages')).to route_to('projects/wikis#pages', namespace_id: 'gitlab', project_id: 'gitlabhq')
end end
it 'to #archive format:zip' do it 'to #history' do
expect(get('/gitlab/gitlabhq/repository/archive.zip')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'zip') expect(get('/gitlab/gitlabhq/wikis/1/history')).to route_to('projects/wikis#history', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end end
it 'to #archive format:tar.bz2' do it_behaves_like 'RESTful project resources' do
expect(get('/gitlab/gitlabhq/repository/archive.tar.bz2')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'tar.bz2') let(:actions) { [:create, :edit, :show, :destroy] }
end let(:controller) { 'wikis' }
end end
end
describe Projects::BranchesController, 'routing' do
it 'to #branches' do # branches_project_repository GET /:project_id/repository/branches(.:format) projects/repositories#branches
expect(get('/gitlab/gitlabhq/branches')).to route_to('projects/branches#index', namespace_id: 'gitlab', project_id: 'gitlabhq') # tags_project_repository GET /:project_id/repository/tags(.:format) projects/repositories#tags
expect(delete('/gitlab/gitlabhq/branches/feature%2345')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45') # archive_project_repository GET /:project_id/repository/archive(.:format) projects/repositories#archive
expect(delete('/gitlab/gitlabhq/branches/feature%2B45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45') # edit_project_repository GET /:project_id/repository/edit(.:format) projects/repositories#edit
expect(delete('/gitlab/gitlabhq/branches/feature@45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45') describe Projects::RepositoriesController, 'routing' do
expect(delete('/gitlab/gitlabhq/branches/feature%2345/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz') it 'to #archive' do
expect(delete('/gitlab/gitlabhq/branches/feature%2B45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz') expect(get('/gitlab/gitlabhq/repository/archive')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq')
expect(delete('/gitlab/gitlabhq/branches/feature@45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz') end
end
end it 'to #archive format:zip' do
expect(get('/gitlab/gitlabhq/repository/archive.zip')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'zip')
describe Projects::TagsController, 'routing' do end
it 'to #tags' do
expect(get('/gitlab/gitlabhq/tags')).to route_to('projects/tags#index', namespace_id: 'gitlab', project_id: 'gitlabhq') it 'to #archive format:tar.bz2' do
expect(delete('/gitlab/gitlabhq/tags/feature%2345')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45') expect(get('/gitlab/gitlabhq/repository/archive.tar.bz2')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'tar.bz2')
expect(delete('/gitlab/gitlabhq/tags/feature%2B45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45') end
expect(delete('/gitlab/gitlabhq/tags/feature@45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45') end
expect(delete('/gitlab/gitlabhq/tags/feature%2345/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz')
expect(delete('/gitlab/gitlabhq/tags/feature%2B45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz') describe Projects::BranchesController, 'routing' do
expect(delete('/gitlab/gitlabhq/tags/feature@45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz') it 'to #branches' do
end expect(get('/gitlab/gitlabhq/branches')).to route_to('projects/branches#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
end expect(delete('/gitlab/gitlabhq/branches/feature%2345')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45')
expect(delete('/gitlab/gitlabhq/branches/feature%2B45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45')
# project_deploy_keys GET /:project_id/deploy_keys(.:format) deploy_keys#index expect(delete('/gitlab/gitlabhq/branches/feature@45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45')
# POST /:project_id/deploy_keys(.:format) deploy_keys#create expect(delete('/gitlab/gitlabhq/branches/feature%2345/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz')
# new_project_deploy_key GET /:project_id/deploy_keys/new(.:format) deploy_keys#new expect(delete('/gitlab/gitlabhq/branches/feature%2B45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz')
# project_deploy_key GET /:project_id/deploy_keys/:id(.:format) deploy_keys#show expect(delete('/gitlab/gitlabhq/branches/feature@45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz')
# DELETE /:project_id/deploy_keys/:id(.:format) deploy_keys#destroy end
describe Projects::DeployKeysController, 'routing' do end
it_behaves_like 'RESTful project resources' do
let(:actions) { [:index, :new, :create] } describe Projects::TagsController, 'routing' do
let(:controller) { 'deploy_keys' } it 'to #tags' do
end expect(get('/gitlab/gitlabhq/tags')).to route_to('projects/tags#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
end expect(delete('/gitlab/gitlabhq/tags/feature%2345')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45')
expect(delete('/gitlab/gitlabhq/tags/feature%2B45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45')
# project_protected_branches GET /:project_id/protected_branches(.:format) protected_branches#index expect(delete('/gitlab/gitlabhq/tags/feature@45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45')
# POST /:project_id/protected_branches(.:format) protected_branches#create expect(delete('/gitlab/gitlabhq/tags/feature%2345/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz')
# project_protected_branch DELETE /:project_id/protected_branches/:id(.:format) protected_branches#destroy expect(delete('/gitlab/gitlabhq/tags/feature%2B45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz')
describe Projects::ProtectedBranchesController, 'routing' do expect(delete('/gitlab/gitlabhq/tags/feature@45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz')
it_behaves_like 'RESTful project resources' do end
let(:actions) { [:index, :create, :destroy] } end
let(:controller) { 'protected_branches' }
end # project_deploy_keys GET /:project_id/deploy_keys(.:format) deploy_keys#index
end # POST /:project_id/deploy_keys(.:format) deploy_keys#create
# new_project_deploy_key GET /:project_id/deploy_keys/new(.:format) deploy_keys#new
# switch_project_refs GET /:project_id/refs/switch(.:format) refs#switch # project_deploy_key GET /:project_id/deploy_keys/:id(.:format) deploy_keys#show
# logs_tree_project_ref GET /:project_id/refs/:id/logs_tree(.:format) refs#logs_tree # DELETE /:project_id/deploy_keys/:id(.:format) deploy_keys#destroy
# logs_file_project_ref GET /:project_id/refs/:id/logs_tree/:path(.:format) refs#logs_tree describe Projects::DeployKeysController, 'routing' do
describe Projects::RefsController, 'routing' do it_behaves_like 'RESTful project resources' do
it 'to #switch' do let(:actions) { [:index, :new, :create] }
expect(get('/gitlab/gitlabhq/refs/switch')).to route_to('projects/refs#switch', namespace_id: 'gitlab', project_id: 'gitlabhq') let(:controller) { 'deploy_keys' }
end end
end
it 'to #logs_tree' do
expect(get('/gitlab/gitlabhq/refs/stable/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable') # project_protected_branches GET /:project_id/protected_branches(.:format) protected_branches#index
expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45') # POST /:project_id/protected_branches(.:format) protected_branches#create
expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45') # project_protected_branch DELETE /:project_id/protected_branches/:id(.:format) protected_branches#destroy
expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45') describe Projects::ProtectedBranchesController, 'routing' do
expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'foo/bar/baz') it_behaves_like 'RESTful project resources' do
expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45', path: 'foo/bar/baz') let(:actions) { [:index, :create, :destroy] }
expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45', path: 'foo/bar/baz') let(:controller) { 'protected_branches' }
expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45', path: 'foo/bar/baz') end
expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/files.scss')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'files.scss') end
end
end # switch_project_refs GET /:project_id/refs/switch(.:format) refs#switch
# logs_tree_project_ref GET /:project_id/refs/:id/logs_tree(.:format) refs#logs_tree
# diffs_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/diffs(.:format) projects/merge_requests#diffs # logs_file_project_ref GET /:project_id/refs/:id/logs_tree/:path(.:format) refs#logs_tree
# commits_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/commits(.:format) projects/merge_requests#commits describe Projects::RefsController, 'routing' do
# merge_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/merge(.:format) projects/merge_requests#merge it 'to #switch' do
# merge_check_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/merge_check(.:format) projects/merge_requests#merge_check expect(get('/gitlab/gitlabhq/refs/switch')).to route_to('projects/refs#switch', namespace_id: 'gitlab', project_id: 'gitlabhq')
# ci_status_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/ci_status(.:format) projects/merge_requests#ci_status end
# toggle_subscription_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/toggle_subscription(.:format) projects/merge_requests#toggle_subscription
# branch_from_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_from(.:format) projects/merge_requests#branch_from it 'to #logs_tree' do
# branch_to_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_to(.:format) projects/merge_requests#branch_to expect(get('/gitlab/gitlabhq/refs/stable/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable')
# update_branches_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/update_branches(.:format) projects/merge_requests#update_branches expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45')
# namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#index expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45')
# POST /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#create expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45')
# new_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/new(.:format) projects/merge_requests#new expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'foo/bar/baz')
# edit_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/edit(.:format) projects/merge_requests#edit expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45', path: 'foo/bar/baz')
# namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#show expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45', path: 'foo/bar/baz')
# PATCH /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45', path: 'foo/bar/baz')
# PUT /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/files.scss')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'files.scss')
describe Projects::MergeRequestsController, 'routing' do end
it 'to #diffs' do end
expect(get('/gitlab/gitlabhq/merge_requests/1/diffs')).to route_to('projects/merge_requests#diffs', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end # diffs_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/diffs(.:format) projects/merge_requests#diffs
# commits_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/commits(.:format) projects/merge_requests#commits
it 'to #commits' do # merge_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/merge(.:format) projects/merge_requests#merge
expect(get('/gitlab/gitlabhq/merge_requests/1/commits')).to route_to('projects/merge_requests#commits', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') # merge_check_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/merge_check(.:format) projects/merge_requests#merge_check
end # ci_status_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/ci_status(.:format) projects/merge_requests#ci_status
# toggle_subscription_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/toggle_subscription(.:format) projects/merge_requests#toggle_subscription
it 'to #merge' do # branch_from_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_from(.:format) projects/merge_requests#branch_from
expect(post('/gitlab/gitlabhq/merge_requests/1/merge')).to route_to( # branch_to_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_to(.:format) projects/merge_requests#branch_to
'projects/merge_requests#merge', # update_branches_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/update_branches(.:format) projects/merge_requests#update_branches
namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1' # namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#index
) # POST /:namespace_id/:project_id/merge_requests(.:format) projects/merge_requests#create
end # new_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/new(.:format) projects/merge_requests#new
# edit_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/edit(.:format) projects/merge_requests#edit
it 'to #merge_check' do # namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#show
expect(get('/gitlab/gitlabhq/merge_requests/1/merge_check')).to route_to('projects/merge_requests#merge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') # PATCH /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update
end # PUT /:namespace_id/:project_id/merge_requests/:id(.:format) projects/merge_requests#update
describe Projects::MergeRequestsController, 'routing' do
it 'to #branch_from' do it 'to #diffs' do
expect(get('/gitlab/gitlabhq/merge_requests/branch_from')).to route_to('projects/merge_requests#branch_from', namespace_id: 'gitlab', project_id: 'gitlabhq') expect(get('/gitlab/gitlabhq/merge_requests/1/diffs')).to route_to('projects/merge_requests#diffs', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end end
it 'to #branch_to' do it 'to #commits' do
expect(get('/gitlab/gitlabhq/merge_requests/branch_to')).to route_to('projects/merge_requests#branch_to', namespace_id: 'gitlab', project_id: 'gitlabhq') expect(get('/gitlab/gitlabhq/merge_requests/1/commits')).to route_to('projects/merge_requests#commits', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end end
it 'to #show' do it 'to #merge' do
expect(get('/gitlab/gitlabhq/merge_requests/1.diff')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'diff') expect(post('/gitlab/gitlabhq/merge_requests/1/merge')).to route_to(
expect(get('/gitlab/gitlabhq/merge_requests/1.patch')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'patch') 'projects/merge_requests#merge',
end namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1'
)
it_behaves_like 'RESTful project resources' do end
let(:controller) { 'merge_requests' }
let(:actions) { [:index, :create, :new, :edit, :show, :update] } it 'to #merge_check' do
end expect(get('/gitlab/gitlabhq/merge_requests/1/merge_check')).to route_to('projects/merge_requests#merge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end end
# raw_project_snippet GET /:project_id/snippets/:id/raw(.:format) snippets#raw it 'to #branch_from' do
# project_snippets GET /:project_id/snippets(.:format) snippets#index expect(get('/gitlab/gitlabhq/merge_requests/branch_from')).to route_to('projects/merge_requests#branch_from', namespace_id: 'gitlab', project_id: 'gitlabhq')
# POST /:project_id/snippets(.:format) snippets#create end
# new_project_snippet GET /:project_id/snippets/new(.:format) snippets#new
# edit_project_snippet GET /:project_id/snippets/:id/edit(.:format) snippets#edit it 'to #branch_to' do
# project_snippet GET /:project_id/snippets/:id(.:format) snippets#show expect(get('/gitlab/gitlabhq/merge_requests/branch_to')).to route_to('projects/merge_requests#branch_to', namespace_id: 'gitlab', project_id: 'gitlabhq')
# PUT /:project_id/snippets/:id(.:format) snippets#update end
# DELETE /:project_id/snippets/:id(.:format) snippets#destroy
describe SnippetsController, 'routing' do it 'to #show' do
it 'to #raw' do expect(get('/gitlab/gitlabhq/merge_requests/1.diff')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'diff')
expect(get('/gitlab/gitlabhq/snippets/1/raw')).to route_to('projects/snippets#raw', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') expect(get('/gitlab/gitlabhq/merge_requests/1.patch')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'patch')
end end
it 'to #index' do it_behaves_like 'RESTful project resources' do
expect(get('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#index', namespace_id: 'gitlab', project_id: 'gitlabhq') let(:controller) { 'merge_requests' }
end let(:actions) { [:index, :create, :new, :edit, :show, :update] }
end
it 'to #create' do end
expect(post('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
end # raw_project_snippet GET /:project_id/snippets/:id/raw(.:format) snippets#raw
# project_snippets GET /:project_id/snippets(.:format) snippets#index
it 'to #new' do # POST /:project_id/snippets(.:format) snippets#create
expect(get('/gitlab/gitlabhq/snippets/new')).to route_to('projects/snippets#new', namespace_id: 'gitlab', project_id: 'gitlabhq') # new_project_snippet GET /:project_id/snippets/new(.:format) snippets#new
end # edit_project_snippet GET /:project_id/snippets/:id/edit(.:format) snippets#edit
# project_snippet GET /:project_id/snippets/:id(.:format) snippets#show
it 'to #edit' do # PUT /:project_id/snippets/:id(.:format) snippets#update
expect(get('/gitlab/gitlabhq/snippets/1/edit')).to route_to('projects/snippets#edit', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') # DELETE /:project_id/snippets/:id(.:format) snippets#destroy
end describe SnippetsController, 'routing' do
it 'to #raw' do
it 'to #show' do expect(get('/gitlab/gitlabhq/snippets/1/raw')).to route_to('projects/snippets#raw', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
expect(get('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') end
end
it 'to #index' do
it 'to #update' do expect(get('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
expect(put('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#update', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') end
end
it 'to #create' do
it 'to #destroy' do expect(post('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
expect(delete('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') end
end
end it 'to #new' do
expect(get('/gitlab/gitlabhq/snippets/new')).to route_to('projects/snippets#new', namespace_id: 'gitlab', project_id: 'gitlabhq')
# test_project_hook GET /:project_id/hooks/:id/test(.:format) hooks#test end
# project_hooks GET /:project_id/hooks(.:format) hooks#index
# POST /:project_id/hooks(.:format) hooks#create it 'to #edit' do
# project_hook DELETE /:project_id/hooks/:id(.:format) hooks#destroy expect(get('/gitlab/gitlabhq/snippets/1/edit')).to route_to('projects/snippets#edit', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
describe Projects::HooksController, 'routing' do end
it 'to #test' do
expect(get('/gitlab/gitlabhq/hooks/1/test')).to route_to('projects/hooks#test', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') it 'to #show' do
end expect(get('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end
it_behaves_like 'RESTful project resources' do
let(:actions) { [:index, :create, :destroy] } it 'to #update' do
let(:controller) { 'hooks' } expect(put('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#update', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end end
end
it 'to #destroy' do
# project_commit GET /:project_id/commit/:id(.:format) commit#show {id: /\h{7,40}/, project_id: /[^\/]+/} expect(delete('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
describe Projects::CommitController, 'routing' do end
it 'to #show' do end
expect(get('/gitlab/gitlabhq/commit/4246fbd')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd')
expect(get('/gitlab/gitlabhq/commit/4246fbd.diff')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd', format: 'diff') # test_project_hook GET /:project_id/hooks/:id/test(.:format) hooks#test
expect(get('/gitlab/gitlabhq/commit/4246fbd.patch')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd', format: 'patch') # project_hooks GET /:project_id/hooks(.:format) hooks#index
expect(get('/gitlab/gitlabhq/commit/4246fbd13872934f72a8fd0d6fb1317b47b59cb5')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd13872934f72a8fd0d6fb1317b47b59cb5') # POST /:project_id/hooks(.:format) hooks#create
end # project_hook DELETE /:project_id/hooks/:id(.:format) hooks#destroy
end describe Projects::HooksController, 'routing' do
it 'to #test' do
# patch_project_commit GET /:project_id/commits/:id/patch(.:format) commits#patch expect(get('/gitlab/gitlabhq/hooks/1/test')).to route_to('projects/hooks#test', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
# project_commits GET /:project_id/commits(.:format) commits#index end
# POST /:project_id/commits(.:format) commits#create
# project_commit GET /:project_id/commits/:id(.:format) commits#show it_behaves_like 'RESTful project resources' do
describe Projects::CommitsController, 'routing' do let(:actions) { [:index, :create, :destroy] }
it_behaves_like 'RESTful project resources' do let(:controller) { 'hooks' }
let(:actions) { [:show] } end
let(:controller) { 'commits' } end
end
# project_commit GET /:project_id/commit/:id(.:format) commit#show {id: /\h{7,40}/, project_id: /[^\/]+/}
it 'to #show' do describe Projects::CommitController, 'routing' do
expect(get('/gitlab/gitlabhq/commits/master.atom')).to route_to('projects/commits#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master.atom') it 'to #show' do
end expect(get('/gitlab/gitlabhq/commit/4246fbd')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd')
end expect(get('/gitlab/gitlabhq/commit/4246fbd.diff')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd', format: 'diff')
expect(get('/gitlab/gitlabhq/commit/4246fbd.patch')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd', format: 'patch')
# project_project_members GET /:project_id/project_members(.:format) project_members#index expect(get('/gitlab/gitlabhq/commit/4246fbd13872934f72a8fd0d6fb1317b47b59cb5')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd13872934f72a8fd0d6fb1317b47b59cb5')
# POST /:project_id/project_members(.:format) project_members#create end
# PUT /:project_id/project_members/:id(.:format) project_members#update end
# DELETE /:project_id/project_members/:id(.:format) project_members#destroy
describe Projects::ProjectMembersController, 'routing' do # patch_project_commit GET /:project_id/commits/:id/patch(.:format) commits#patch
it_behaves_like 'RESTful project resources' do # project_commits GET /:project_id/commits(.:format) commits#index
let(:actions) { [:index, :create, :update, :destroy] } # POST /:project_id/commits(.:format) commits#create
let(:controller) { 'project_members' } # project_commit GET /:project_id/commits/:id(.:format) commits#show
end describe Projects::CommitsController, 'routing' do
end it_behaves_like 'RESTful project resources' do
let(:actions) { [:show] }
# project_milestones GET /:project_id/milestones(.:format) milestones#index let(:controller) { 'commits' }
# POST /:project_id/milestones(.:format) milestones#create end
# new_project_milestone GET /:project_id/milestones/new(.:format) milestones#new
# edit_project_milestone GET /:project_id/milestones/:id/edit(.:format) milestones#edit it 'to #show' do
# project_milestone GET /:project_id/milestones/:id(.:format) milestones#show expect(get('/gitlab/gitlabhq/commits/master.atom')).to route_to('projects/commits#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master.atom')
# PUT /:project_id/milestones/:id(.:format) milestones#update end
# DELETE /:project_id/milestones/:id(.:format) milestones#destroy end
describe Projects::MilestonesController, 'routing' do
it_behaves_like 'RESTful project resources' do # project_project_members GET /:project_id/project_members(.:format) project_members#index
let(:controller) { 'milestones' } # POST /:project_id/project_members(.:format) project_members#create
let(:actions) { [:index, :create, :new, :edit, :show, :update] } # PUT /:project_id/project_members/:id(.:format) project_members#update
end # DELETE /:project_id/project_members/:id(.:format) project_members#destroy
end describe Projects::ProjectMembersController, 'routing' do
it_behaves_like 'RESTful project resources' do
# project_labels GET /:project_id/labels(.:format) labels#index let(:actions) { [:index, :create, :update, :destroy] }
describe Projects::LabelsController, 'routing' do let(:controller) { 'project_members' }
it 'to #index' do end
expect(get('/gitlab/gitlabhq/labels')).to route_to('projects/labels#index', namespace_id: 'gitlab', project_id: 'gitlabhq') end
end
end # project_milestones GET /:project_id/milestones(.:format) milestones#index
# POST /:project_id/milestones(.:format) milestones#create
# sort_project_issues POST /:project_id/issues/sort(.:format) issues#sort # new_project_milestone GET /:project_id/milestones/new(.:format) milestones#new
# bulk_update_project_issues POST /:project_id/issues/bulk_update(.:format) issues#bulk_update # edit_project_milestone GET /:project_id/milestones/:id/edit(.:format) milestones#edit
# search_project_issues GET /:project_id/issues/search(.:format) issues#search # project_milestone GET /:project_id/milestones/:id(.:format) milestones#show
# project_issues GET /:project_id/issues(.:format) issues#index # PUT /:project_id/milestones/:id(.:format) milestones#update
# POST /:project_id/issues(.:format) issues#create # DELETE /:project_id/milestones/:id(.:format) milestones#destroy
# new_project_issue GET /:project_id/issues/new(.:format) issues#new describe Projects::MilestonesController, 'routing' do
# edit_project_issue GET /:project_id/issues/:id/edit(.:format) issues#edit it_behaves_like 'RESTful project resources' do
# project_issue GET /:project_id/issues/:id(.:format) issues#show let(:controller) { 'milestones' }
# PUT /:project_id/issues/:id(.:format) issues#update let(:actions) { [:index, :create, :new, :edit, :show, :update] }
# DELETE /:project_id/issues/:id(.:format) issues#destroy end
describe Projects::IssuesController, 'routing' do end
it 'to #bulk_update' do
expect(post('/gitlab/gitlabhq/issues/bulk_update')).to route_to('projects/issues#bulk_update', namespace_id: 'gitlab', project_id: 'gitlabhq') # project_labels GET /:project_id/labels(.:format) labels#index
end describe Projects::LabelsController, 'routing' do
it 'to #index' do
it_behaves_like 'RESTful project resources' do expect(get('/gitlab/gitlabhq/labels')).to route_to('projects/labels#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
let(:controller) { 'issues' } end
let(:actions) { [:index, :create, :new, :edit, :show, :update] } end
end
end # sort_project_issues POST /:project_id/issues/sort(.:format) issues#sort
# bulk_update_project_issues POST /:project_id/issues/bulk_update(.:format) issues#bulk_update
# project_notes GET /:project_id/notes(.:format) notes#index # search_project_issues GET /:project_id/issues/search(.:format) issues#search
# POST /:project_id/notes(.:format) notes#create # project_issues GET /:project_id/issues(.:format) issues#index
# project_note DELETE /:project_id/notes/:id(.:format) notes#destroy # POST /:project_id/issues(.:format) issues#create
describe Projects::NotesController, 'routing' do # new_project_issue GET /:project_id/issues/new(.:format) issues#new
it_behaves_like 'RESTful project resources' do # edit_project_issue GET /:project_id/issues/:id/edit(.:format) issues#edit
let(:actions) { [:index, :create, :destroy] } # project_issue GET /:project_id/issues/:id(.:format) issues#show
let(:controller) { 'notes' } # PUT /:project_id/issues/:id(.:format) issues#update
end # DELETE /:project_id/issues/:id(.:format) issues#destroy
end describe Projects::IssuesController, 'routing' do
it 'to #bulk_update' do
# project_blame GET /:project_id/blame/:id(.:format) blame#show {id: /.+/, project_id: /[^\/]+/} expect(post('/gitlab/gitlabhq/issues/bulk_update')).to route_to('projects/issues#bulk_update', namespace_id: 'gitlab', project_id: 'gitlabhq')
describe Projects::BlameController, 'routing' do end
it 'to #show' do
expect(get('/gitlab/gitlabhq/blame/master/app/models/project.rb')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb') it_behaves_like 'RESTful project resources' do
expect(get('/gitlab/gitlabhq/blame/master/files.scss')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss') let(:controller) { 'issues' }
end let(:actions) { [:index, :create, :new, :edit, :show, :update] }
end end
end
# project_blob GET /:project_id/blob/:id(.:format) blob#show {id: /.+/, project_id: /[^\/]+/}
describe Projects::BlobController, 'routing' do # project_notes GET /:project_id/notes(.:format) notes#index
it 'to #show' do # POST /:project_id/notes(.:format) notes#create
expect(get('/gitlab/gitlabhq/blob/master/app/models/project.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb') # project_note DELETE /:project_id/notes/:id(.:format) notes#destroy
expect(get('/gitlab/gitlabhq/blob/master/app/models/compare.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/compare.rb') describe Projects::NotesController, 'routing' do
expect(get('/gitlab/gitlabhq/blob/master/app/models/diff.js')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/diff.js') it_behaves_like 'RESTful project resources' do
expect(get('/gitlab/gitlabhq/blob/master/files.scss')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss') let(:actions) { [:index, :create, :destroy] }
end let(:controller) { 'notes' }
end end
end
# project_tree GET /:project_id/tree/:id(.:format) tree#show {id: /.+/, project_id: /[^\/]+/}
describe Projects::TreeController, 'routing' do # project_blame GET /:project_id/blame/:id(.:format) blame#show {id: /.+/, project_id: /[^\/]+/}
it 'to #show' do describe Projects::BlameController, 'routing' do
expect(get('/gitlab/gitlabhq/tree/master/app/models/project.rb')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb') it 'to #show' do
expect(get('/gitlab/gitlabhq/tree/master/files.scss')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss') expect(get('/gitlab/gitlabhq/blame/master/app/models/project.rb')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
end expect(get('/gitlab/gitlabhq/blame/master/files.scss')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss')
end end
end
# project_find_file GET /:namespace_id/:project_id/find_file/*id(.:format) projects/find_file#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/html/}
# project_files GET /:namespace_id/:project_id/files/*id(.:format) projects/find_file#list {:id=>/(?:[^.]|\.(?!json$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/json/} # project_blob GET /:project_id/blob/:id(.:format) blob#show {id: /.+/, project_id: /[^\/]+/}
describe Projects::FindFileController, 'routing' do describe Projects::BlobController, 'routing' do
it 'to #show' do it 'to #show' do
expect(get('/gitlab/gitlabhq/find_file/master')).to route_to('projects/find_file#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master') expect(get('/gitlab/gitlabhq/blob/master/app/models/project.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
end expect(get('/gitlab/gitlabhq/blob/master/app/models/compare.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/compare.rb')
expect(get('/gitlab/gitlabhq/blob/master/app/models/diff.js')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/diff.js')
it 'to #list' do expect(get('/gitlab/gitlabhq/blob/master/files.scss')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss')
expect(get('/gitlab/gitlabhq/files/master.json')).to route_to('projects/find_file#list', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json') end
end end
end
# project_tree GET /:project_id/tree/:id(.:format) tree#show {id: /.+/, project_id: /[^\/]+/}
describe Projects::BlobController, 'routing' do describe Projects::TreeController, 'routing' do
it 'to #edit' do it 'to #show' do
expect(get('/gitlab/gitlabhq/edit/master/app/models/project.rb')).to( expect(get('/gitlab/gitlabhq/tree/master/app/models/project.rb')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
route_to('projects/blob#edit', expect(get('/gitlab/gitlabhq/tree/master/files.scss')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss')
namespace_id: 'gitlab', project_id: 'gitlabhq', end
id: 'master/app/models/project.rb')) end
end
# project_find_file GET /:namespace_id/:project_id/find_file/*id(.:format) projects/find_file#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/html/}
it 'to #preview' do # project_files GET /:namespace_id/:project_id/files/*id(.:format) projects/find_file#list {:id=>/(?:[^.]|\.(?!json$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/json/}
expect(post('/gitlab/gitlabhq/preview/master/app/models/project.rb')).to( describe Projects::FindFileController, 'routing' do
route_to('projects/blob#preview', it 'to #show' do
namespace_id: 'gitlab', project_id: 'gitlabhq', expect(get('/gitlab/gitlabhq/find_file/master')).to route_to('projects/find_file#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
id: 'master/app/models/project.rb')) end
end
end it 'to #list' do
expect(get('/gitlab/gitlabhq/files/master.json')).to route_to('projects/find_file#list', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
# project_compare_index GET /:project_id/compare(.:format) compare#index {id: /[^\/]+/, project_id: /[^\/]+/} end
# POST /:project_id/compare(.:format) compare#create {id: /[^\/]+/, project_id: /[^\/]+/} end
# project_compare /:project_id/compare/:from...:to(.:format) compare#show {from: /.+/, to: /.+/, id: /[^\/]+/, project_id: /[^\/]+/}
describe Projects::CompareController, 'routing' do describe Projects::BlobController, 'routing' do
it 'to #index' do it 'to #edit' do
expect(get('/gitlab/gitlabhq/compare')).to route_to('projects/compare#index', namespace_id: 'gitlab', project_id: 'gitlabhq') expect(get('/gitlab/gitlabhq/edit/master/app/models/project.rb')).to(
end route_to('projects/blob#edit',
namespace_id: 'gitlab', project_id: 'gitlabhq',
it 'to #compare' do id: 'master/app/models/project.rb'))
expect(post('/gitlab/gitlabhq/compare')).to route_to('projects/compare#create', namespace_id: 'gitlab', project_id: 'gitlabhq') end
end
it 'to #preview' do
it 'to #show' do expect(post('/gitlab/gitlabhq/preview/master/app/models/project.rb')).to(
expect(get('/gitlab/gitlabhq/compare/master...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'master', to: 'stable') route_to('projects/blob#preview',
expect(get('/gitlab/gitlabhq/compare/issue/1234...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'issue/1234', to: 'stable') namespace_id: 'gitlab', project_id: 'gitlabhq',
end id: 'master/app/models/project.rb'))
end end
end
describe Projects::NetworkController, 'routing' do
it 'to #show' do # project_compare_index GET /:project_id/compare(.:format) compare#index {id: /[^\/]+/, project_id: /[^\/]+/}
expect(get('/gitlab/gitlabhq/network/master')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master') # POST /:project_id/compare(.:format) compare#create {id: /[^\/]+/, project_id: /[^\/]+/}
expect(get('/gitlab/gitlabhq/network/ends-with.json')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'ends-with.json') # project_compare /:project_id/compare/:from...:to(.:format) compare#show {from: /.+/, to: /.+/, id: /[^\/]+/, project_id: /[^\/]+/}
expect(get('/gitlab/gitlabhq/network/master?format=json')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json') describe Projects::CompareController, 'routing' do
end it 'to #index' do
end expect(get('/gitlab/gitlabhq/compare')).to route_to('projects/compare#index', namespace_id: 'gitlab', project_id: 'gitlabhq')
end
describe Projects::GraphsController, 'routing' do
it 'to #show' do it 'to #compare' do
expect(get('/gitlab/gitlabhq/graphs/master')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master') expect(post('/gitlab/gitlabhq/compare')).to route_to('projects/compare#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
expect(get('/gitlab/gitlabhq/graphs/ends-with.json')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'ends-with.json') end
expect(get('/gitlab/gitlabhq/graphs/master?format=json')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
end it 'to #show' do
end expect(get('/gitlab/gitlabhq/compare/master...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'master', to: 'stable')
expect(get('/gitlab/gitlabhq/compare/issue/1234...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'issue/1234', to: 'stable')
describe Projects::ForksController, 'routing' do end
it 'to #new' do end
expect(get('/gitlab/gitlabhq/forks/new')).to route_to('projects/forks#new', namespace_id: 'gitlab', project_id: 'gitlabhq')
end describe Projects::NetworkController, 'routing' do
it 'to #show' do
it 'to #create' do expect(get('/gitlab/gitlabhq/network/master')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
expect(post('/gitlab/gitlabhq/forks')).to route_to('projects/forks#create', namespace_id: 'gitlab', project_id: 'gitlabhq') expect(get('/gitlab/gitlabhq/network/ends-with.json')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'ends-with.json')
end expect(get('/gitlab/gitlabhq/network/master?format=json')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
end end
end
# project_avatar DELETE /project/avatar(.:format) projects/avatars#destroy
describe Projects::AvatarsController, 'routing' do describe Projects::GraphsController, 'routing' do
it 'to #destroy' do it 'to #show' do
expect(delete('/gitlab/gitlabhq/avatar')).to route_to( expect(get('/gitlab/gitlabhq/graphs/master')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
'projects/avatars#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq') expect(get('/gitlab/gitlabhq/graphs/ends-with.json')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'ends-with.json')
expect(get('/gitlab/gitlabhq/graphs/master?format=json')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
end
end
describe Projects::ForksController, 'routing' do
it 'to #new' do
expect(get('/gitlab/gitlabhq/forks/new')).to route_to('projects/forks#new', namespace_id: 'gitlab', project_id: 'gitlabhq')
end
it 'to #create' do
expect(post('/gitlab/gitlabhq/forks')).to route_to('projects/forks#create', namespace_id: 'gitlab', project_id: 'gitlabhq')
end
end
# project_avatar DELETE /project/avatar(.:format) projects/avatars#destroy
describe Projects::AvatarsController, 'routing' do
it 'to #destroy' do
expect(delete('/gitlab/gitlabhq/avatar')).to route_to(
'projects/avatars#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq')
end
end end
end end
...@@ -9,7 +9,7 @@ require 'spec_helper' ...@@ -9,7 +9,7 @@ require 'spec_helper'
# user_calendar_activities GET /u/:username/calendar_activities(.:format) # user_calendar_activities GET /u/:username/calendar_activities(.:format)
describe UsersController, "routing" do describe UsersController, "routing" do
it "to #show" do it "to #show" do
allow(User).to receive(:find_by).and_return(true) allow_any_instance_of(UserUrlConstrainer).to receive(:matches?).and_return(true)
expect(get("/User")).to route_to('users#show', username: 'User') expect(get("/User")).to route_to('users#show', username: 'User')
end end
...@@ -195,6 +195,8 @@ describe Profiles::KeysController, "routing" do ...@@ -195,6 +195,8 @@ describe Profiles::KeysController, "routing" do
# get all the ssh-keys of a user # get all the ssh-keys of a user
it "to #get_keys" do it "to #get_keys" do
allow_any_instance_of(UserUrlConstrainer).to receive(:matches?).and_return(true)
expect(get("/foo.keys")).to route_to('profiles/keys#get_keys', username: 'foo') expect(get("/foo.keys")).to route_to('profiles/keys#get_keys', username: 'foo')
end end
end end
...@@ -263,13 +265,17 @@ end ...@@ -263,13 +265,17 @@ end
describe "Groups", "routing" do describe "Groups", "routing" do
let(:name) { 'complex.group-namegit' } let(:name) { 'complex.group-namegit' }
before { allow_any_instance_of(GroupUrlConstrainer).to receive(:matches?).and_return(true) }
it "to #show" do it "to #show" do
expect(get("/groups/#{name}")).to route_to('groups#show', id: name) expect(get("/groups/#{name}")).to route_to('groups#show', id: name)
end end
it "also display group#show on the short path" do it "also supports nested groups" do
allow(Group).to receive(:find_by).and_return(true) expect(get("/#{name}/#{name}")).to route_to('groups#show', id: "#{name}/#{name}")
end
it "also display group#show on the short path" do
expect(get("/#{name}")).to route_to('groups#show', id: name) expect(get("/#{name}")).to route_to('groups#show', id: name)
end end
...@@ -284,6 +290,10 @@ describe "Groups", "routing" do ...@@ -284,6 +290,10 @@ describe "Groups", "routing" do
it "to #members" do it "to #members" do
expect(get("/groups/#{name}/group_members")).to route_to('groups/group_members#index', group_id: name) expect(get("/groups/#{name}/group_members")).to route_to('groups/group_members#index', group_id: name)
end end
it "also display group#show with slash in the path" do
expect(get('/group/subgroup')).to route_to('groups#show', id: 'group/subgroup')
end
end end
describe HealthCheckController, 'routing' do describe HealthCheckController, 'routing' do
......
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