Merge branch 'gist' of https://github.com/Andrew8xx8/gitlabhq into Andrew8xx8-gist
Conflicts: Gemfile.lock app/models/ability.rb app/models/project.rb app/views/snippets/_form.html.haml db/schema.rb features/steps/shared/paths.rb spec/factories.rb spec/models/project_spec.rb
This commit is contained in:
commit
bcc4e4dc7e
|
@ -1,11 +1,4 @@
|
||||||
class Projects::ApplicationController < ApplicationController
|
class Projects::ApplicationController < ApplicationController
|
||||||
|
before_filter :project
|
||||||
before_filter :authorize_admin_team_member!
|
before_filter :repository
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def user_team
|
|
||||||
@team ||= UserTeam.find_by_path(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
class Projects::SnippetsController < Projects::ApplicationController
|
||||||
|
before_filter :module_enabled
|
||||||
|
before_filter :snippet, only: [:show, :edit, :destroy, :update, :raw]
|
||||||
|
|
||||||
|
# Allow read any snippet
|
||||||
|
before_filter :authorize_read_project_snippet!
|
||||||
|
|
||||||
|
# Allow write(create) snippet
|
||||||
|
before_filter :authorize_write_project_snippet!, only: [:new, :create]
|
||||||
|
|
||||||
|
# Allow modify snippet
|
||||||
|
before_filter :authorize_modify_project_snippet!, only: [:edit, :update]
|
||||||
|
|
||||||
|
# Allow destroy snippet
|
||||||
|
before_filter :authorize_admin_project_snippet!, only: [:destroy]
|
||||||
|
|
||||||
|
layout 'project_resource'
|
||||||
|
|
||||||
|
respond_to :html
|
||||||
|
|
||||||
|
def index
|
||||||
|
@snippets = @project.snippets.fresh.non_expired
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@snippet = @project.snippets.build
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@snippet = @project.snippets.build(params[:project_snippet])
|
||||||
|
@snippet.author = current_user
|
||||||
|
|
||||||
|
if @snippet.save
|
||||||
|
redirect_to project_snippet_path(@project, @snippet)
|
||||||
|
else
|
||||||
|
respond_with(@snippet)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @snippet.update_attributes(params[:project_snippet])
|
||||||
|
redirect_to project_snippet_path(@project, @snippet)
|
||||||
|
else
|
||||||
|
respond_with(@snippet)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@note = @project.notes.new(noteable: @snippet)
|
||||||
|
@target_type = :snippet
|
||||||
|
@target_id = @snippet.id
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
return access_denied! unless can?(current_user, :admin_project_snippet, @snippet)
|
||||||
|
|
||||||
|
@snippet.destroy
|
||||||
|
|
||||||
|
redirect_to project_snippets_path(@project)
|
||||||
|
end
|
||||||
|
|
||||||
|
def raw
|
||||||
|
send_data(
|
||||||
|
@snippet.content,
|
||||||
|
type: "text/plain",
|
||||||
|
disposition: 'inline',
|
||||||
|
filename: @snippet.file_name
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def snippet
|
||||||
|
@snippet ||= @project.snippets.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorize_modify_project_snippet!
|
||||||
|
return render_404 unless can?(current_user, :modify_project_snippet, @snippet)
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorize_admin_project_snippet!
|
||||||
|
return render_404 unless can?(current_user, :admin_project_snippet, @snippet)
|
||||||
|
end
|
||||||
|
|
||||||
|
def module_enabled
|
||||||
|
return render_404 unless @project.snippets_enabled
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,7 @@
|
||||||
class Projects::TeamsController < Projects::ApplicationController
|
class Projects::TeamsController < Projects::ApplicationController
|
||||||
|
|
||||||
|
before_filter :authorize_admin_team_member!
|
||||||
|
|
||||||
def available
|
def available
|
||||||
@teams = current_user.is_admin? ? UserTeam.scoped : current_user.user_teams
|
@teams = current_user.is_admin? ? UserTeam.scoped : current_user.user_teams
|
||||||
@teams = @teams.without_project(project)
|
@teams = @teams.without_project(project)
|
||||||
|
@ -24,4 +26,9 @@ class Projects::TeamsController < Projects::ApplicationController
|
||||||
redirect_to project_team_index_path(project)
|
redirect_to project_team_index_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def user_team
|
||||||
|
@team ||= UserTeam.find_by_path(params[:id])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
class SnippetsController < ProjectResourceController
|
class SnippetsController < ApplicationController
|
||||||
before_filter :module_enabled
|
|
||||||
before_filter :snippet, only: [:show, :edit, :destroy, :update, :raw]
|
before_filter :snippet, only: [:show, :edit, :destroy, :update, :raw]
|
||||||
|
|
||||||
# Allow read any snippet
|
|
||||||
before_filter :authorize_read_snippet!
|
|
||||||
|
|
||||||
# Allow write(create) snippet
|
|
||||||
before_filter :authorize_write_snippet!, only: [:new, :create]
|
|
||||||
|
|
||||||
# Allow modify snippet
|
# Allow modify snippet
|
||||||
before_filter :authorize_modify_snippet!, only: [:edit, :update]
|
before_filter :authorize_modify_snippet!, only: [:edit, :update]
|
||||||
|
|
||||||
|
@ -17,22 +10,38 @@ class SnippetsController < ProjectResourceController
|
||||||
respond_to :html
|
respond_to :html
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@snippets = @project.snippets.fresh.non_expired
|
@snippets = Snippet.public.fresh.non_expired.page(params[:page]).per(20)
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_index
|
||||||
|
@user = User.find_by_username(params[:username])
|
||||||
|
|
||||||
|
@snippets = @current_user.snippets.fresh.non_expired
|
||||||
|
|
||||||
|
@snippets = case params[:scope]
|
||||||
|
when 'public' then
|
||||||
|
@snippets.public
|
||||||
|
when 'private' then
|
||||||
|
@snippets.private
|
||||||
|
else
|
||||||
|
@snippets
|
||||||
|
end
|
||||||
|
|
||||||
|
@snippets = @snippets.page(params[:page]).per(20)
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@snippet = @project.snippets.new
|
@snippet = PersonalSnippet.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@snippet = @project.snippets.new(params[:snippet])
|
@snippet = PersonalSnippet.new(params[:personal_snippet])
|
||||||
@snippet.author = current_user
|
@snippet.author = current_user
|
||||||
@snippet.save
|
|
||||||
|
|
||||||
if @snippet.valid?
|
if @snippet.save
|
||||||
redirect_to [@project, @snippet]
|
redirect_to snippet_path(@snippet)
|
||||||
else
|
else
|
||||||
respond_with(@snippet)
|
respond_with @snippet
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,27 +49,22 @@ class SnippetsController < ProjectResourceController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@snippet.update_attributes(params[:snippet])
|
if @snippet.update_attributes(params[:personal_snippet])
|
||||||
|
redirect_to snippet_path(@snippet)
|
||||||
if @snippet.valid?
|
|
||||||
redirect_to [@project, @snippet]
|
|
||||||
else
|
else
|
||||||
respond_with(@snippet)
|
respond_with @snippet
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@note = @project.notes.new(noteable: @snippet)
|
|
||||||
@target_type = :snippet
|
|
||||||
@target_id = @snippet.id
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
return access_denied! unless can?(current_user, :admin_snippet, @snippet)
|
return access_denied! unless can?(current_user, :admin_personal_snippet, @snippet)
|
||||||
|
|
||||||
@snippet.destroy
|
@snippet.destroy
|
||||||
|
|
||||||
redirect_to project_snippets_path(@project)
|
redirect_to snippets_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def raw
|
def raw
|
||||||
|
@ -75,18 +79,14 @@ class SnippetsController < ProjectResourceController
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def snippet
|
def snippet
|
||||||
@snippet ||= @project.snippets.find(params[:id])
|
@snippet ||= PersonalSnippet.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def authorize_modify_snippet!
|
def authorize_modify_snippet!
|
||||||
return render_404 unless can?(current_user, :modify_snippet, @snippet)
|
return render_404 unless can?(current_user, :modify_personal_snippet, @snippet)
|
||||||
end
|
end
|
||||||
|
|
||||||
def authorize_admin_snippet!
|
def authorize_admin_snippet!
|
||||||
return render_404 unless can?(current_user, :admin_snippet, @snippet)
|
return render_404 unless can?(current_user, :admin_personal_snippet, @snippet)
|
||||||
end
|
|
||||||
|
|
||||||
def module_enabled
|
|
||||||
return render_404 unless @project.snippets_enabled
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -73,7 +73,7 @@ module TabHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_tab_class
|
def project_tab_class
|
||||||
return "active" if current_page?(controller: "projects", action: :edit, id: @project)
|
return "active" if current_page?(controller: "/projects", action: :edit, id: @project)
|
||||||
|
|
||||||
if ['services', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name
|
if ['services', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name
|
||||||
"active"
|
"active"
|
||||||
|
|
|
@ -7,7 +7,8 @@ class Ability
|
||||||
when "Project" then project_abilities(user, subject)
|
when "Project" then project_abilities(user, subject)
|
||||||
when "Issue" then issue_abilities(user, subject)
|
when "Issue" then issue_abilities(user, subject)
|
||||||
when "Note" then note_abilities(user, subject)
|
when "Note" then note_abilities(user, subject)
|
||||||
when "Snippet" then snippet_abilities(user, subject)
|
when "ProjectSnippet" then project_snippet_abilities(user, subject)
|
||||||
|
when "PersonalSnippet" then personal_snippet_abilities(user, subject)
|
||||||
when "MergeRequest" then merge_request_abilities(user, subject)
|
when "MergeRequest" then merge_request_abilities(user, subject)
|
||||||
when "Group", "Namespace" then group_abilities(user, subject)
|
when "Group", "Namespace" then group_abilities(user, subject)
|
||||||
when "UserTeam" then user_team_abilities(user, subject)
|
when "UserTeam" then user_team_abilities(user, subject)
|
||||||
|
@ -54,7 +55,7 @@ class Ability
|
||||||
:read_wiki,
|
:read_wiki,
|
||||||
:read_issue,
|
:read_issue,
|
||||||
:read_milestone,
|
:read_milestone,
|
||||||
:read_snippet,
|
:read_project_snippet,
|
||||||
:read_team_member,
|
:read_team_member,
|
||||||
:read_merge_request,
|
:read_merge_request,
|
||||||
:read_note,
|
:read_note,
|
||||||
|
@ -67,8 +68,8 @@ class Ability
|
||||||
def project_report_rules
|
def project_report_rules
|
||||||
project_guest_rules + [
|
project_guest_rules + [
|
||||||
:download_code,
|
:download_code,
|
||||||
:write_snippet,
|
|
||||||
:fork_project
|
:fork_project
|
||||||
|
:write_project_snippet
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -84,11 +85,11 @@ class Ability
|
||||||
project_dev_rules + [
|
project_dev_rules + [
|
||||||
:push_code_to_protected_branches,
|
:push_code_to_protected_branches,
|
||||||
:modify_issue,
|
:modify_issue,
|
||||||
:modify_snippet,
|
:modify_project_snippet,
|
||||||
:modify_merge_request,
|
:modify_merge_request,
|
||||||
:admin_issue,
|
:admin_issue,
|
||||||
:admin_milestone,
|
:admin_milestone,
|
||||||
:admin_snippet,
|
:admin_project_snippet,
|
||||||
:admin_team_member,
|
:admin_team_member,
|
||||||
:admin_merge_request,
|
:admin_merge_request,
|
||||||
:admin_note,
|
:admin_note,
|
||||||
|
@ -135,8 +136,7 @@ class Ability
|
||||||
rules.flatten
|
rules.flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
|
[:issue, :note, :project_snippet, :personal_snippet, :merge_request].each do |name|
|
||||||
[:issue, :note, :snippet, :merge_request].each do |name|
|
|
||||||
define_method "#{name}_abilities" do |user, subject|
|
define_method "#{name}_abilities" do |user, subject|
|
||||||
if subject.author == user
|
if subject.author == user
|
||||||
[
|
[
|
||||||
|
|
|
@ -241,6 +241,10 @@ class Event < ActiveRecord::Base
|
||||||
target.noteable_type == "Commit"
|
target.noteable_type == "Commit"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def note_project_snippet?
|
||||||
|
target.noteable_type == "Snippet"
|
||||||
|
end
|
||||||
|
|
||||||
def note_target
|
def note_target
|
||||||
target.noteable
|
target.noteable
|
||||||
end
|
end
|
||||||
|
|
|
@ -159,4 +159,10 @@ class Note < ActiveRecord::Base
|
||||||
"wall"
|
"wall"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# FIXME: Hack for polymorphic associations with STI
|
||||||
|
# For more information wisit http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Polymorphic+Associations
|
||||||
|
def noteable_type=(sType)
|
||||||
|
super(sType.to_s.classify.constantize.base_class.to_s)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: snippets
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# title :string(255)
|
||||||
|
# content :text
|
||||||
|
# author_id :integer not null
|
||||||
|
# project_id :integer not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# file_name :string(255)
|
||||||
|
# expires_at :datetime
|
||||||
|
# type :string(255)
|
||||||
|
# private :boolean
|
||||||
|
|
||||||
|
class PersonalSnippet < Snippet
|
||||||
|
end
|
|
@ -57,7 +57,7 @@ class Project < ActiveRecord::Base
|
||||||
has_many :milestones, dependent: :destroy
|
has_many :milestones, dependent: :destroy
|
||||||
has_many :users_projects, dependent: :destroy
|
has_many :users_projects, dependent: :destroy
|
||||||
has_many :notes, dependent: :destroy
|
has_many :notes, dependent: :destroy
|
||||||
has_many :snippets, dependent: :destroy
|
has_many :snippets, dependent: :destroy, class_name: "ProjectSnippet"
|
||||||
has_many :hooks, dependent: :destroy, class_name: "ProjectHook"
|
has_many :hooks, dependent: :destroy, class_name: "ProjectHook"
|
||||||
has_many :protected_branches, dependent: :destroy
|
has_many :protected_branches, dependent: :destroy
|
||||||
has_many :user_team_project_relationships, dependent: :destroy
|
has_many :user_team_project_relationships, dependent: :destroy
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: snippets
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# title :string(255)
|
||||||
|
# content :text
|
||||||
|
# author_id :integer not null
|
||||||
|
# project_id :integer not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# file_name :string(255)
|
||||||
|
# expires_at :datetime
|
||||||
|
# type :string(255)
|
||||||
|
# private :boolean
|
||||||
|
|
||||||
|
class ProjectSnippet < Snippet
|
||||||
|
belongs_to :project
|
||||||
|
belongs_to :author, class_name: "User"
|
||||||
|
|
||||||
|
validates :project, presence: true
|
||||||
|
|
||||||
|
# Scopes
|
||||||
|
scope :fresh, -> { order("created_at DESC") }
|
||||||
|
scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) }
|
||||||
|
scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) }
|
||||||
|
end
|
|
@ -11,29 +11,31 @@
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# file_name :string(255)
|
# file_name :string(255)
|
||||||
# expires_at :datetime
|
# expires_at :datetime
|
||||||
#
|
# type :string(255)
|
||||||
|
# private :boolean
|
||||||
|
|
||||||
class Snippet < ActiveRecord::Base
|
class Snippet < ActiveRecord::Base
|
||||||
include Linguist::BlobHelper
|
include Linguist::BlobHelper
|
||||||
|
|
||||||
attr_accessible :title, :content, :file_name, :expires_at
|
attr_accessible :title, :content, :file_name, :expires_at, :private
|
||||||
|
|
||||||
belongs_to :project
|
|
||||||
belongs_to :author, class_name: "User"
|
belongs_to :author, class_name: "User"
|
||||||
|
|
||||||
has_many :notes, as: :noteable, dependent: :destroy
|
has_many :notes, as: :noteable, dependent: :destroy
|
||||||
|
|
||||||
delegate :name, :email, to: :author, prefix: true, allow_nil: true
|
delegate :name, :email, to: :author, prefix: true, allow_nil: true
|
||||||
|
|
||||||
validates :author, presence: true
|
validates :author, presence: true
|
||||||
validates :project, presence: true
|
|
||||||
validates :title, presence: true, length: { within: 0..255 }
|
validates :title, presence: true, length: { within: 0..255 }
|
||||||
validates :file_name, presence: true, length: { within: 0..255 }
|
validates :file_name, presence: true, length: { within: 0..255 }
|
||||||
validates :content, presence: true
|
validates :content, presence: true
|
||||||
|
|
||||||
# Scopes
|
# Scopes
|
||||||
|
scope :public, -> { where(private: false) }
|
||||||
|
scope :private, -> { where(private: true) }
|
||||||
scope :fresh, -> { order("created_at DESC") }
|
scope :fresh, -> { order("created_at DESC") }
|
||||||
scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) }
|
|
||||||
scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) }
|
scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) }
|
||||||
|
scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) }
|
||||||
|
|
||||||
def self.content_types
|
def self.content_types
|
||||||
[
|
[
|
||||||
|
|
|
@ -78,6 +78,7 @@ class User < ActiveRecord::Base
|
||||||
has_many :team_projects, through: :user_team_project_relationships
|
has_many :team_projects, through: :user_team_project_relationships
|
||||||
|
|
||||||
# Projects
|
# Projects
|
||||||
|
has_many :snippets, dependent: :destroy, foreign_key: :author_id, class_name: "Snippet"
|
||||||
has_many :users_projects, dependent: :destroy
|
has_many :users_projects, dependent: :destroy
|
||||||
has_many :issues, dependent: :destroy, foreign_key: :author_id
|
has_many :issues, dependent: :destroy, foreign_key: :author_id
|
||||||
has_many :notes, dependent: :destroy, foreign_key: :author_id
|
has_many :notes, dependent: :destroy, foreign_key: :author_id
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
- if event.note_commit?
|
- if event.note_commit?
|
||||||
= event.note_target_type
|
= event.note_target_type
|
||||||
= link_to event.note_short_commit_id, project_commit_path(event.project, event.note_commit_id), class: "commit_short_id"
|
= link_to event.note_short_commit_id, project_commit_path(event.project, event.note_commit_id), class: "commit_short_id"
|
||||||
|
- if event.note_project_snippet?
|
||||||
|
= link_to project_snippet_path(event.project, event.note_target) do
|
||||||
|
%strong
|
||||||
|
#{event.note_target_type} ##{truncate event.note_target_id}
|
||||||
- else
|
- else
|
||||||
= link_to [event.project, event.note_target] do
|
= link_to [event.project, event.note_target] do
|
||||||
%strong
|
%strong
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
!!! 5
|
||||||
|
%html{ lang: "en"}
|
||||||
|
= render "layouts/head", title: "Snipepts"
|
||||||
|
%body{class: "#{app_theme} application"}
|
||||||
|
= render "layouts/head_panel", title: "Snippets"
|
||||||
|
= render "layouts/flash"
|
||||||
|
.container
|
||||||
|
%ul.main_menu
|
||||||
|
= nav_link(path: 'dashboard#show', html_options: {class: 'home'}) do
|
||||||
|
= link_to root_path, title: "Back to dashboard" do
|
||||||
|
%i.icon-arrow-left
|
||||||
|
= nav_link(path: 'snippet#new') do
|
||||||
|
= link_to new_snippet_path do
|
||||||
|
New snippet
|
||||||
|
= nav_link(path: 'snippets#user_index') do
|
||||||
|
= link_to user_snippets_path(@current_user) do
|
||||||
|
My snippets
|
||||||
|
= nav_link(path: 'snippets#index') do
|
||||||
|
= link_to snippets_path do
|
||||||
|
Discover snippets
|
||||||
|
|
||||||
|
.content= yield
|
|
@ -0,0 +1,12 @@
|
||||||
|
.file_holder
|
||||||
|
.file_title
|
||||||
|
%i.icon-file
|
||||||
|
%strong= @snippet.file_name
|
||||||
|
%span.options
|
||||||
|
= link_to "raw", raw_project_snippet_path(@project, @snippet), class: "btn btn-tiny", target: "_blank"
|
||||||
|
.file_content.code
|
||||||
|
- unless @snippet.content.empty?
|
||||||
|
%div{class: user_color_scheme_class}
|
||||||
|
= raw @snippet.colorize(formatter: :gitlab)
|
||||||
|
- else
|
||||||
|
%p.nothing_here_message Empty file
|
|
@ -0,0 +1,41 @@
|
||||||
|
%h3.page_title
|
||||||
|
= @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}"
|
||||||
|
%hr
|
||||||
|
.snippet-form-holder
|
||||||
|
= form_for [@project, @snippet], as: :project_snippet, url: url do |f|
|
||||||
|
-if @snippet.errors.any?
|
||||||
|
.alert.alert-error
|
||||||
|
%ul
|
||||||
|
- @snippet.errors.full_messages.each do |msg|
|
||||||
|
%li= msg
|
||||||
|
|
||||||
|
.clearfix
|
||||||
|
= f.label :title
|
||||||
|
.input= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true
|
||||||
|
.clearfix
|
||||||
|
= f.label "Lifetime"
|
||||||
|
.input= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'}
|
||||||
|
.clearfix
|
||||||
|
.file-editor
|
||||||
|
= f.label :file_name, "File"
|
||||||
|
.input
|
||||||
|
.file_holder.snippet
|
||||||
|
.file_title
|
||||||
|
= f.text_field :file_name, placeholder: "example.rb", class: 'snippet-file-name', required: true
|
||||||
|
.file_content.code
|
||||||
|
%pre#editor= @snippet.content
|
||||||
|
= f.hidden_field :content, class: 'snippet-file-content'
|
||||||
|
|
||||||
|
.form-actions
|
||||||
|
= f.submit 'Save', class: "btn-save btn"
|
||||||
|
= link_to "Cancel", project_snippets_path(@project), class: " btn"
|
||||||
|
- unless @snippet.new_record?
|
||||||
|
.pull-right= link_to 'Destroy', project_snippet_path(@project, @snippet), confirm: 'Are you sure?', method: :delete, class: "btn pull-right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}"
|
||||||
|
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
var editor = ace.edit("editor");
|
||||||
|
$(".snippet-form-holder form").submit(function(){
|
||||||
|
$(".snippet-file-content").val(editor.getValue());
|
||||||
|
});
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
= image_tag gravatar_icon(snippet.author_email), class: "avatar s24"
|
||||||
|
%a{href: project_snippet_path(snippet.project, snippet)}
|
||||||
|
%strong= truncate(snippet.title, length: 60)
|
||||||
|
%td
|
||||||
|
= snippet.file_name
|
||||||
|
%td
|
||||||
|
%span.cgray
|
||||||
|
- if snippet.expires_at
|
||||||
|
= snippet.expires_at.to_date.to_s(:short)
|
||||||
|
- else
|
||||||
|
Never
|
|
@ -0,0 +1 @@
|
||||||
|
= render "projects/snippets/form", url: project_snippet_path(@project, @snippet)
|
|
@ -0,0 +1,19 @@
|
||||||
|
%h3.page_title
|
||||||
|
Snippets
|
||||||
|
%small share code pastes with others out of git repository
|
||||||
|
|
||||||
|
- if can? current_user, :write_project_snippet, @project
|
||||||
|
= link_to new_project_snippet_path(@project), class: "btn btn-small add_new pull-right", title: "New Snippet" do
|
||||||
|
Add new snippet
|
||||||
|
%br
|
||||||
|
%table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th Title
|
||||||
|
%th File Name
|
||||||
|
%th Expires At
|
||||||
|
= render partial: "projects/snippets/snippet", collection: @snippets
|
||||||
|
- if @snippets.empty?
|
||||||
|
%tr
|
||||||
|
%td{colspan: 3}
|
||||||
|
%h3.nothing_here_message Nothing here.
|
|
@ -0,0 +1 @@
|
||||||
|
= render "projects/snippets/form", url: project_snippets_path(@project, @snippet)
|
|
@ -0,0 +1,9 @@
|
||||||
|
%h3.page_title
|
||||||
|
= @snippet.title
|
||||||
|
%small= @snippet.file_name
|
||||||
|
- if can?(current_user, :admin_project_snippet, @project) || @snippet.author == current_user
|
||||||
|
= link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right", title: 'Edit Snippet'
|
||||||
|
|
||||||
|
%br
|
||||||
|
%div= render 'projects/snippets/blob'
|
||||||
|
%div#notes= render "notes/notes_with_form"
|
|
@ -3,7 +3,7 @@
|
||||||
%i.icon-file
|
%i.icon-file
|
||||||
%strong= @snippet.file_name
|
%strong= @snippet.file_name
|
||||||
%span.options
|
%span.options
|
||||||
= link_to "raw", raw_project_snippet_path(@project, @snippet), class: "btn btn-tiny", target: "_blank"
|
= link_to "raw", raw_snippet_path(@snippet), class: "btn btn-tiny", target: "_blank"
|
||||||
.file_content.code
|
.file_content.code
|
||||||
- unless @snippet.content.empty?
|
- unless @snippet.content.empty?
|
||||||
%div{class: user_color_scheme_class}
|
%div{class: user_color_scheme_class}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
= @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}"
|
= @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}"
|
||||||
%hr
|
%hr
|
||||||
.snippet-form-holder
|
.snippet-form-holder
|
||||||
= form_for [@project, @snippet] do |f|
|
= form_for @snippet, as: :personal_snippet, url: url do |f|
|
||||||
-if @snippet.errors.any?
|
-if @snippet.errors.any?
|
||||||
.alert.alert-error
|
.alert.alert-error
|
||||||
%ul
|
%ul
|
||||||
|
@ -12,6 +12,9 @@
|
||||||
.clearfix
|
.clearfix
|
||||||
= f.label :title
|
= f.label :title
|
||||||
.input= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true
|
.input= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true
|
||||||
|
.clearfix
|
||||||
|
= f.label "Private?"
|
||||||
|
.input= f.check_box :private, {class: ''}
|
||||||
.clearfix
|
.clearfix
|
||||||
= f.label "Lifetime"
|
= f.label "Lifetime"
|
||||||
.input= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'}
|
.input= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'}
|
||||||
|
@ -28,9 +31,9 @@
|
||||||
|
|
||||||
.form-actions
|
.form-actions
|
||||||
= f.submit 'Save', class: "btn-save btn"
|
= f.submit 'Save', class: "btn-save btn"
|
||||||
= link_to "Cancel", project_snippets_path(@project), class: " btn"
|
= link_to "Cancel", snippets_path(@project), class: " btn"
|
||||||
- unless @snippet.new_record?
|
- unless @snippet.new_record?
|
||||||
.pull-right= link_to 'Destroy', [@project, @snippet], confirm: 'Removed snippet cannot be restored! Are you sure?', method: :delete, class: "btn pull-right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}"
|
.pull-right= link_to 'Destroy', snippet_path(@snippet), confirm: 'Removed snippet cannot be restored! Are you sure?', method: :delete, class: "btn pull-right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}"
|
||||||
|
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
|
- if snippet.private?
|
||||||
|
%i.icon-lock
|
||||||
|
- else
|
||||||
|
%i.icon-globe
|
||||||
= image_tag gravatar_icon(snippet.author_email), class: "avatar s24"
|
= image_tag gravatar_icon(snippet.author_email), class: "avatar s24"
|
||||||
|
- if snippet.project_id?
|
||||||
%a{href: project_snippet_path(snippet.project, snippet)}
|
%a{href: project_snippet_path(snippet.project, snippet)}
|
||||||
%strong= truncate(snippet.title, length: 60)
|
%strong= truncate(snippet.title, length: 60)
|
||||||
|
- else
|
||||||
|
%a{href: snippet_path(snippet)}
|
||||||
|
%strong= truncate(snippet.title, length: 60)
|
||||||
%td
|
%td
|
||||||
= snippet.file_name
|
= snippet.file_name
|
||||||
%td
|
%td
|
||||||
|
@ -11,3 +19,6 @@
|
||||||
= snippet.expires_at.to_date.to_s(:short)
|
= snippet.expires_at.to_date.to_s(:short)
|
||||||
- else
|
- else
|
||||||
Never
|
Never
|
||||||
|
%td
|
||||||
|
- if snippet.project_id?
|
||||||
|
= link_to snippet.project.name, project_path(snippet.project)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
%table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th Title
|
||||||
|
%th File Name
|
||||||
|
%th Expires At
|
||||||
|
%th Project
|
||||||
|
|
||||||
|
= render partial: 'snippet', collection: @snippets
|
||||||
|
- if @snippets.empty?
|
||||||
|
%tr
|
||||||
|
%td{colspan: 4}
|
||||||
|
%h3.nothing_here_message Nothing here.
|
||||||
|
|
||||||
|
= paginate @snippets
|
|
@ -1 +1 @@
|
||||||
= render "snippets/form"
|
= render "snippets/form", url: snippet_path(@snippet)
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
Snippets
|
Public snippets
|
||||||
%small share code pastes with others out of git repository
|
%small share code pastes with others out of git repository
|
||||||
|
= link_to new_snippet_path, class: "btn btn-small add_new pull-right", title: "New Snippet" do
|
||||||
- if can? current_user, :write_snippet, @project
|
|
||||||
= link_to new_project_snippet_path(@project), class: "btn btn-small add_new pull-right", title: "New Snippet" do
|
|
||||||
Add new snippet
|
Add new snippet
|
||||||
%br
|
|
||||||
%table
|
%hr
|
||||||
%thead
|
.row
|
||||||
%tr
|
.span12
|
||||||
%th Title
|
= render 'snippets'
|
||||||
%th File Name
|
|
||||||
%th Expires At
|
|
||||||
= render @snippets
|
|
||||||
- if @snippets.empty?
|
|
||||||
%tr
|
|
||||||
%td{colspan: 3}
|
|
||||||
%h3.nothing_here_message Nothing here.
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
= render "snippets/form"
|
= render "snippets/form", url: snippets_path(@snippet)
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
|
- if @snippet.private?
|
||||||
|
%i.icon-lock
|
||||||
|
- else
|
||||||
|
%i.icon-globe
|
||||||
|
|
||||||
= @snippet.title
|
= @snippet.title
|
||||||
%small= @snippet.file_name
|
%small= @snippet.file_name
|
||||||
- if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user
|
- if @snippet.author == current_user
|
||||||
= link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right", title: 'Edit Snippet'
|
= link_to "Edit", edit_snippet_path(@snippet), class: "btn btn-small pull-right", title: 'Edit Snippet'
|
||||||
|
|
||||||
%br
|
%br
|
||||||
%div= render 'blob'
|
%div= render 'blob'
|
||||||
%div#notes= render "notes/notes_with_form"
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
%h3.page_title
|
||||||
|
Snippets by
|
||||||
|
= @user.name
|
||||||
|
%small share code pastes with others out of git repository
|
||||||
|
= link_to new_snippet_path, class: "btn btn-small add_new pull-right", title: "New Snippet" do
|
||||||
|
Add new snippet
|
||||||
|
|
||||||
|
%hr
|
||||||
|
.row
|
||||||
|
.span3
|
||||||
|
%ul.nav.nav-pills.nav-stacked
|
||||||
|
= nav_tab :scope, nil do
|
||||||
|
= link_to "All", user_snippets_path(@user)
|
||||||
|
= nav_tab :scope, 'private' do
|
||||||
|
= link_to "Private", user_snippets_path(@user, scope: 'private')
|
||||||
|
= nav_tab :scope, 'public' do
|
||||||
|
= link_to "Public", user_snippets_path(@user, scope: 'public')
|
||||||
|
|
||||||
|
.span9
|
||||||
|
= render 'snippets'
|
|
@ -38,6 +38,16 @@ Gitlab::Application.routes.draw do
|
||||||
get 'help/web_hooks' => 'help#web_hooks'
|
get 'help/web_hooks' => 'help#web_hooks'
|
||||||
get 'help/workflow' => 'help#workflow'
|
get 'help/workflow' => 'help#workflow'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Global snippets
|
||||||
|
#
|
||||||
|
resources :snippets do
|
||||||
|
member do
|
||||||
|
get "raw"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
get "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ }
|
||||||
|
|
||||||
#
|
#
|
||||||
# Public namespace
|
# Public namespace
|
||||||
#
|
#
|
||||||
|
@ -182,6 +192,14 @@ Gitlab::Application.routes.draw do
|
||||||
resources :graph, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/}
|
resources :graph, only: [:show], constraints: {id: /(?:[^.]|\.(?!json$))+/, format: /json/}
|
||||||
match "/compare/:from...:to" => "compare#show", as: "compare", via: [:get, :post], constraints: {from: /.+/, to: /.+/}
|
match "/compare/:from...:to" => "compare#show", as: "compare", via: [:get, :post], constraints: {from: /.+/, to: /.+/}
|
||||||
|
|
||||||
|
scope module: :projects do
|
||||||
|
resources :snippets do
|
||||||
|
member do
|
||||||
|
get "raw"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
resources :wikis, only: [:show, :edit, :destroy, :create] do
|
resources :wikis, only: [:show, :edit, :destroy, :create] do
|
||||||
collection do
|
collection do
|
||||||
get :pages
|
get :pages
|
||||||
|
@ -255,19 +273,12 @@ Gitlab::Application.routes.draw do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :snippets do
|
|
||||||
member do
|
|
||||||
get "raw"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
resources :hooks, only: [:index, :create, :destroy] do
|
resources :hooks, only: [:index, :create, :destroy] do
|
||||||
member do
|
member do
|
||||||
get :test
|
get :test
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
resources :team, controller: 'team_members', only: [:index]
|
resources :team, controller: 'team_members', only: [:index]
|
||||||
resources :milestones, except: [:destroy]
|
resources :milestones, except: [:destroy]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddPrivateToSnippets < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :snippets, :private, :boolean, null: false, default: true
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddTypeToSnippets < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :snippets, :type, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
class ChangeProjectIdToNullInSnipepts < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
change_column :snippets, :project_id, :integer, :null => true
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
change_column :snippets, :project_id, :integer, :null => false
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
class AddTypeValueForSnippets < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
Snippet.where("project_id IS NOT NULL").update_all(type: 'ProjectSnippet')
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
end
|
||||||
|
end
|
|
@ -204,11 +204,13 @@ ActiveRecord::Schema.define(:version => 20130522141856) do
|
||||||
t.string "title"
|
t.string "title"
|
||||||
t.text "content"
|
t.text "content"
|
||||||
t.integer "author_id", :null => false
|
t.integer "author_id", :null => false
|
||||||
t.integer "project_id", :null => false
|
t.integer "project_id"
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
t.string "file_name"
|
t.string "file_name"
|
||||||
t.datetime "expires_at"
|
t.datetime "expires_at"
|
||||||
|
t.boolean "private", :default => true, :null => false
|
||||||
|
t.string "type"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "snippets", ["created_at"], :name => "index_snippets_on_created_at"
|
add_index "snippets", ["created_at"], :name => "index_snippets_on_created_at"
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
Feature: Project Snippets
|
||||||
|
Background:
|
||||||
|
Given I sign in as a user
|
||||||
|
And I own project "Shop"
|
||||||
|
And project "Shop" have "Snippet one" snippet
|
||||||
|
And project "Shop" have no "Snippet two" snippet
|
||||||
|
And I visit project "Shop" snippets page
|
||||||
|
|
||||||
|
Scenario: I should see snippets
|
||||||
|
Given I visit project "Shop" snippets page
|
||||||
|
Then I should see "Snippet one" in snippets
|
||||||
|
And I should not see "Snippet two" in snippets
|
||||||
|
|
||||||
|
Scenario: I create new project snippet
|
||||||
|
Given I click link "New Snippet"
|
||||||
|
And I submit new snippet "Snippet three"
|
||||||
|
Then I should see snippet "Snippet three"
|
||||||
|
|
||||||
|
@javascript
|
||||||
|
Scenario: I comment on a snippet "Snippet one"
|
||||||
|
Given I visit snippet page "Snippet one"
|
||||||
|
And I leave a comment like "Good snippet!"
|
||||||
|
Then I should see comment "Good snippet!"
|
||||||
|
|
||||||
|
Scenario: I update "Snippet one"
|
||||||
|
Given I visit snippet page "Snippet one"
|
||||||
|
And I click link "Edit"
|
||||||
|
And I submit new title "Snippet new title"
|
||||||
|
Then I should see "Snippet new title"
|
||||||
|
|
||||||
|
Scenario: I destroy "Snippet one"
|
||||||
|
Given I visit snippet page "Snippet one"
|
||||||
|
And I click link "Edit"
|
||||||
|
And I click link "Destroy"
|
||||||
|
Then I should not see "Snippet one" in snippets
|
|
@ -0,0 +1,10 @@
|
||||||
|
Feature: Discover Snippets
|
||||||
|
Background:
|
||||||
|
Given I sign in as a user
|
||||||
|
And I have public "Personal snippet one" snippet
|
||||||
|
And I have private "Personal snippet private" snippet
|
||||||
|
|
||||||
|
Scenario: I should see snippets
|
||||||
|
Given I visit snippets page
|
||||||
|
Then I should see "Personal snippet one" in snippets
|
||||||
|
And I should not see "Personal snippet private" in snippets
|
|
@ -0,0 +1,28 @@
|
||||||
|
Feature: Snippets Feature
|
||||||
|
Background:
|
||||||
|
Given I sign in as a user
|
||||||
|
And I have public "Personal snippet one" snippet
|
||||||
|
And I have private "Personal snippet private" snippet
|
||||||
|
|
||||||
|
Scenario: I create new snippet
|
||||||
|
Given I visit new snippet page
|
||||||
|
And I submit new snippet "Personal snippet three"
|
||||||
|
Then I should see snippet "Personal snippet three"
|
||||||
|
|
||||||
|
Scenario: I update "Personal snippet one"
|
||||||
|
Given I visit snippet page "Personal snippet one"
|
||||||
|
And I click link "Edit"
|
||||||
|
And I submit new title "Personal snippet new title"
|
||||||
|
Then I should see "Personal snippet new title"
|
||||||
|
|
||||||
|
Scenario: Set "Personal snippet one" public
|
||||||
|
Given I visit snippet page "Personal snippet one"
|
||||||
|
And I click link "Edit"
|
||||||
|
And I uncheck "Private" checkbox
|
||||||
|
Then I should see "Personal snippet one" public
|
||||||
|
|
||||||
|
Scenario: I destroy "Personal snippet one"
|
||||||
|
Given I visit snippet page "Personal snippet one"
|
||||||
|
And I click link "Edit"
|
||||||
|
And I click link "Destroy"
|
||||||
|
Then I should not see "Personal snippet one" in snippets
|
|
@ -0,0 +1,22 @@
|
||||||
|
Feature: User Snippets
|
||||||
|
Background:
|
||||||
|
Given I sign in as a user
|
||||||
|
And I have public "Personal snippet one" snippet
|
||||||
|
And I have private "Personal snippet private" snippet
|
||||||
|
|
||||||
|
Scenario: I should see all my snippets
|
||||||
|
Given I visit my snippets page
|
||||||
|
Then I should see "Personal snippet one" in snippets
|
||||||
|
And I should see "Personal snippet private" in snippets
|
||||||
|
|
||||||
|
Scenario: I can see only my private snippets
|
||||||
|
Given I visit my snippets page
|
||||||
|
And I click "Private" filter
|
||||||
|
Then I should not see "Personal snippet one" in snippets
|
||||||
|
And I should see "Personal snippet private" in snippets
|
||||||
|
|
||||||
|
Scenario: I can see only my public snippets
|
||||||
|
Given I visit my snippets page
|
||||||
|
And I click "Public" filter
|
||||||
|
Then I should see "Personal snippet one" in snippets
|
||||||
|
And I should not see "Personal snippet private" in snippets
|
|
@ -0,0 +1,100 @@
|
||||||
|
class ProjectSnippets < Spinach::FeatureSteps
|
||||||
|
include SharedAuthentication
|
||||||
|
include SharedProject
|
||||||
|
include SharedNote
|
||||||
|
include SharedPaths
|
||||||
|
|
||||||
|
And 'project "Shop" have "Snippet one" snippet' do
|
||||||
|
create(:project_snippet,
|
||||||
|
title: "Snippet one",
|
||||||
|
content: "Test content",
|
||||||
|
file_name: "snippet.rb",
|
||||||
|
project: project,
|
||||||
|
author: project.users.first)
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'project "Shop" have no "Snippet two" snippet' do
|
||||||
|
create(:snippet,
|
||||||
|
title: "Snippet two",
|
||||||
|
content: "Test content",
|
||||||
|
file_name: "snippet.rb",
|
||||||
|
author: project.users.first)
|
||||||
|
end
|
||||||
|
|
||||||
|
Given 'I click link "New Snippet"' do
|
||||||
|
click_link "Add new snippet"
|
||||||
|
end
|
||||||
|
|
||||||
|
Given 'I click link "Snippet one"' do
|
||||||
|
click_link "Snippet one"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see "Snippet one" in snippets' do
|
||||||
|
page.should have_content "Snippet one"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I should not see "Snippet two" in snippets' do
|
||||||
|
page.should_not have_content "Snippet two"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I should not see "Snippet one" in snippets' do
|
||||||
|
page.should_not have_content "Snippet one"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I click link "Edit"' do
|
||||||
|
within ".page_title" do
|
||||||
|
click_link "Edit"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I click link "Destroy"' do
|
||||||
|
click_link "Destroy"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I submit new snippet "Snippet three"' do
|
||||||
|
fill_in "project_snippet_title", :with => "Snippet three"
|
||||||
|
select "forever", :from => "project_snippet_expires_at"
|
||||||
|
fill_in "project_snippet_file_name", :with => "my_snippet.rb"
|
||||||
|
within('.file-editor') do
|
||||||
|
find(:xpath, "//input[@id='project_snippet_content']").set 'Content of snippet three'
|
||||||
|
end
|
||||||
|
click_button "Save"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see snippet "Snippet three"' do
|
||||||
|
page.should have_content "Snippet three"
|
||||||
|
page.should have_content "Content of snippet three"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I submit new title "Snippet new title"' do
|
||||||
|
fill_in "project_snippet_title", :with => "Snippet new title"
|
||||||
|
click_button "Save"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see "Snippet new title"' do
|
||||||
|
page.should have_content "Snippet new title"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I leave a comment like "Good snippet!"' do
|
||||||
|
within('.js-main-target-form') do
|
||||||
|
fill_in "note_note", with: "Good snippet!"
|
||||||
|
click_button "Add Comment"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see comment "Good snippet!"' do
|
||||||
|
page.should have_content "Good snippet!"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I visit snippet page "Snippet one"' do
|
||||||
|
visit project_snippet_path(project, project_snippet)
|
||||||
|
end
|
||||||
|
|
||||||
|
def project
|
||||||
|
@project ||= Project.find_by_name!("Shop")
|
||||||
|
end
|
||||||
|
|
||||||
|
def project_snippet
|
||||||
|
@project_snippet ||= ProjectSnippet.find_by_title!("Snippet One")
|
||||||
|
end
|
||||||
|
end
|
|
@ -275,6 +275,22 @@ module SharedPaths
|
||||||
visit public_root_path
|
visit public_root_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------
|
||||||
|
# Snippets
|
||||||
|
# ----------------------------------------
|
||||||
|
|
||||||
|
Given 'I visit project "Shop" snippets page' do
|
||||||
|
visit project_snippets_path(project)
|
||||||
|
end
|
||||||
|
|
||||||
|
Given 'I visit snippets page' do
|
||||||
|
visit snippets_path
|
||||||
|
end
|
||||||
|
|
||||||
|
Given 'I visit new snippet page' do
|
||||||
|
visit new_snippet_path
|
||||||
|
end
|
||||||
|
|
||||||
def root_ref
|
def root_ref
|
||||||
@project.repository.root_ref
|
@project.repository.root_ref
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
module SharedSnippet
|
||||||
|
include Spinach::DSL
|
||||||
|
|
||||||
|
And 'I have public "Personal snippet one" snippet' do
|
||||||
|
create(:personal_snippet,
|
||||||
|
title: "Personal snippet one",
|
||||||
|
content: "Test content",
|
||||||
|
file_name: "snippet.rb",
|
||||||
|
private: false,
|
||||||
|
author: current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I have private "Personal snippet private" snippet' do
|
||||||
|
create(:personal_snippet,
|
||||||
|
title: "Personal snippet private",
|
||||||
|
content: "Provate content",
|
||||||
|
file_name: "private_snippet.rb",
|
||||||
|
private: true,
|
||||||
|
author: current_user)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,17 @@
|
||||||
|
class DiscoverSnippets < Spinach::FeatureSteps
|
||||||
|
include SharedAuthentication
|
||||||
|
include SharedPaths
|
||||||
|
include SharedSnippet
|
||||||
|
|
||||||
|
Then 'I should see "Personal snippet one" in snippets' do
|
||||||
|
page.should have_content "Personal snippet one"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I should not see "Personal snippet private" in snippets' do
|
||||||
|
page.should_not have_content "Personal snippet private"
|
||||||
|
end
|
||||||
|
|
||||||
|
def snippet
|
||||||
|
@snippet ||= PersonalSnippet.find_by_title!("Personal snippet one")
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,65 @@
|
||||||
|
class SnippetsFeature < Spinach::FeatureSteps
|
||||||
|
include SharedAuthentication
|
||||||
|
include SharedPaths
|
||||||
|
include SharedProject
|
||||||
|
include SharedSnippet
|
||||||
|
|
||||||
|
Given 'I click link "Personal snippet one"' do
|
||||||
|
click_link "Personal snippet one"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I should not see "Personal snippet one" in snippets' do
|
||||||
|
page.should_not have_content "Personal snippet one"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I click link "Edit"' do
|
||||||
|
within ".page_title" do
|
||||||
|
click_link "Edit"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I click link "Destroy"' do
|
||||||
|
click_link "Destroy"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I submit new snippet "Personal snippet three"' do
|
||||||
|
fill_in "personal_snippet_title", :with => "Personal snippet three"
|
||||||
|
select "forever", :from => "personal_snippet_expires_at"
|
||||||
|
fill_in "personal_snippet_file_name", :with => "my_snippet.rb"
|
||||||
|
within('.file-editor') do
|
||||||
|
find(:xpath, "//input[@id='personal_snippet_content']").set 'Content of snippet three'
|
||||||
|
end
|
||||||
|
click_button "Save"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see snippet "Personal snippet three"' do
|
||||||
|
page.should have_content "Personal snippet three"
|
||||||
|
page.should have_content "Content of snippet three"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I submit new title "Personal snippet new title"' do
|
||||||
|
fill_in "personal_snippet_title", :with => "Personal snippet new title"
|
||||||
|
click_button "Save"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see "Personal snippet new title"' do
|
||||||
|
page.should have_content "Personal snippet new title"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I uncheck "Private" checkbox' do
|
||||||
|
find(:xpath, "//input[@id='personal_snippet_private']").set true
|
||||||
|
click_button "Save"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see "Personal snippet one" public' do
|
||||||
|
page.should have_no_xpath("//i[@class='public-snippet']")
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I visit snippet page "Personal snippet one"' do
|
||||||
|
visit snippet_path(snippet)
|
||||||
|
end
|
||||||
|
|
||||||
|
def snippet
|
||||||
|
@snippet ||= PersonalSnippet.find_by_title!("Personal snippet one")
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,41 @@
|
||||||
|
class UserSnippets < Spinach::FeatureSteps
|
||||||
|
include SharedAuthentication
|
||||||
|
include SharedPaths
|
||||||
|
include SharedSnippet
|
||||||
|
|
||||||
|
Given 'I visit my snippets page' do
|
||||||
|
visit user_snippets_path(current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see "Personal snippet one" in snippets' do
|
||||||
|
page.should have_content "Personal snippet one"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I should see "Personal snippet private" in snippets' do
|
||||||
|
page.should have_content "Personal snippet private"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should not see "Personal snippet one" in snippets' do
|
||||||
|
page.should_not have_content "Personal snippet one"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I should not see "Personal snippet private" in snippets' do
|
||||||
|
page.should_not have_content "Personal snippet private"
|
||||||
|
end
|
||||||
|
|
||||||
|
Given 'I click "Public" filter' do
|
||||||
|
within('.nav-stacked') do
|
||||||
|
click_link "Public"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Given 'I click "Private" filter' do
|
||||||
|
within('.nav-stacked') do
|
||||||
|
click_link "Private"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def snippet
|
||||||
|
@snippet ||= PersonalSnippet.find_by_title!("Personal snippet one")
|
||||||
|
end
|
||||||
|
end
|
|
@ -328,7 +328,7 @@ module API
|
||||||
# Example Request:
|
# Example Request:
|
||||||
# POST /projects/:id/snippets
|
# POST /projects/:id/snippets
|
||||||
post ":id/snippets" do
|
post ":id/snippets" do
|
||||||
authorize! :write_snippet, user_project
|
authorize! :write_project_snippet, user_project
|
||||||
required_attributes! [:title, :file_name, :code]
|
required_attributes! [:title, :file_name, :code]
|
||||||
|
|
||||||
attrs = attributes_for_keys [:title, :file_name]
|
attrs = attributes_for_keys [:title, :file_name]
|
||||||
|
@ -357,7 +357,7 @@ module API
|
||||||
# PUT /projects/:id/snippets/:snippet_id
|
# PUT /projects/:id/snippets/:snippet_id
|
||||||
put ":id/snippets/:snippet_id" do
|
put ":id/snippets/:snippet_id" do
|
||||||
@snippet = user_project.snippets.find(params[:snippet_id])
|
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||||
authorize! :modify_snippet, @snippet
|
authorize! :modify_project_snippet, @snippet
|
||||||
|
|
||||||
attrs = attributes_for_keys [:title, :file_name]
|
attrs = attributes_for_keys [:title, :file_name]
|
||||||
attrs[:expires_at] = params[:lifetime] if params[:lifetime].present?
|
attrs[:expires_at] = params[:lifetime] if params[:lifetime].present?
|
||||||
|
@ -380,7 +380,7 @@ module API
|
||||||
delete ":id/snippets/:snippet_id" do
|
delete ":id/snippets/:snippet_id" do
|
||||||
begin
|
begin
|
||||||
@snippet = user_project.snippets.find(params[:snippet_id])
|
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||||
authorize! :modify_snippet, user_project
|
authorize! :modify_project_snippet, @snippet
|
||||||
@snippet.destroy
|
@snippet.destroy
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
|
|
|
@ -197,7 +197,7 @@ FactoryGirl.define do
|
||||||
url
|
url
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :snippet do
|
factory :project_snippet do
|
||||||
project
|
project
|
||||||
author
|
author
|
||||||
title
|
title
|
||||||
|
@ -205,6 +205,20 @@ FactoryGirl.define do
|
||||||
file_name
|
file_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :personal_snippet do
|
||||||
|
author
|
||||||
|
title
|
||||||
|
content
|
||||||
|
file_name
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :snippet do
|
||||||
|
author
|
||||||
|
title
|
||||||
|
content
|
||||||
|
file_name
|
||||||
|
end
|
||||||
|
|
||||||
factory :protected_branch do
|
factory :protected_branch do
|
||||||
name
|
name
|
||||||
project
|
project
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe "Snippets" do
|
|
||||||
let(:project) { create(:project) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
login_as :user
|
|
||||||
project.team << [@user, :developer]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET /snippets" do
|
|
||||||
before do
|
|
||||||
@snippet = create(:snippet,
|
|
||||||
author: @user,
|
|
||||||
project: project)
|
|
||||||
|
|
||||||
visit project_snippets_path(project)
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { page }
|
|
||||||
|
|
||||||
it { should have_content(@snippet.title[0..10]) }
|
|
||||||
it { should have_content(@snippet.project.name) }
|
|
||||||
|
|
||||||
describe "Destroy" do
|
|
||||||
before do
|
|
||||||
# admin access to remove snippet
|
|
||||||
@user.users_projects.destroy_all
|
|
||||||
project.team << [@user, :master]
|
|
||||||
visit edit_project_snippet_path(project, @snippet)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should remove entry" do
|
|
||||||
expect {
|
|
||||||
click_link "destroy_snippet_#{@snippet.id}"
|
|
||||||
}.to change { Snippet.count }.by(-1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "New snippet" do
|
|
||||||
before do
|
|
||||||
visit project_snippets_path(project)
|
|
||||||
click_link "New Snippet"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should open new snippet popup" do
|
|
||||||
page.current_path.should == new_project_snippet_path(project)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "fill in", js: true do
|
|
||||||
before do
|
|
||||||
fill_in "snippet_title", with: "login function"
|
|
||||||
fill_in "snippet_file_name", with: "test.rb"
|
|
||||||
page.execute_script("editor.insert('def login; end');")
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect { click_button "Save" }.to change {Snippet.count}.by(1) }
|
|
||||||
|
|
||||||
it "should add new snippet to table" do
|
|
||||||
click_button "Save"
|
|
||||||
page.current_path.should == project_snippet_path(project, Snippet.last)
|
|
||||||
page.should have_content "login function"
|
|
||||||
page.should have_content "test.rb"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "Edit snippet" do
|
|
||||||
before do
|
|
||||||
@snippet = create(:snippet,
|
|
||||||
author: @user,
|
|
||||||
project: project)
|
|
||||||
visit project_snippet_path(project, @snippet)
|
|
||||||
click_link "Edit Snippet"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should open edit page" do
|
|
||||||
page.current_path.should == edit_project_snippet_path(project, @snippet)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "fill in" do
|
|
||||||
before do
|
|
||||||
fill_in "snippet_title", with: "login function"
|
|
||||||
fill_in "snippet_file_name", with: "test.rb"
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect { click_button "Save" }.to_not change {Snippet.count} }
|
|
||||||
|
|
||||||
it "should update snippet fields" do
|
|
||||||
click_button "Save"
|
|
||||||
|
|
||||||
page.current_path.should == project_snippet_path(project, @snippet)
|
|
||||||
page.should have_content "login function"
|
|
||||||
page.should have_content "test.rb"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -10,7 +10,7 @@ describe GitlabMarkdownHelper do
|
||||||
let(:commit) { project.repository.commit }
|
let(:commit) { project.repository.commit }
|
||||||
let(:issue) { create(:issue, project: project) }
|
let(:issue) { create(:issue, project: project) }
|
||||||
let(:merge_request) { create(:merge_request, project: project) }
|
let(:merge_request) { create(:merge_request, project: project) }
|
||||||
let(:snippet) { create(:snippet, project: project) }
|
let(:snippet) { create(:project_snippet, project: project) }
|
||||||
let(:member) { project.users_projects.where(user_id: user).first }
|
let(:member) { project.users_projects.where(user_id: user).first }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
@ -190,8 +190,43 @@ describe GitlabMarkdownHelper do
|
||||||
describe "referencing a snippet" do
|
describe "referencing a snippet" do
|
||||||
let(:object) { snippet }
|
let(:object) { snippet }
|
||||||
let(:reference) { "$#{snippet.id}" }
|
let(:reference) { "$#{snippet.id}" }
|
||||||
|
let(:actual) { "Reference to #{reference}" }
|
||||||
|
let(:expected) { project_snippet_path(project, object) }
|
||||||
|
|
||||||
|
it "should link using a valid id" do
|
||||||
|
gfm(actual).should match(expected)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should link with adjacent text" do
|
||||||
|
# Wrap the reference in parenthesis
|
||||||
|
gfm(actual.gsub(reference, "(#{reference})")).should match(expected)
|
||||||
|
|
||||||
|
# Append some text to the end of the reference
|
||||||
|
gfm(actual.gsub(reference, "#{reference}, right?")).should match(expected)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should keep whitespace intact" do
|
||||||
|
actual = "Referenced #{reference} already."
|
||||||
|
expected = /Referenced <a.+>[^\s]+<\/a> already/
|
||||||
|
gfm(actual).should match(expected)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not link with an invalid id" do
|
||||||
|
# Modify the reference string so it's still parsed, but is invalid
|
||||||
|
reference.gsub!(/^(.)(\d+)$/, '\1' + ('\2' * 2))
|
||||||
|
gfm(actual).should == actual
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should include a title attribute" do
|
||||||
|
title = "Snippet: #{object.title}"
|
||||||
|
gfm(actual).should match(/title="#{title}"/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should include standard gfm classes" do
|
||||||
|
css = object.class.to_s.underscore
|
||||||
|
gfm(actual).should match(/class="\s?gfm gfm-snippet\s?"/)
|
||||||
|
end
|
||||||
|
|
||||||
include_examples 'referenced object'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "referencing multiple objects" do
|
describe "referencing multiple objects" do
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: snippets
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# title :string(255)
|
||||||
|
# content :text
|
||||||
|
# author_id :integer not null
|
||||||
|
# project_id :integer not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# file_name :string(255)
|
||||||
|
# expires_at :datetime
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe ProjectSnippet do
|
||||||
|
describe "Associations" do
|
||||||
|
it { should belong_to(:project) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Mass assignment" do
|
||||||
|
it { should_not allow_mass_assignment_of(:project_id) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Validation" do
|
||||||
|
it { should validate_presence_of(:project) }
|
||||||
|
end
|
||||||
|
end
|
|
@ -36,7 +36,7 @@ describe Project do
|
||||||
it { should have_many(:milestones).dependent(:destroy) }
|
it { should have_many(:milestones).dependent(:destroy) }
|
||||||
it { should have_many(:users_projects).dependent(:destroy) }
|
it { should have_many(:users_projects).dependent(:destroy) }
|
||||||
it { should have_many(:notes).dependent(:destroy) }
|
it { should have_many(:notes).dependent(:destroy) }
|
||||||
it { should have_many(:snippets).dependent(:destroy) }
|
it { should have_many(:snippets).class_name('ProjectSnippet').dependent(:destroy) }
|
||||||
it { should have_many(:deploy_keys_projects).dependent(:destroy) }
|
it { should have_many(:deploy_keys_projects).dependent(:destroy) }
|
||||||
it { should have_many(:deploy_keys) }
|
it { should have_many(:deploy_keys) }
|
||||||
it { should have_many(:hooks).dependent(:destroy) }
|
it { should have_many(:hooks).dependent(:destroy) }
|
||||||
|
|
|
@ -17,19 +17,16 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe Snippet do
|
describe Snippet do
|
||||||
describe "Associations" do
|
describe "Associations" do
|
||||||
it { should belong_to(:project) }
|
|
||||||
it { should belong_to(:author).class_name('User') }
|
it { should belong_to(:author).class_name('User') }
|
||||||
it { should have_many(:notes).dependent(:destroy) }
|
it { should have_many(:notes).dependent(:destroy) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Mass assignment" do
|
describe "Mass assignment" do
|
||||||
it { should_not allow_mass_assignment_of(:author_id) }
|
it { should_not allow_mass_assignment_of(:author_id) }
|
||||||
it { should_not allow_mass_assignment_of(:project_id) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Validation" do
|
describe "Validation" do
|
||||||
it { should validate_presence_of(:author) }
|
it { should validate_presence_of(:author) }
|
||||||
it { should validate_presence_of(:project) }
|
|
||||||
|
|
||||||
it { should validate_presence_of(:title) }
|
it { should validate_presence_of(:title) }
|
||||||
it { should ensure_length_of(:title).is_within(0..255) }
|
it { should ensure_length_of(:title).is_within(0..255) }
|
||||||
|
|
|
@ -41,6 +41,7 @@ require 'spec_helper'
|
||||||
describe User do
|
describe User do
|
||||||
describe "Associations" do
|
describe "Associations" do
|
||||||
it { should have_one(:namespace) }
|
it { should have_one(:namespace) }
|
||||||
|
it { should have_many(:snippets).class_name('Snippet').dependent(:destroy) }
|
||||||
it { should have_many(:users_projects).dependent(:destroy) }
|
it { should have_many(:users_projects).dependent(:destroy) }
|
||||||
it { should have_many(:groups) }
|
it { should have_many(:groups) }
|
||||||
it { should have_many(:keys).dependent(:destroy) }
|
it { should have_many(:keys).dependent(:destroy) }
|
||||||
|
|
|
@ -7,7 +7,7 @@ describe API::API do
|
||||||
let!(:project) { create(:project, namespace: user.namespace ) }
|
let!(:project) { create(:project, namespace: user.namespace ) }
|
||||||
let!(:issue) { create(:issue, project: project, author: user) }
|
let!(:issue) { create(:issue, project: project, author: user) }
|
||||||
let!(:merge_request) { create(:merge_request, project: project, author: user) }
|
let!(:merge_request) { create(:merge_request, project: project, author: user) }
|
||||||
let!(:snippet) { create(:snippet, project: project, author: user) }
|
let!(:snippet) { create(:project_snippet, project: project, author: user) }
|
||||||
let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) }
|
let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) }
|
||||||
let!(:merge_request_note) { create(:note, noteable: merge_request, project: project, author: user) }
|
let!(:merge_request_note) { create(:note, noteable: merge_request, project: project, author: user) }
|
||||||
let!(:snippet_note) { create(:note, noteable: snippet, project: project, author: user) }
|
let!(:snippet_note) { create(:note, noteable: snippet, project: project, author: user) }
|
||||||
|
|
|
@ -10,7 +10,7 @@ describe API::API do
|
||||||
let(:admin) { create(:admin) }
|
let(:admin) { create(:admin) }
|
||||||
let!(:project) { create(:project_with_code, creator_id: user.id) }
|
let!(:project) { create(:project_with_code, creator_id: user.id) }
|
||||||
let!(:hook) { create(:project_hook, project: project, url: "http://example.com") }
|
let!(:hook) { create(:project_hook, project: project, url: "http://example.com") }
|
||||||
let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') }
|
let!(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') }
|
||||||
let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
|
let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
|
||||||
let!(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
|
let!(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
|
||||||
|
|
||||||
|
|
|
@ -258,13 +258,37 @@ end
|
||||||
# project_snippet GET /:project_id/snippets/:id(.:format) snippets#show
|
# project_snippet GET /:project_id/snippets/:id(.:format) snippets#show
|
||||||
# PUT /:project_id/snippets/:id(.:format) snippets#update
|
# PUT /:project_id/snippets/:id(.:format) snippets#update
|
||||||
# DELETE /:project_id/snippets/:id(.:format) snippets#destroy
|
# DELETE /:project_id/snippets/:id(.:format) snippets#destroy
|
||||||
describe SnippetsController, "routing" do
|
describe Project::SnippetsController, "routing" do
|
||||||
it "to #raw" do
|
it "to #raw" do
|
||||||
get("/gitlabhq/snippets/1/raw").should route_to('snippets#raw', project_id: 'gitlabhq', id: '1')
|
get("/gitlabhq/snippets/1/raw").should route_to('projects/snippets#raw', project_id: 'gitlabhq', id: '1')
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like "RESTful project resources" do
|
it "to #index" do
|
||||||
let(:controller) { 'snippets' }
|
get("/gitlabhq/snippets").should route_to("projects/snippets#index", project_id: 'gitlabhq')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #create" do
|
||||||
|
post("/gitlabhq/snippets").should route_to("projects/snippets#create", project_id: 'gitlabhq')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #new" do
|
||||||
|
get("/gitlabhq/snippets/new").should route_to("projects/snippets#new", project_id: 'gitlabhq')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #edit" do
|
||||||
|
get("/gitlabhq/snippets/1/edit").should route_to("projects/snippets#edit", project_id: 'gitlabhq', id: '1')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #show" do
|
||||||
|
get("/gitlabhq/snippets/1").should route_to("projects/snippets#show", project_id: 'gitlabhq', id: '1')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #update" do
|
||||||
|
put("/gitlabhq/snippets/1").should route_to("projects/snippets#update", project_id: 'gitlabhq', id: '1')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #destroy" do
|
||||||
|
delete("/gitlabhq/snippets/1").should route_to("projects/snippets#destroy", project_id: 'gitlabhq', id: '1')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,51 @@ describe "Mounted Apps", "routing" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# snippets GET /snippets(.:format) snippets#index
|
||||||
|
# POST /snippets(.:format) snippets#create
|
||||||
|
# new_snippet GET /snippets/new(.:format) snippets#new
|
||||||
|
# edit_snippet GET /snippets/:id/edit(.:format) snippets#edit
|
||||||
|
# snippet GET /snippets/:id(.:format) snippets#show
|
||||||
|
# PUT /snippets/:id(.:format) snippets#update
|
||||||
|
# DELETE /snippets/:id(.:format) snippets#destroy
|
||||||
|
describe SnippetsController, "routing" do
|
||||||
|
it "to #user_index" do
|
||||||
|
get("/s/User").should route_to('snippets#user_index', username: 'User')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #raw" do
|
||||||
|
get("/snippets/1/raw").should route_to('snippets#raw', id: '1')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #index" do
|
||||||
|
get("/snippets").should route_to('snippets#index')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #create" do
|
||||||
|
post("/snippets").should route_to('snippets#create')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #new" do
|
||||||
|
get("/snippets/new").should route_to('snippets#new')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #edit" do
|
||||||
|
get("/snippets/1/edit").should route_to('snippets#edit', id: '1')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #show" do
|
||||||
|
get("/snippets/1").should route_to('snippets#show', id: '1')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #update" do
|
||||||
|
put("/snippets/1").should route_to('snippets#update', id: '1')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "to #destroy" do
|
||||||
|
delete("/snippets/1").should route_to('snippets#destroy', id: '1')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# help GET /help(.:format) help#index
|
# help GET /help(.:format) help#index
|
||||||
# help_permissions GET /help/permissions(.:format) help#permissions
|
# help_permissions GET /help/permissions(.:format) help#permissions
|
||||||
# help_workflow GET /help/workflow(.:format) help#workflow
|
# help_workflow GET /help/workflow(.:format) help#workflow
|
||||||
|
|
Loading…
Reference in New Issue