From cc869d5dc101ea1175e308d8532064f06072d08b Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Sat, 23 Mar 2013 22:14:37 +0400 Subject: Private field added to snippet --- app/controllers/projects/snippets_controller.rb | 92 ++++++++++++++++++++++ .../20130323174317_add_private_to_snippets.rb | 5 ++ db/schema.rb | 3 +- 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 app/controllers/projects/snippets_controller.rb create mode 100644 db/migrate/20130323174317_add_private_to_snippets.rb diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb new file mode 100644 index 00000000000..a2e22a670a3 --- /dev/null +++ b/app/controllers/projects/snippets_controller.rb @@ -0,0 +1,92 @@ +class SnippetsController < ProjectResourceController + before_filter :module_enabled + 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 + before_filter :authorize_modify_snippet!, only: [:edit, :update] + + # Allow destroy snippet + before_filter :authorize_admin_snippet!, only: [:destroy] + + respond_to :html + + def index + @snippets = @project.snippets.fresh.non_expired + end + + def new + @snippet = @project.snippets.new + end + + def create + @snippet = @project.snippets.new(params[:snippet]) + @snippet.author = current_user + @snippet.save + + if @snippet.valid? + redirect_to [@project, @snippet] + else + respond_with(@snippet) + end + end + + def edit + end + + def update + @snippet.update_attributes(params[:snippet]) + + if @snippet.valid? + redirect_to [@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_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_snippet! + return render_404 unless can?(current_user, :modify_snippet, @snippet) + end + + def authorize_admin_snippet! + return render_404 unless can?(current_user, :admin_snippet, @snippet) + end + + def module_enabled + return render_404 unless @project.snippets_enabled + end +end diff --git a/db/migrate/20130323174317_add_private_to_snippets.rb b/db/migrate/20130323174317_add_private_to_snippets.rb new file mode 100644 index 00000000000..427b530464d --- /dev/null +++ b/db/migrate/20130323174317_add_private_to_snippets.rb @@ -0,0 +1,5 @@ +class AddPrivateToSnippets < ActiveRecord::Migration + def change + add_column :snippets, :private, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index e4349ac4bf7..a48b85c153e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130318212250) do +ActiveRecord::Schema.define(:version => 20130323174317) do create_table "events", :force => true do |t| t.string "target_type" @@ -190,6 +190,7 @@ ActiveRecord::Schema.define(:version => 20130318212250) do t.datetime "updated_at", :null => false t.string "file_name" t.datetime "expires_at" + t.boolean "private" end add_index "snippets", ["created_at"], :name => "index_snippets_on_created_at" -- cgit v1.2.1 From b49cfbc1d54b6cfa674ba803b3a90fb81c609c8b Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Sat, 23 Mar 2013 23:13:51 +0400 Subject: Project snippets moved to /projects --- app/controllers/projects/snippets_controller.rb | 2 +- app/views/projects/snippets/_blob.html.haml | 12 ++++++++ app/views/projects/snippets/_form.html.haml | 41 +++++++++++++++++++++++++ app/views/projects/snippets/_snippet.html.haml | 13 ++++++++ app/views/projects/snippets/edit.html.haml | 1 + app/views/projects/snippets/index.html.haml | 19 ++++++++++++ app/views/projects/snippets/new.html.haml | 1 + app/views/projects/snippets/show.html.haml | 9 ++++++ config/routes.rb | 8 +++-- spec/routing/project_routing_spec.rb | 32 ++++++++++++++++--- 10 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 app/views/projects/snippets/_blob.html.haml create mode 100644 app/views/projects/snippets/_form.html.haml create mode 100644 app/views/projects/snippets/_snippet.html.haml create mode 100644 app/views/projects/snippets/edit.html.haml create mode 100644 app/views/projects/snippets/index.html.haml create mode 100644 app/views/projects/snippets/new.html.haml create mode 100644 app/views/projects/snippets/show.html.haml diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index a2e22a670a3..7c3281084f7 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -1,4 +1,4 @@ -class SnippetsController < ProjectResourceController +class Projects::SnippetsController < Projects::ApplicationController before_filter :module_enabled before_filter :snippet, only: [:show, :edit, :destroy, :update, :raw] diff --git a/app/views/projects/snippets/_blob.html.haml b/app/views/projects/snippets/_blob.html.haml new file mode 100644 index 00000000000..017a33b34f3 --- /dev/null +++ b/app/views/projects/snippets/_blob.html.haml @@ -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 diff --git a/app/views/projects/snippets/_form.html.haml b/app/views/projects/snippets/_form.html.haml new file mode 100644 index 00000000000..77162cdcde3 --- /dev/null +++ b/app/views/projects/snippets/_form.html.haml @@ -0,0 +1,41 @@ +%h3.page_title + = @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}" +%hr +.snippet-form-holder + = form_for [@project, @snippet] 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], 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()); + }); + diff --git a/app/views/projects/snippets/_snippet.html.haml b/app/views/projects/snippets/_snippet.html.haml new file mode 100644 index 00000000000..a576500c15d --- /dev/null +++ b/app/views/projects/snippets/_snippet.html.haml @@ -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 diff --git a/app/views/projects/snippets/edit.html.haml b/app/views/projects/snippets/edit.html.haml new file mode 100644 index 00000000000..f81c0b8bc64 --- /dev/null +++ b/app/views/projects/snippets/edit.html.haml @@ -0,0 +1 @@ += render "snippets/form" diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml new file mode 100644 index 00000000000..bacf23d8f8d --- /dev/null +++ b/app/views/projects/snippets/index.html.haml @@ -0,0 +1,19 @@ +%h3.page_title + Snippets + %small share code pastes with others out of git repository + + - 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 +%br +%table + %thead + %tr + %th Title + %th File Name + %th Expires At + = render @snippets + - if @snippets.empty? + %tr + %td{colspan: 3} + %h3.nothing_here_message Nothing here. diff --git a/app/views/projects/snippets/new.html.haml b/app/views/projects/snippets/new.html.haml new file mode 100644 index 00000000000..f81c0b8bc64 --- /dev/null +++ b/app/views/projects/snippets/new.html.haml @@ -0,0 +1 @@ += render "snippets/form" diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml new file mode 100644 index 00000000000..12534edf8ba --- /dev/null +++ b/app/views/projects/snippets/show.html.haml @@ -0,0 +1,9 @@ +%h3.page_title + = @snippet.title + %small= @snippet.file_name + - if can?(current_user, :admin_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 'blob' +%div#notes= render "notes/notes_with_form" diff --git a/config/routes.rb b/config/routes.rb index 0028baf8d53..d87dd4abdb0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -244,9 +244,11 @@ Gitlab::Application.routes.draw do end end - resources :snippets do - member do - get "raw" + scope module: :projects do + resources :snippets do + member do + get "raw" + end end end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 41533f8b4fe..059abe14961 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -249,13 +249,37 @@ end # project_snippet GET /:project_id/snippets/:id(.:format) snippets#show # PUT /:project_id/snippets/:id(.:format) snippets#update # DELETE /:project_id/snippets/:id(.:format) snippets#destroy -describe SnippetsController, "routing" do +describe Project::SnippetsController, "routing" 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 - it_behaves_like "RESTful project resources" do - let(:controller) { 'snippets' } + it "to #index" do + 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 -- cgit v1.2.1 From 617239000762a01c57b35cbb699f155622ae921a Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Sun, 24 Mar 2013 11:57:15 +0400 Subject: User Teams specific code moved to user_teams controller --- app/controllers/projects/application_controller.rb | 8 -------- app/controllers/projects/teams_controller.rb | 7 +++++++ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 7e4776d2d75..49e514a228e 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -1,11 +1,3 @@ class Projects::ApplicationController < ApplicationController - before_filter :authorize_admin_team_member! - - protected - - def user_team - @team ||= UserTeam.find_by_path(params[:id]) - end - end diff --git a/app/controllers/projects/teams_controller.rb b/app/controllers/projects/teams_controller.rb index 17e7367364a..c7d51b84fc4 100644 --- a/app/controllers/projects/teams_controller.rb +++ b/app/controllers/projects/teams_controller.rb @@ -1,5 +1,7 @@ class Projects::TeamsController < Projects::ApplicationController + before_filter :authorize_admin_team_member! + def available @teams = current_user.is_admin? ? UserTeam.scoped : current_user.user_teams @teams = @teams.without_project(project) @@ -24,4 +26,9 @@ class Projects::TeamsController < Projects::ApplicationController redirect_to project_team_index_path(project) end + protected + + def user_team + @team ||= UserTeam.find_by_path(params[:id]) + end end -- cgit v1.2.1 From 7d2fbe6bd880b001857a373500e4fae31d43060a Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Sun, 24 Mar 2013 19:12:28 +0400 Subject: Project Snippets now part of project --- app/controllers/projects/application_controller.rb | 3 +- app/controllers/projects/snippets_controller.rb | 2 + app/helpers/tab_helper.rb | 2 +- spec/features/projects/snippets_spec.rb | 101 +++++++++++++++++++++ 4 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 spec/features/projects/snippets_spec.rb diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 49e514a228e..86e4a7cbd6b 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -1,3 +1,4 @@ class Projects::ApplicationController < ApplicationController - + before_filter :project + before_filter :repository end diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 7c3281084f7..4602fbb989a 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -14,6 +14,8 @@ class Projects::SnippetsController < Projects::ApplicationController # Allow destroy snippet before_filter :authorize_admin_snippet!, only: [:destroy] + layout 'project_resource' + respond_to :html def index diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index d2be4b1a7e6..19aba0f5f6d 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -73,7 +73,7 @@ module TabHelper end 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 "active" diff --git a/spec/features/projects/snippets_spec.rb b/spec/features/projects/snippets_spec.rb new file mode 100644 index 00000000000..3c85359ee06 --- /dev/null +++ b/spec/features/projects/snippets_spec.rb @@ -0,0 +1,101 @@ +require 'spec_helper' + +describe "Project::Snippets" do + let(:project) { create(:project) } + + before do + login_as :user + project.team << [@user, :developer] + end + + describe "GET /:project/snippets" do + before do + @snippet = create(:snippet, + author: @user, + project: project) + + visit project_snippets_path(project) + p 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 project 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 project 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 -- cgit v1.2.1 From bc7c5f87bbd5cc25a0aaf03e9e5ecf6a65375098 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Sun, 24 Mar 2013 19:26:49 +0400 Subject: Project snippet moved to separate model --- app/models/project_snippet.rb | 27 ++++++++++++++++++++ app/models/snippet.rb | 5 ++-- db/migrate/20130324151736_add_type_to_snippets.rb | 5 ++++ db/schema.rb | 3 ++- spec/models/project_snippet_spec.rb | 30 +++++++++++++++++++++++ spec/models/snippet_spec.rb | 3 --- 6 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 app/models/project_snippet.rb create mode 100644 db/migrate/20130324151736_add_type_to_snippets.rb create mode 100644 spec/models/project_snippet_spec.rb diff --git a/app/models/project_snippet.rb b/app/models/project_snippet.rb new file mode 100644 index 00000000000..a86f2e7a32f --- /dev/null +++ b/app/models/project_snippet.rb @@ -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 diff --git a/app/models/snippet.rb b/app/models/snippet.rb index c4ee35e0556..592dfdfbb57 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -11,21 +11,20 @@ # updated_at :datetime not null # file_name :string(255) # expires_at :datetime -# +# type :string(255) +# private :boolean class Snippet < ActiveRecord::Base include Linguist::BlobHelper attr_accessible :title, :content, :file_name, :expires_at - belongs_to :project belongs_to :author, class_name: "User" has_many :notes, as: :noteable, dependent: :destroy delegate :name, :email, to: :author, prefix: true, allow_nil: true validates :author, presence: true - validates :project, presence: true validates :title, presence: true, length: { within: 0..255 } validates :file_name, presence: true, length: { within: 0..255 } validates :content, presence: true diff --git a/db/migrate/20130324151736_add_type_to_snippets.rb b/db/migrate/20130324151736_add_type_to_snippets.rb new file mode 100644 index 00000000000..276aab2ca15 --- /dev/null +++ b/db/migrate/20130324151736_add_type_to_snippets.rb @@ -0,0 +1,5 @@ +class AddTypeToSnippets < ActiveRecord::Migration + def change + add_column :snippets, :type, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index a48b85c153e..88e249047e6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130323174317) do +ActiveRecord::Schema.define(:version => 20130324151736) do create_table "events", :force => true do |t| t.string "target_type" @@ -191,6 +191,7 @@ ActiveRecord::Schema.define(:version => 20130323174317) do t.string "file_name" t.datetime "expires_at" t.boolean "private" + t.string "type" end add_index "snippets", ["created_at"], :name => "index_snippets_on_created_at" diff --git a/spec/models/project_snippet_spec.rb b/spec/models/project_snippet_spec.rb new file mode 100644 index 00000000000..716fd81c91b --- /dev/null +++ b/spec/models/project_snippet_spec.rb @@ -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 diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index e4d1934829f..52355c38f0c 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -17,19 +17,16 @@ require 'spec_helper' describe Snippet do describe "Associations" do - it { should belong_to(:project) } it { should belong_to(:author).class_name('User') } it { should have_many(:notes).dependent(:destroy) } end describe "Mass assignment" do it { should_not allow_mass_assignment_of(:author_id) } - it { should_not allow_mass_assignment_of(:project_id) } end describe "Validation" do it { should validate_presence_of(:author) } - it { should validate_presence_of(:project) } it { should validate_presence_of(:title) } it { should ensure_length_of(:title).is_within(0..255) } -- cgit v1.2.1 From 5b35000f16201bd631f161ef6d79b0a77dc2c27b Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Sun, 24 Mar 2013 22:31:14 +0400 Subject: Snippets feature refactored. Tests now use spinach --- app/controllers/projects/snippets_controller.rb | 14 +-- app/controllers/snippets_controller.rb | 2 +- app/models/ability.rb | 3 +- app/models/project.rb | 2 +- app/views/projects/snippets/_form.html.haml | 4 +- app/views/projects/snippets/edit.html.haml | 2 +- app/views/projects/snippets/index.html.haml | 2 +- app/views/projects/snippets/new.html.haml | 2 +- app/views/projects/snippets/show.html.haml | 2 +- config/routes.rb | 17 ++-- ...172327_change_project_id_to_null_in_snipepts.rb | 9 ++ db/schema.rb | 4 +- features/project/snippets.feature | 35 +++++++ features/steps/project/project_snippets.rb | 100 ++++++++++++++++++++ features/steps/shared/paths.rb | 4 + spec/factories.rb | 9 +- spec/features/projects/snippets_spec.rb | 101 --------------------- spec/features/snippets_spec.rb | 99 -------------------- 18 files changed, 183 insertions(+), 228 deletions(-) create mode 100644 db/migrate/20130324172327_change_project_id_to_null_in_snipepts.rb create mode 100644 features/project/snippets.feature create mode 100644 features/steps/project/project_snippets.rb delete mode 100644 spec/features/projects/snippets_spec.rb delete mode 100644 spec/features/snippets_spec.rb diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 4602fbb989a..ebff5039ffa 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -27,12 +27,12 @@ class Projects::SnippetsController < Projects::ApplicationController end def create - @snippet = @project.snippets.new(params[:snippet]) + @snippet = @project.snippets.new(params[:project_snippet]) @snippet.author = current_user @snippet.save if @snippet.valid? - redirect_to [@project, @snippet] + redirect_to project_snippet_path(@project, @snippet) else respond_with(@snippet) end @@ -42,10 +42,10 @@ class Projects::SnippetsController < Projects::ApplicationController end def update - @snippet.update_attributes(params[:snippet]) + @snippet.update_attributes(params[:project_snippet]) if @snippet.valid? - redirect_to [@project, @snippet] + redirect_to project_snippet_path(@project, @snippet) else respond_with(@snippet) end @@ -58,7 +58,7 @@ class Projects::SnippetsController < Projects::ApplicationController end def destroy - return access_denied! unless can?(current_user, :admin_snippet, @snippet) + return access_denied! unless can?(current_user, :admin_project_snippet, @snippet) @snippet.destroy @@ -81,11 +81,11 @@ class Projects::SnippetsController < Projects::ApplicationController end def authorize_modify_snippet! - return render_404 unless can?(current_user, :modify_snippet, @snippet) + return render_404 unless can?(current_user, :modify_project_snippet, @snippet) end def authorize_admin_snippet! - return render_404 unless can?(current_user, :admin_snippet, @snippet) + return render_404 unless can?(current_user, :admin_project_snippet, @snippet) end def module_enabled diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index a2e22a670a3..bb5fffca33c 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -60,7 +60,7 @@ class SnippetsController < ProjectResourceController @snippet.destroy - redirect_to project_snippets_path(@project) + redirect_to project_snippet_path(@project) end def raw diff --git a/app/models/ability.rb b/app/models/ability.rb index 41f7127403c..928b36e6c80 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -7,6 +7,7 @@ class Ability when "Project" then project_abilities(user, subject) when "Issue" then issue_abilities(user, subject) when "Note" then note_abilities(user, subject) + when "ProjectSnippet" then project_snippet_abilities(user, subject) when "Snippet" then snippet_abilities(user, subject) when "MergeRequest" then merge_request_abilities(user, subject) when "Group", "Namespace" then group_abilities(user, subject) @@ -135,7 +136,7 @@ class Ability end - [:issue, :note, :snippet, :merge_request].each do |name| + [:issue, :note, :project_snippet, :snippet, :merge_request].each do |name| define_method "#{name}_abilities" do |user, subject| if subject.author == user [ diff --git a/app/models/project.rb b/app/models/project.rb index 23eb7f90194..a0f014a15ab 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -50,7 +50,7 @@ class Project < ActiveRecord::Base has_many :milestones, dependent: :destroy has_many :users_projects, dependent: :destroy has_many :notes, dependent: :destroy - has_many :snippets, dependent: :destroy + has_many :snippets, dependent: :destroy, class_name: "ProjectSnippet" has_many :deploy_keys, dependent: :destroy, class_name: "Key", foreign_key: "project_id" has_many :hooks, dependent: :destroy, class_name: "ProjectHook" has_many :wikis, dependent: :destroy diff --git a/app/views/projects/snippets/_form.html.haml b/app/views/projects/snippets/_form.html.haml index 77162cdcde3..99a8761daef 100644 --- a/app/views/projects/snippets/_form.html.haml +++ b/app/views/projects/snippets/_form.html.haml @@ -2,7 +2,7 @@ = @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}" %hr .snippet-form-holder - = form_for [@project, @snippet] do |f| + = form_for [@project, @snippet], as: :project_snippet, url: url do |f| -if @snippet.errors.any? .alert.alert-error %ul @@ -30,7 +30,7 @@ = 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], confirm: 'Are you sure?', method: :delete, class: "btn pull-right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}" + .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 diff --git a/app/views/projects/snippets/edit.html.haml b/app/views/projects/snippets/edit.html.haml index f81c0b8bc64..e28b7d4937e 100644 --- a/app/views/projects/snippets/edit.html.haml +++ b/app/views/projects/snippets/edit.html.haml @@ -1 +1 @@ -= render "snippets/form" += render "projects/snippets/form", url: project_snippet_path(@project, @snippet) diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml index bacf23d8f8d..12760d377f3 100644 --- a/app/views/projects/snippets/index.html.haml +++ b/app/views/projects/snippets/index.html.haml @@ -12,7 +12,7 @@ %th Title %th File Name %th Expires At - = render @snippets + = render partial: "projects/snippets/snippet", collection: @snippets - if @snippets.empty? %tr %td{colspan: 3} diff --git a/app/views/projects/snippets/new.html.haml b/app/views/projects/snippets/new.html.haml index f81c0b8bc64..460af34f676 100644 --- a/app/views/projects/snippets/new.html.haml +++ b/app/views/projects/snippets/new.html.haml @@ -1 +1 @@ -= render "snippets/form" += render "projects/snippets/form", url: project_snippets_path(@project, @snippet) diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index 12534edf8ba..e325c3d84e6 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -5,5 +5,5 @@ = link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right", title: 'Edit Snippet' %br -%div= render 'blob' +%div= render 'projects/snippets/blob' %div#notes= render "notes/notes_with_form" diff --git a/config/routes.rb b/config/routes.rb index d87dd4abdb0..21a5eb9bfec 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -177,6 +177,14 @@ Gitlab::Application.routes.draw do 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 collection do get :pages @@ -244,21 +252,12 @@ Gitlab::Application.routes.draw do end end - scope module: :projects do - resources :snippets do - member do - get "raw" - end - end - end - resources :hooks, only: [:index, :create, :destroy] do member do get :test end end - resources :team, controller: 'team_members', only: [:index] resources :milestones, except: [:destroy] resources :labels, only: [:index] diff --git a/db/migrate/20130324172327_change_project_id_to_null_in_snipepts.rb b/db/migrate/20130324172327_change_project_id_to_null_in_snipepts.rb new file mode 100644 index 00000000000..4c992bac4d1 --- /dev/null +++ b/db/migrate/20130324172327_change_project_id_to_null_in_snipepts.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index 88e249047e6..f54bd2e16ea 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130324151736) do +ActiveRecord::Schema.define(:version => 20130324172327) do create_table "events", :force => true do |t| t.string "target_type" @@ -185,7 +185,7 @@ ActiveRecord::Schema.define(:version => 20130324151736) do t.string "title" t.text "content" t.integer "author_id", :null => false - t.integer "project_id", :null => false + t.integer "project_id" t.datetime "created_at", :null => false t.datetime "updated_at", :null => false t.string "file_name" diff --git a/features/project/snippets.feature b/features/project/snippets.feature new file mode 100644 index 00000000000..a26c8dc8474 --- /dev/null +++ b/features/project/snippets.feature @@ -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 diff --git a/features/steps/project/project_snippets.rb b/features/steps/project/project_snippets.rb new file mode 100644 index 00000000000..c8580d6fd30 --- /dev/null +++ b/features/steps/project/project_snippets.rb @@ -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 diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 1af8b478155..42004df426e 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -263,6 +263,10 @@ module SharedPaths visit project_wiki_path(@project, :home) end + Given 'I visit project "Shop" snippets page' do + visit project_snippets_path(project) + end + def root_ref @project.repository.root_ref end diff --git a/spec/factories.rb b/spec/factories.rb index 41766859468..67caec9f851 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -196,7 +196,7 @@ FactoryGirl.define do user end - factory :snippet do + factory :project_snippet do project author title @@ -204,6 +204,13 @@ FactoryGirl.define do file_name end + factory :snippet do + author + title + content + file_name + end + factory :protected_branch do name project diff --git a/spec/features/projects/snippets_spec.rb b/spec/features/projects/snippets_spec.rb deleted file mode 100644 index 3c85359ee06..00000000000 --- a/spec/features/projects/snippets_spec.rb +++ /dev/null @@ -1,101 +0,0 @@ -require 'spec_helper' - -describe "Project::Snippets" do - let(:project) { create(:project) } - - before do - login_as :user - project.team << [@user, :developer] - end - - describe "GET /:project/snippets" do - before do - @snippet = create(:snippet, - author: @user, - project: project) - - visit project_snippets_path(project) - p 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 project 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 project 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 diff --git a/spec/features/snippets_spec.rb b/spec/features/snippets_spec.rb deleted file mode 100644 index 1a0f6eaeef4..00000000000 --- a/spec/features/snippets_spec.rb +++ /dev/null @@ -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 -- cgit v1.2.1 From 9e2525cbd0da4204f93937e368e277be38d1a7b3 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Sun, 24 Mar 2013 23:09:59 +0400 Subject: Association form user to snippets added --- app/models/user.rb | 1 + spec/models/user_spec.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/models/user.rb b/app/models/user.rb index c73353bf032..e6ab66f4bc7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -75,6 +75,7 @@ class User < ActiveRecord::Base has_many :team_projects, through: :user_team_project_relationships # Projects + has_many :snippets, dependent: :destroy, foreign_key: :author_id, class_name: "Snippet" has_many :users_projects, dependent: :destroy has_many :issues, dependent: :destroy, foreign_key: :author_id has_many :notes, dependent: :destroy, foreign_key: :author_id diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7d061bf28b2..89124086d99 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -40,6 +40,7 @@ require 'spec_helper' describe User do describe "Associations" do 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(:groups) } it { should have_many(:keys).dependent(:destroy) } -- cgit v1.2.1 From 718ec26a23e3e303e04c569447acf963b9ef307e Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Sun, 24 Mar 2013 23:55:51 +0400 Subject: Routing updated to support global snippets --- config/routes.rb | 8 ++++++++ spec/routing/routing_spec.rb | 45 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/config/routes.rb b/config/routes.rb index 21a5eb9bfec..f3632e64d61 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -100,6 +100,14 @@ Gitlab::Application.routes.draw do get "errors/githost" + resources :snippets do + member do + get "raw" + get "my" + end + end + match "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ } + # # Profile Area # diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb index 5ad8165ecce..3d7db8ac217 100644 --- a/spec/routing/routing_spec.rb +++ b/spec/routing/routing_spec.rb @@ -25,6 +25,51 @@ describe "Mounted Apps", "routing" do 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_permissions GET /help/permissions(.:format) help#permissions # help_workflow GET /help/workflow(.:format) help#workflow -- cgit v1.2.1 From 770f262a6a89ff5335ed452b83d1b8edb3e3ff5d Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 00:22:45 +0400 Subject: Private added to attr_accessible --- app/models/snippet.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 592dfdfbb57..7018dc67ab7 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -17,7 +17,7 @@ class Snippet < ActiveRecord::Base include Linguist::BlobHelper - attr_accessible :title, :content, :file_name, :expires_at + attr_accessible :title, :content, :file_name, :expires_at, :private belongs_to :author, class_name: "User" has_many :notes, as: :noteable, dependent: :destroy -- cgit v1.2.1 From 8adf9c79560f0b1d39270b8ee957df75b53fc30a Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 00:23:12 +0400 Subject: Additional scopes added --- app/models/snippet.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 7018dc67ab7..1d454801315 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -30,9 +30,12 @@ class Snippet < ActiveRecord::Base validates :content, presence: true # Scopes - scope :fresh, -> { order("created_at DESC") } - scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) } + scope :public, -> { where(private: false) } + scope :private, -> { where(private: true) } + scope :fresh, -> { order("created_at DESC") } scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) } + scope :has_project, -> { where("bars.id IS NOT NULL") } + scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) } def self.content_types [ -- cgit v1.2.1 From 83eb63cbe8c266256ce93af9336e118233845173 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 00:24:34 +0400 Subject: New layout for snippets added --- app/views/layouts/snippets.html.haml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 app/views/layouts/snippets.html.haml diff --git a/app/views/layouts/snippets.html.haml b/app/views/layouts/snippets.html.haml new file mode 100644 index 00000000000..0675ad55845 --- /dev/null +++ b/app/views/layouts/snippets.html.haml @@ -0,0 +1,24 @@ +!!! 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 + = nav_link(path: 'search#show') do + = link_to "Search", search_path + + .content= yield -- cgit v1.2.1 From 3b6228dc27fad65250884256bec05a66e1dff74c Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 00:37:14 +0400 Subject: It's better to use STI instead --- app/models/snippet.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 1d454801315..5d09c6b6e47 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -34,7 +34,6 @@ class Snippet < ActiveRecord::Base scope :private, -> { where(private: true) } scope :fresh, -> { order("created_at DESC") } scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) } - scope :has_project, -> { where("bars.id IS NOT NULL") } scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) } def self.content_types -- cgit v1.2.1 From b3dc4fb72146d439314bdb40377272a317974397 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 00:39:38 +0400 Subject: Migrations to convert data added --- db/migrate/20130323174317_add_private_to_snippets.rb | 2 +- db/migrate/20130324203535_add_type_value_for_snippets.rb | 8 ++++++++ db/schema.rb | 10 +++++----- 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 db/migrate/20130324203535_add_type_value_for_snippets.rb diff --git a/db/migrate/20130323174317_add_private_to_snippets.rb b/db/migrate/20130323174317_add_private_to_snippets.rb index 427b530464d..92f3a5c7011 100644 --- a/db/migrate/20130323174317_add_private_to_snippets.rb +++ b/db/migrate/20130323174317_add_private_to_snippets.rb @@ -1,5 +1,5 @@ class AddPrivateToSnippets < ActiveRecord::Migration def change - add_column :snippets, :private, :boolean + add_column :snippets, :private, :boolean, null: false, default: true end end diff --git a/db/migrate/20130324203535_add_type_value_for_snippets.rb b/db/migrate/20130324203535_add_type_value_for_snippets.rb new file mode 100644 index 00000000000..8c05dd2cc71 --- /dev/null +++ b/db/migrate/20130324203535_add_type_value_for_snippets.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index f54bd2e16ea..c988b172d90 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130324172327) do +ActiveRecord::Schema.define(:version => 20130324203535) do create_table "events", :force => true do |t| t.string "target_type" @@ -184,13 +184,13 @@ ActiveRecord::Schema.define(:version => 20130324172327) do create_table "snippets", :force => true do |t| t.string "title" t.text "content" - t.integer "author_id", :null => false + t.integer "author_id", :null => false t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "file_name" t.datetime "expires_at" - t.boolean "private" + t.boolean "private", :default => true, :null => false t.string "type" end -- cgit v1.2.1 From 9710e42d798556ecaf0ffeaf4806a117c1b3530c Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 01:16:52 +0400 Subject: Layuot and templates for personal snippets added --- app/views/snippets/_blob.html.haml | 2 +- app/views/snippets/_form.html.haml | 9 ++++++--- app/views/snippets/_snippet.html.haml | 15 +++++++++++++-- app/views/snippets/_snippets.html.haml | 13 +++++++++++++ app/views/snippets/edit.html.haml | 2 +- app/views/snippets/index.html.haml | 28 +++++++++++++--------------- app/views/snippets/new.html.haml | 2 +- app/views/snippets/show.html.haml | 10 +++++++--- app/views/snippets/user_index.html.haml | 20 ++++++++++++++++++++ 9 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 app/views/snippets/_snippets.html.haml create mode 100644 app/views/snippets/user_index.html.haml diff --git a/app/views/snippets/_blob.html.haml b/app/views/snippets/_blob.html.haml index 017a33b34f3..56e62f0d6b3 100644 --- a/app/views/snippets/_blob.html.haml +++ b/app/views/snippets/_blob.html.haml @@ -3,7 +3,7 @@ %i.icon-file %strong= @snippet.file_name %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 - unless @snippet.content.empty? %div{class: user_color_scheme_class} diff --git a/app/views/snippets/_form.html.haml b/app/views/snippets/_form.html.haml index 77162cdcde3..d9514890b20 100644 --- a/app/views/snippets/_form.html.haml +++ b/app/views/snippets/_form.html.haml @@ -2,7 +2,7 @@ = @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}" %hr .snippet-form-holder - = form_for [@project, @snippet] do |f| + = form_for @snippet, as: :personal_snippet, url: url do |f| -if @snippet.errors.any? .alert.alert-error %ul @@ -12,6 +12,9 @@ .clearfix = f.label :title .input= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true + .clearfix + = f.label "Private?" + .input= f.check_box :private, {class: ''} .clearfix = f.label "Lifetime" .input= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'} @@ -28,9 +31,9 @@ .form-actions = 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? - .pull-right= link_to 'Destroy', [@project, @snippet], confirm: '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: 'Are you sure?', method: :delete, class: "btn pull-right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}" :javascript diff --git a/app/views/snippets/_snippet.html.haml b/app/views/snippets/_snippet.html.haml index a576500c15d..77d9d211d8d 100644 --- a/app/views/snippets/_snippet.html.haml +++ b/app/views/snippets/_snippet.html.haml @@ -1,8 +1,16 @@ %tr %td + - if snippet.private? + %i.icon-lock + - else + %i.icon-globe = image_tag gravatar_icon(snippet.author_email), class: "avatar s24" - %a{href: project_snippet_path(snippet.project, snippet)} - %strong= truncate(snippet.title, length: 60) + - if snippet.project_id? + %a{href: project_snippet_path(snippet.project, snippet)} + %strong= truncate(snippet.title, length: 60) + - else + %a{href: snippet_path(snippet)} + %strong= truncate(snippet.title, length: 60) %td = snippet.file_name %td @@ -11,3 +19,6 @@ = snippet.expires_at.to_date.to_s(:short) - else Never + %td + - if snippet.project_id? + = link_to snippet.project.name, project_path(snippet.project) diff --git a/app/views/snippets/_snippets.html.haml b/app/views/snippets/_snippets.html.haml new file mode 100644 index 00000000000..8162c546ea7 --- /dev/null +++ b/app/views/snippets/_snippets.html.haml @@ -0,0 +1,13 @@ +%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. diff --git a/app/views/snippets/edit.html.haml b/app/views/snippets/edit.html.haml index f81c0b8bc64..1b88a85faf1 100644 --- a/app/views/snippets/edit.html.haml +++ b/app/views/snippets/edit.html.haml @@ -1 +1 @@ -= render "snippets/form" += render "snippets/form", url: snippet_path(@snippet) diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml index bacf23d8f8d..2c00dd465db 100644 --- a/app/views/snippets/index.html.haml +++ b/app/views/snippets/index.html.haml @@ -1,19 +1,17 @@ %h3.page_title Snippets %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 - - 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 -%br -%table - %thead - %tr - %th Title - %th File Name - %th Expires At - = render @snippets - - if @snippets.empty? - %tr - %td{colspan: 3} - %h3.nothing_here_message Nothing here. +%hr +.row + .span3 + %ul.nav.nav-pills.nav-stacked + = nav_tab :scope, nil do + = link_to "All", snippets_path + = nav_tab :scope, 'projects' do + = link_to "Projects", snippets_path(scope: 'projects') + + .span9 + = render 'snippets' diff --git a/app/views/snippets/new.html.haml b/app/views/snippets/new.html.haml index f81c0b8bc64..90e0a1f79da 100644 --- a/app/views/snippets/new.html.haml +++ b/app/views/snippets/new.html.haml @@ -1 +1 @@ -= render "snippets/form" += render "snippets/form", url: snippets_path(@snippet) diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index 12534edf8ba..18348fb1067 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -1,9 +1,13 @@ %h3.page_title + - if @snippet.private? + %i.icon-lock + - else + %i.icon-globe + = @snippet.title %small= @snippet.file_name - - if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user - = link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right", title: 'Edit Snippet' + - if @snippet.author == current_user + = link_to "Edit", edit_snippet_path(@snippet), class: "btn btn-small pull-right", title: 'Edit Snippet' %br %div= render 'blob' -%div#notes= render "notes/notes_with_form" diff --git a/app/views/snippets/user_index.html.haml b/app/views/snippets/user_index.html.haml new file mode 100644 index 00000000000..2f2cce26af4 --- /dev/null +++ b/app/views/snippets/user_index.html.haml @@ -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' -- cgit v1.2.1 From 9bd1983e167c7a040565d8e03a20364455bddd59 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 02:02:08 +0400 Subject: Search link removed. Will be implemented later --- app/views/layouts/snippets.html.haml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/views/layouts/snippets.html.haml b/app/views/layouts/snippets.html.haml index 0675ad55845..73b502e9132 100644 --- a/app/views/layouts/snippets.html.haml +++ b/app/views/layouts/snippets.html.haml @@ -18,7 +18,5 @@ = nav_link(path: 'snippets#index') do = link_to snippets_path do Discover snippets - = nav_link(path: 'search#show') do - = link_to "Search", search_path .content= yield -- cgit v1.2.1 From e90aebe259b1f81cb2523099cab4626b9276e751 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 02:17:03 +0400 Subject: Personal snippets controlelr refactored --- app/controllers/snippets_controller.rb | 59 ++++++++++++++++++---------------- app/models/ability.rb | 5 ++- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index bb5fffca33c..2062ceafa9c 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -1,13 +1,6 @@ -class SnippetsController < ProjectResourceController - before_filter :module_enabled +class SnippetsController < ApplicationController 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 before_filter :authorize_modify_snippet!, only: [:edit, :update] @@ -17,22 +10,39 @@ class SnippetsController < ProjectResourceController respond_to :html 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 def new - @snippet = @project.snippets.new + @snippet = PersonalSnippet.new end def create - @snippet = @project.snippets.new(params[:snippet]) + @snippet = PersonalSnippet.new(params[:personal_snippet]) @snippet.author = current_user @snippet.save if @snippet.valid? - redirect_to [@project, @snippet] + redirect_to snippet_path(@snippet) else - respond_with(@snippet) + respond_with @snippet end end @@ -40,27 +50,24 @@ class SnippetsController < ProjectResourceController end def update - @snippet.update_attributes(params[:snippet]) + @snippet.update_attributes(params[:personal_snippet]) if @snippet.valid? - redirect_to [@project, @snippet] + redirect_to snippet_path(@snippet) else - respond_with(@snippet) + 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_snippet, @snippet) + return access_denied! unless can?(current_user, :admin_personal_snippet, @snippet) @snippet.destroy - redirect_to project_snippet_path(@project) + redirect_to snippets_path end def raw @@ -75,18 +82,14 @@ class SnippetsController < ProjectResourceController protected def snippet - @snippet ||= @project.snippets.find(params[:id]) + @snippet ||= PersonalSnippet.find(params[:id]) end 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 def authorize_admin_snippet! - return render_404 unless can?(current_user, :admin_snippet, @snippet) - end - - def module_enabled - return render_404 unless @project.snippets_enabled + return render_404 unless can?(current_user, :admin_personal_snippet, @snippet) end end diff --git a/app/models/ability.rb b/app/models/ability.rb index 928b36e6c80..2dadb584460 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -8,7 +8,7 @@ class Ability when "Issue" then issue_abilities(user, subject) when "Note" then note_abilities(user, subject) when "ProjectSnippet" then project_snippet_abilities(user, subject) - when "Snippet" then snippet_abilities(user, subject) + when "PersonalSnippet" then personal_snippet_abilities(user, subject) when "MergeRequest" then merge_request_abilities(user, subject) when "Group", "Namespace" then group_abilities(user, subject) when "UserTeam" then user_team_abilities(user, subject) @@ -135,8 +135,7 @@ class Ability rules.flatten end - - [:issue, :note, :project_snippet, :snippet, :merge_request].each do |name| + [:issue, :note, :project_snippet, :personal_snippet, :merge_request].each do |name| define_method "#{name}_abilities" do |user, subject| if subject.author == user [ -- cgit v1.2.1 From 4be12be62a9dc30faecff139684f7537f0726d45 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 02:17:20 +0400 Subject: Routes fixed --- config/routes.rb | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index f3632e64d61..4501d79e650 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -38,6 +38,16 @@ Gitlab::Application.routes.draw do get 'help/web_hooks' => 'help#web_hooks' get 'help/workflow' => 'help#workflow' + # + # Global snippets + # + resources :snippets do + member do + get "raw" + end + end + match "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ } + # # Public namespace # @@ -100,14 +110,6 @@ Gitlab::Application.routes.draw do get "errors/githost" - resources :snippets do - member do - get "raw" - get "my" - end - end - match "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ } - # # Profile Area # -- cgit v1.2.1 From 8f08fbfd9f768b885c631bdc8bc8ad202c6827a0 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 02:17:38 +0400 Subject: Tests for personal snippets added --- features/snippets/discover_snippets.feature | 10 +++++ features/snippets/snippets.feature | 28 ++++++++++++ features/snippets/user_snippets.feature | 22 ++++++++++ features/steps/shared/paths.rb | 8 ++++ features/steps/shared/snippet.rb | 19 +++++++++ features/steps/snippets/discover_snippets.rb | 17 ++++++++ features/steps/snippets/snippets.rb | 64 ++++++++++++++++++++++++++++ features/steps/snippets/user_snippets.rb | 41 ++++++++++++++++++ 8 files changed, 209 insertions(+) create mode 100644 features/snippets/discover_snippets.feature create mode 100644 features/snippets/snippets.feature create mode 100644 features/snippets/user_snippets.feature create mode 100644 features/steps/shared/snippet.rb create mode 100644 features/steps/snippets/discover_snippets.rb create mode 100644 features/steps/snippets/snippets.rb create mode 100644 features/steps/snippets/user_snippets.rb diff --git a/features/snippets/discover_snippets.feature b/features/snippets/discover_snippets.feature new file mode 100644 index 00000000000..d6fd2cd7808 --- /dev/null +++ b/features/snippets/discover_snippets.feature @@ -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 diff --git a/features/snippets/snippets.feature b/features/snippets/snippets.feature new file mode 100644 index 00000000000..ebb4a7c0719 --- /dev/null +++ b/features/snippets/snippets.feature @@ -0,0 +1,28 @@ +Feature: 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 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 diff --git a/features/snippets/user_snippets.feature b/features/snippets/user_snippets.feature new file mode 100644 index 00000000000..4c8a91501c4 --- /dev/null +++ b/features/snippets/user_snippets.feature @@ -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 diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 42004df426e..08da0908384 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -267,6 +267,14 @@ module SharedPaths 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 @project.repository.root_ref end diff --git a/features/steps/shared/snippet.rb b/features/steps/shared/snippet.rb new file mode 100644 index 00000000000..32cc68c2852 --- /dev/null +++ b/features/steps/shared/snippet.rb @@ -0,0 +1,19 @@ +module SharedProject + 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 diff --git a/features/steps/snippets/discover_snippets.rb b/features/steps/snippets/discover_snippets.rb new file mode 100644 index 00000000000..ff2e4952c36 --- /dev/null +++ b/features/steps/snippets/discover_snippets.rb @@ -0,0 +1,17 @@ +class DiscoverSnippets < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + 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 diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb new file mode 100644 index 00000000000..87a499821dd --- /dev/null +++ b/features/steps/snippets/snippets.rb @@ -0,0 +1,64 @@ +class Snippets < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + 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_selector(: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 diff --git a/features/steps/snippets/user_snippets.rb b/features/steps/snippets/user_snippets.rb new file mode 100644 index 00000000000..0920b56e38d --- /dev/null +++ b/features/steps/snippets/user_snippets.rb @@ -0,0 +1,41 @@ +class UserSnippets < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + 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 -- cgit v1.2.1 From 3d3e40c251179654d136d9838087f275c549e827 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 02:18:03 +0400 Subject: Personal snippet model added --- app/models/personal_snippet.rb | 18 ++++++++++++++++++ spec/factories.rb | 7 +++++++ 2 files changed, 25 insertions(+) create mode 100644 app/models/personal_snippet.rb diff --git a/app/models/personal_snippet.rb b/app/models/personal_snippet.rb new file mode 100644 index 00000000000..d581c6092aa --- /dev/null +++ b/app/models/personal_snippet.rb @@ -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 diff --git a/spec/factories.rb b/spec/factories.rb index 67caec9f851..2e6fdbf11ab 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -204,6 +204,13 @@ FactoryGirl.define do file_name end + factory :personal_snippet do + author + title + content + file_name + end + factory :snippet do author title -- cgit v1.2.1 From ed4dcf7484149c4432597c81b9ce1324010e036a Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 02:18:39 +0400 Subject: View improved. Pagination added --- app/views/snippets/_snippets.html.haml | 2 ++ app/views/snippets/index.html.haml | 12 +++--------- app/views/snippets/show.html.haml | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/app/views/snippets/_snippets.html.haml b/app/views/snippets/_snippets.html.haml index 8162c546ea7..192cb6aa94a 100644 --- a/app/views/snippets/_snippets.html.haml +++ b/app/views/snippets/_snippets.html.haml @@ -11,3 +11,5 @@ %tr %td{colspan: 4} %h3.nothing_here_message Nothing here. + += paginate @snippets diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml index 2c00dd465db..97f7b39877e 100644 --- a/app/views/snippets/index.html.haml +++ b/app/views/snippets/index.html.haml @@ -1,17 +1,11 @@ %h3.page_title - Snippets + Public snippets %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", snippets_path - = nav_tab :scope, 'projects' do - = link_to "Projects", snippets_path(scope: 'projects') - - .span9 + .span12 = render 'snippets' + diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index 18348fb1067..37a1181dea3 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -2,7 +2,7 @@ - if @snippet.private? %i.icon-lock - else - %i.icon-globe + %i.icon-globe.public-snippet = @snippet.title %small= @snippet.file_name -- cgit v1.2.1 From 611ac727450b4fb9214e428cd91f7913d48ed7d8 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 02:46:56 +0400 Subject: Tests for private snippet fixed --- app/views/snippets/show.html.haml | 2 +- features/steps/snippets/snippets.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index 37a1181dea3..18348fb1067 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -2,7 +2,7 @@ - if @snippet.private? %i.icon-lock - else - %i.icon-globe.public-snippet + %i.icon-globe = @snippet.title %small= @snippet.file_name diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb index 87a499821dd..f20832cb1f1 100644 --- a/features/steps/snippets/snippets.rb +++ b/features/steps/snippets/snippets.rb @@ -51,7 +51,7 @@ class Snippets < Spinach::FeatureSteps end Then 'I should see "Personal snippet one" public' do - page.should have_selector(:xpath, "//i[@class='public-snippet']") + page.should have_no_xpath("//i[@class='public-snippet']") end And 'I visit snippet page "Personal snippet one"' do -- cgit v1.2.1 From d4543eb5a71bd3aa5bfc24f9fadf07e4fe3d461d Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 11:20:14 +0400 Subject: Tests fixed --- app/controllers/projects/snippets_controller.rb | 4 +-- app/models/ability.rb | 8 ++--- lib/api/projects.rb | 6 ++-- spec/helpers/gitlab_markdown_helper_spec.rb | 39 +++++++++++++++++++++++-- spec/models/project_spec.rb | 2 +- spec/requests/api/notes_spec.rb | 2 +- spec/requests/api/projects_spec.rb | 2 +- 7 files changed, 49 insertions(+), 14 deletions(-) diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index ebff5039ffa..cd14c08c779 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -23,11 +23,11 @@ class Projects::SnippetsController < Projects::ApplicationController end def new - @snippet = @project.snippets.new + @snippet = @project.snippets.build end def create - @snippet = @project.snippets.new(params[:project_snippet]) + @snippet = @project.snippets.build(params[:project_snippet]) @snippet.author = current_user @snippet.save diff --git a/app/models/ability.rb b/app/models/ability.rb index 2dadb584460..b86a4b5a044 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -55,7 +55,7 @@ class Ability :read_wiki, :read_issue, :read_milestone, - :read_snippet, + :read_project_snippet, :read_team_member, :read_merge_request, :read_note, @@ -68,7 +68,7 @@ class Ability def project_report_rules project_guest_rules + [ :download_code, - :write_snippet + :write_project_snippet ] end @@ -84,11 +84,11 @@ class Ability project_dev_rules + [ :push_code_to_protected_branches, :modify_issue, - :modify_snippet, + :modify_project_snippet, :modify_merge_request, :admin_issue, :admin_milestone, - :admin_snippet, + :admin_project_snippet, :admin_team_member, :admin_merge_request, :admin_note, diff --git a/lib/api/projects.rb b/lib/api/projects.rb index d4f50fda1b5..3699971f25c 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -408,7 +408,7 @@ module Gitlab # Example Request: # POST /projects/:id/snippets post ":id/snippets" do - authorize! :write_snippet, user_project + authorize! :write_project_snippet, user_project required_attributes! [:title, :file_name, :code] attrs = attributes_for_keys [:title, :file_name] @@ -437,7 +437,7 @@ module Gitlab # PUT /projects/:id/snippets/:snippet_id put ":id/snippets/:snippet_id" do @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[:expires_at] = params[:lifetime] if params[:lifetime].present? @@ -460,7 +460,7 @@ module Gitlab delete ":id/snippets/:snippet_id" do begin @snippet = user_project.snippets.find(params[:snippet_id]) - authorize! :modify_snippet, user_project + authorize! :modify_project_snippet, @snippet @snippet.destroy rescue end diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index b9025026c1b..94ccefa79f9 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -10,7 +10,7 @@ describe GitlabMarkdownHelper do let(:commit) { CommitDecorator.decorate(project.repository.commit) } let(:issue) { create(:issue, 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 } before do @@ -190,8 +190,43 @@ describe GitlabMarkdownHelper do describe "referencing a snippet" do let(:object) { snippet } 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 [^\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 describe "referencing multiple objects" do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 9423c7de6ec..17033973dfe 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -34,7 +34,7 @@ describe Project do it { should have_many(:milestones).dependent(:destroy) } it { should have_many(:users_projects).dependent(:destroy) } it { should have_many(:notes).dependent(:destroy) } - it { should have_many(:snippets).dependent(:destroy) } + it { should have_many(:project_snippets).class_name('ProjectSnippet').dependent(:destroy) } it { should have_many(:deploy_keys).dependent(:destroy) } it { should have_many(:hooks).dependent(:destroy) } it { should have_many(:wikis).dependent(:destroy) } diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb index 901640834f2..0df3189ca0c 100644 --- a/spec/requests/api/notes_spec.rb +++ b/spec/requests/api/notes_spec.rb @@ -7,7 +7,7 @@ describe Gitlab::API do let!(:project) { create(:project, namespace: user.namespace ) } let!(:issue) { create(:issue, 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!(:merge_request_note) { create(:note, noteable: merge_request, project: project, author: user) } let!(:snippet_note) { create(:note, noteable: snippet, project: project, author: user) } diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index cddb7264018..c5a74ed9e0d 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -9,7 +9,7 @@ describe Gitlab::API do let(:admin) { create(:admin) } let!(:project) { create(:project, namespace: user.namespace ) } 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_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) } let(:key) { create(:key, project: project) } -- cgit v1.2.1 From 033037a059c9229df310e3508f9c50beb676bf00 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 13:14:12 +0400 Subject: Typo in class name fixed --- features/steps/shared/snippet.rb | 4 +++- features/steps/snippets/discover_snippets.rb | 2 +- features/steps/snippets/snippets.rb | 1 + features/steps/snippets/user_snippets.rb | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/features/steps/shared/snippet.rb b/features/steps/shared/snippet.rb index 32cc68c2852..543e43196a5 100644 --- a/features/steps/shared/snippet.rb +++ b/features/steps/shared/snippet.rb @@ -1,4 +1,6 @@ -module SharedProject +module SharedSnippet + include Spinach::DSL + And 'I have public "Personal snippet one" snippet' do create(:personal_snippet, title: "Personal snippet one", diff --git a/features/steps/snippets/discover_snippets.rb b/features/steps/snippets/discover_snippets.rb index ff2e4952c36..3afe019adf6 100644 --- a/features/steps/snippets/discover_snippets.rb +++ b/features/steps/snippets/discover_snippets.rb @@ -1,7 +1,7 @@ class DiscoverSnippets < Spinach::FeatureSteps include SharedAuthentication include SharedPaths - include SharedProject + include SharedSnippet Then 'I should see "Personal snippet one" in snippets' do page.should have_content "Personal snippet one" diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb index f20832cb1f1..0ab636543a9 100644 --- a/features/steps/snippets/snippets.rb +++ b/features/steps/snippets/snippets.rb @@ -2,6 +2,7 @@ class Snippets < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedProject + include SharedSnippet Given 'I click link "Personal snippet one"' do click_link "Personal snippet one" diff --git a/features/steps/snippets/user_snippets.rb b/features/steps/snippets/user_snippets.rb index 0920b56e38d..15d6da6db3d 100644 --- a/features/steps/snippets/user_snippets.rb +++ b/features/steps/snippets/user_snippets.rb @@ -1,7 +1,7 @@ class UserSnippets < Spinach::FeatureSteps include SharedAuthentication include SharedPaths - include SharedProject + include SharedSnippet Given 'I visit my snippets page' do visit user_snippets_path(current_user) -- cgit v1.2.1 From e3351287b4284af95390835bc75a6c3c461f04ba Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 14:22:14 +0400 Subject: Permissions for Project Snippet fixed --- app/controllers/projects/snippets_controller.rb | 12 ++++++------ app/views/projects/snippets/index.html.haml | 2 +- app/views/projects/snippets/show.html.haml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index cd14c08c779..92e88de6790 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -3,16 +3,16 @@ class Projects::SnippetsController < Projects::ApplicationController before_filter :snippet, only: [:show, :edit, :destroy, :update, :raw] # Allow read any snippet - before_filter :authorize_read_snippet! + before_filter :authorize_read_project_snippet! # Allow write(create) snippet - before_filter :authorize_write_snippet!, only: [:new, :create] + before_filter :authorize_write_project_snippet!, only: [:new, :create] # Allow modify snippet - before_filter :authorize_modify_snippet!, only: [:edit, :update] + before_filter :authorize_modify_project_snippet!, only: [:edit, :update] # Allow destroy snippet - before_filter :authorize_admin_snippet!, only: [:destroy] + before_filter :authorize_admin_project_snippet!, only: [:destroy] layout 'project_resource' @@ -80,11 +80,11 @@ class Projects::SnippetsController < Projects::ApplicationController @snippet ||= @project.snippets.find(params[:id]) end - def authorize_modify_snippet! + def authorize_modify_project_snippet! return render_404 unless can?(current_user, :modify_project_snippet, @snippet) end - def authorize_admin_snippet! + def authorize_admin_project_snippet! return render_404 unless can?(current_user, :admin_project_snippet, @snippet) end diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml index 12760d377f3..5971e3ffaac 100644 --- a/app/views/projects/snippets/index.html.haml +++ b/app/views/projects/snippets/index.html.haml @@ -2,7 +2,7 @@ Snippets %small share code pastes with others out of git repository - - if can? current_user, :write_snippet, @project + - 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 diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index e325c3d84e6..db5a721dc45 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -1,7 +1,7 @@ %h3.page_title = @snippet.title %small= @snippet.file_name - - if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user + - 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 -- cgit v1.2.1 From 3e695acfa2f4035431cb325645b3114d06e43105 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 15:58:09 +0400 Subject: Notes fixed --- Gemfile.lock | 28 ++++++++++++++-------------- app/models/event.rb | 4 ++++ app/models/note.rb | 6 ++++++ app/models/snippet.rb | 1 + app/views/events/event/_note.html.haml | 4 ++++ 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f2800771f61..ffbef9488e4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,17 @@ +GIT + remote: https://github.com/ctran/annotate_models.git + revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e + specs: + annotate (2.6.0.beta1) + activerecord (>= 2.3.0) + rake (>= 0.8.7) + +GIT + remote: https://github.com/gitlabhq/raphael-rails.git + revision: cb2c92a040b9b941a5f1aa1ea866cc26e944fe58 + specs: + raphael-rails (2.1.0) + GIT remote: https://github.com/gollum/gollum.git revision: 5dcd3c8c8f68158e43ff79861279088ee56d0ebe @@ -15,20 +29,6 @@ GIT stringex (~> 1.5.1) useragent (~> 0.4.16) -GIT - remote: https://github.com/ctran/annotate_models.git - revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e - specs: - annotate (2.6.0.beta1) - activerecord (>= 2.3.0) - rake (>= 0.8.7) - -GIT - remote: https://github.com/gitlabhq/raphael-rails.git - revision: cb2c92a040b9b941a5f1aa1ea866cc26e944fe58 - specs: - raphael-rails (2.1.0) - GEM remote: https://rubygems.org/ specs: diff --git a/app/models/event.rb b/app/models/event.rb index ae14454c59a..d39445c4ffe 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -259,6 +259,10 @@ class Event < ActiveRecord::Base target.noteable_type == "Commit" end + def note_project_snippet? + target.noteable_type == "Snippet" + end + def note_target target.noteable end diff --git a/app/models/note.rb b/app/models/note.rb index f56f999fda1..2f3b059918a 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -170,4 +170,10 @@ class Note < ActiveRecord::Base "wall" 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 diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 5d09c6b6e47..1b37ffe8339 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -20,6 +20,7 @@ class Snippet < ActiveRecord::Base attr_accessible :title, :content, :file_name, :expires_at, :private belongs_to :author, class_name: "User" + has_many :notes, as: :noteable, dependent: :destroy delegate :name, :email, to: :author, prefix: true, allow_nil: true diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml index 8bcfa95ff62..81b8ff9bf24 100644 --- a/app/views/events/event/_note.html.haml +++ b/app/views/events/event/_note.html.haml @@ -5,6 +5,10 @@ - if event.note_commit? = event.note_target_type = 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 = link_to [event.project, event.note_target] do %strong -- cgit v1.2.1 From 0359f1d9ec286fbbf58027e2cdb2a307806f54da Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 16:28:39 +0400 Subject: Codestyle improved --- app/controllers/projects/snippets_controller.rb | 7 ++----- app/controllers/snippets_controller.rb | 11 ++++------- config/routes.rb | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 92e88de6790..1165fa1c583 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -29,9 +29,8 @@ class Projects::SnippetsController < Projects::ApplicationController def create @snippet = @project.snippets.build(params[:project_snippet]) @snippet.author = current_user - @snippet.save - if @snippet.valid? + if @snippet.save redirect_to project_snippet_path(@project, @snippet) else respond_with(@snippet) @@ -42,9 +41,7 @@ class Projects::SnippetsController < Projects::ApplicationController end def update - @snippet.update_attributes(params[:project_snippet]) - - if @snippet.valid? + if @snippet.update_attributes(params[:project_snippet]) redirect_to project_snippet_path(@project, @snippet) else respond_with(@snippet) diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 2062ceafa9c..7c96b82379c 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -31,15 +31,14 @@ class SnippetsController < ApplicationController end def new - @snippet = PersonalSnippet.new + @snippet = PersonalSnippet.build end def create - @snippet = PersonalSnippet.new(params[:personal_snippet]) + @snippet = PersonalSnippet.build(params[:personal_snippet]) @snippet.author = current_user - @snippet.save - if @snippet.valid? + if @snippet.save redirect_to snippet_path(@snippet) else respond_with @snippet @@ -50,9 +49,7 @@ class SnippetsController < ApplicationController end def update - @snippet.update_attributes(params[:personal_snippet]) - - if @snippet.valid? + if @snippet.update_attributes(params[:personal_snippet]) redirect_to snippet_path(@snippet) else respond_with @snippet diff --git a/config/routes.rb b/config/routes.rb index 4501d79e650..97436025965 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -46,7 +46,7 @@ Gitlab::Application.routes.draw do get "raw" end end - match "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ } + get "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ } # # Public namespace -- cgit v1.2.1 From 03de5a5ceea394e03120dcda709058fb0f2c1ab6 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 16:35:57 +0400 Subject: Typo in realtion name fixed --- spec/models/project_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 17033973dfe..00ca0bf5e2e 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -34,7 +34,7 @@ describe Project do it { should have_many(:milestones).dependent(:destroy) } it { should have_many(:users_projects).dependent(:destroy) } it { should have_many(:notes).dependent(:destroy) } - it { should have_many(:project_snippets).class_name('ProjectSnippet').dependent(:destroy) } + it { should have_many(:snippets).class_name('ProjectSnippet').dependent(:destroy) } it { should have_many(:deploy_keys).dependent(:destroy) } it { should have_many(:hooks).dependent(:destroy) } it { should have_many(:wikis).dependent(:destroy) } -- cgit v1.2.1 From e0af7cefb4c92b474d14116b40927d70c13e78cc Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 25 Mar 2013 20:32:10 +0400 Subject: Typos fixed --- app/controllers/snippets_controller.rb | 4 ++-- features/snippets/snippets.feature | 2 +- features/steps/snippets/snippets.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 7c96b82379c..70525beea15 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -31,11 +31,11 @@ class SnippetsController < ApplicationController end def new - @snippet = PersonalSnippet.build + @snippet = PersonalSnippet.new end def create - @snippet = PersonalSnippet.build(params[:personal_snippet]) + @snippet = PersonalSnippet.new(params[:personal_snippet]) @snippet.author = current_user if @snippet.save diff --git a/features/snippets/snippets.feature b/features/snippets/snippets.feature index ebb4a7c0719..1119defa17d 100644 --- a/features/snippets/snippets.feature +++ b/features/snippets/snippets.feature @@ -1,4 +1,4 @@ -Feature: Snippets +Feature: Snippets Feature Background: Given I sign in as a user And I have public "Personal snippet one" snippet diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb index 0ab636543a9..b185f605728 100644 --- a/features/steps/snippets/snippets.rb +++ b/features/steps/snippets/snippets.rb @@ -1,4 +1,4 @@ -class Snippets < Spinach::FeatureSteps +class SnippetsFeature < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedProject -- cgit v1.2.1