Prefer project with exact path to differently cased one when both exist.

This commit is contained in:
Douwe Maan 2015-10-20 16:16:08 +02:00
parent 97eafd4b3d
commit 2f7fc7e9f7
3 changed files with 38 additions and 13 deletions

View File

@ -118,8 +118,8 @@ class ApplicationController < ActionController::Base
end end
project_path = "#{namespace}/#{id}" project_path = "#{namespace}/#{id}"
@project = Project.find_with_namespace(project_path) @project = Project.find_with_namespace(project_path) ||
Project.find_with_namespace(project_path, case_sensitive: false)
if @project and can?(current_user, :read_project, @project) if @project and can?(current_user, :read_project, @project)
if @project.path_with_namespace != project_path if @project.path_with_namespace != project_path

View File

@ -235,7 +235,7 @@ class Project < ActiveRecord::Base
where('projects.archived = ?', false).where('LOWER(projects.name) LIKE :query', query: "%#{query.downcase}%") where('projects.archived = ?', false).where('LOWER(projects.name) LIKE :query', query: "%#{query.downcase}%")
end end
def find_with_namespace(id) def find_with_namespace(id, case_sensitive: true)
namespace_path, project_path = id.split('/') namespace_path, project_path = id.split('/')
return nil if !namespace_path || !project_path return nil if !namespace_path || !project_path
@ -243,11 +243,18 @@ class Project < ActiveRecord::Base
# Use of unscoped ensures we're not secretly adding any ORDER BYs, which # Use of unscoped ensures we're not secretly adding any ORDER BYs, which
# have a negative impact on performance (and aren't needed for this # have a negative impact on performance (and aren't needed for this
# query). # query).
unscoped. projects = unscoped.
joins(:namespace). joins(:namespace).
iwhere('namespaces.path' => namespace_path). iwhere('namespaces.path' => namespace_path)
iwhere('projects.path' => project_path).
take projects =
if case_sensitive
projects.where('projects.path' => project_path)
else
projects.iwhere('projects.path' => project_path)
end
projects.take
end end
def visibility_levels def visibility_levels

View File

@ -51,16 +51,34 @@ describe ProjectsController do
end end
context "when requested with case sensitive namespace and project path" do context "when requested with case sensitive namespace and project path" do
it "redirects to the normalized path for case mismatch" do context "when there is a match with the same casing" do
get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase it "loads the project" do
get :show, namespace_id: public_project.namespace.path, id: public_project.path
expect(response).to redirect_to("/#{public_project.path_with_namespace}") expect(assigns(:project)).to eq(public_project)
expect(response.status).to eq(200)
end
end end
it "loads the page if normalized path matches request path" do context "when there is a match with different casing" do
get :show, namespace_id: public_project.namespace.path, id: public_project.path it "redirects to the normalized path" do
get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase
expect(response.status).to eq(200) expect(assigns(:project)).to eq(public_project)
expect(response).to redirect_to("/#{public_project.path_with_namespace}")
end
context "when there is also a match with the same casing" do
let!(:other_project) { create(:project, :public, namespace: public_project.namespace, path: public_project.path.upcase) }
it "loads the exactly matched project" do
get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase
expect(assigns(:project)).to eq(other_project)
expect(response.status).to eq(200)
end
end
end end
end end
end end