Commit 5b35000f16201bd631f161ef6d79b0a77dc2c27b

Authored by Andrew8xx8
1 parent bc7c5f87

Snippets feature refactored. Tests now use spinach

app/controllers/projects/snippets_controller.rb
@@ -27,12 +27,12 @@ class Projects::SnippetsController < Projects::ApplicationController @@ -27,12 +27,12 @@ class Projects::SnippetsController < Projects::ApplicationController
27 end 27 end
28 28
29 def create 29 def create
30 - @snippet = @project.snippets.new(params[:snippet]) 30 + @snippet = @project.snippets.new(params[:project_snippet])
31 @snippet.author = current_user 31 @snippet.author = current_user
32 @snippet.save 32 @snippet.save
33 33
34 if @snippet.valid? 34 if @snippet.valid?
35 - redirect_to [@project, @snippet] 35 + redirect_to project_snippet_path(@project, @snippet)
36 else 36 else
37 respond_with(@snippet) 37 respond_with(@snippet)
38 end 38 end
@@ -42,10 +42,10 @@ class Projects::SnippetsController < Projects::ApplicationController @@ -42,10 +42,10 @@ class Projects::SnippetsController < Projects::ApplicationController
42 end 42 end
43 43
44 def update 44 def update
45 - @snippet.update_attributes(params[:snippet]) 45 + @snippet.update_attributes(params[:project_snippet])
46 46
47 if @snippet.valid? 47 if @snippet.valid?
48 - redirect_to [@project, @snippet] 48 + redirect_to project_snippet_path(@project, @snippet)
49 else 49 else
50 respond_with(@snippet) 50 respond_with(@snippet)
51 end 51 end
@@ -58,7 +58,7 @@ class Projects::SnippetsController < Projects::ApplicationController @@ -58,7 +58,7 @@ class Projects::SnippetsController < Projects::ApplicationController
58 end 58 end
59 59
60 def destroy 60 def destroy
61 - return access_denied! unless can?(current_user, :admin_snippet, @snippet) 61 + return access_denied! unless can?(current_user, :admin_project_snippet, @snippet)
62 62
63 @snippet.destroy 63 @snippet.destroy
64 64
@@ -81,11 +81,11 @@ class Projects::SnippetsController < Projects::ApplicationController @@ -81,11 +81,11 @@ class Projects::SnippetsController < Projects::ApplicationController
81 end 81 end
82 82
83 def authorize_modify_snippet! 83 def authorize_modify_snippet!
84 - return render_404 unless can?(current_user, :modify_snippet, @snippet) 84 + return render_404 unless can?(current_user, :modify_project_snippet, @snippet)
85 end 85 end
86 86
87 def authorize_admin_snippet! 87 def authorize_admin_snippet!
88 - return render_404 unless can?(current_user, :admin_snippet, @snippet) 88 + return render_404 unless can?(current_user, :admin_project_snippet, @snippet)
89 end 89 end
90 90
91 def module_enabled 91 def module_enabled
app/controllers/snippets_controller.rb
@@ -60,7 +60,7 @@ class SnippetsController < ProjectResourceController @@ -60,7 +60,7 @@ class SnippetsController < ProjectResourceController
60 60
61 @snippet.destroy 61 @snippet.destroy
62 62
63 - redirect_to project_snippets_path(@project) 63 + redirect_to project_snippet_path(@project)
64 end 64 end
65 65
66 def raw 66 def raw
app/models/ability.rb
@@ -7,6 +7,7 @@ class Ability @@ -7,6 +7,7 @@ class Ability
7 when "Project" then project_abilities(user, subject) 7 when "Project" then project_abilities(user, subject)
8 when "Issue" then issue_abilities(user, subject) 8 when "Issue" then issue_abilities(user, subject)
9 when "Note" then note_abilities(user, subject) 9 when "Note" then note_abilities(user, subject)
  10 + when "ProjectSnippet" then project_snippet_abilities(user, subject)
10 when "Snippet" then snippet_abilities(user, subject) 11 when "Snippet" then snippet_abilities(user, subject)
11 when "MergeRequest" then merge_request_abilities(user, subject) 12 when "MergeRequest" then merge_request_abilities(user, subject)
12 when "Group", "Namespace" then group_abilities(user, subject) 13 when "Group", "Namespace" then group_abilities(user, subject)
@@ -135,7 +136,7 @@ class Ability @@ -135,7 +136,7 @@ class Ability
135 end 136 end
136 137
137 138
138 - [:issue, :note, :snippet, :merge_request].each do |name| 139 + [:issue, :note, :project_snippet, :snippet, :merge_request].each do |name|
139 define_method "#{name}_abilities" do |user, subject| 140 define_method "#{name}_abilities" do |user, subject|
140 if subject.author == user 141 if subject.author == user
141 [ 142 [
app/models/project.rb
@@ -50,7 +50,7 @@ class Project < ActiveRecord::Base @@ -50,7 +50,7 @@ class Project < ActiveRecord::Base
50 has_many :milestones, dependent: :destroy 50 has_many :milestones, dependent: :destroy
51 has_many :users_projects, dependent: :destroy 51 has_many :users_projects, dependent: :destroy
52 has_many :notes, dependent: :destroy 52 has_many :notes, dependent: :destroy
53 - has_many :snippets, dependent: :destroy 53 + has_many :snippets, dependent: :destroy, class_name: "ProjectSnippet"
54 has_many :deploy_keys, dependent: :destroy, class_name: "Key", foreign_key: "project_id" 54 has_many :deploy_keys, dependent: :destroy, class_name: "Key", foreign_key: "project_id"
55 has_many :hooks, dependent: :destroy, class_name: "ProjectHook" 55 has_many :hooks, dependent: :destroy, class_name: "ProjectHook"
56 has_many :wikis, dependent: :destroy 56 has_many :wikis, dependent: :destroy
app/views/projects/snippets/_form.html.haml
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 = @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}" 2 = @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}"
3 %hr 3 %hr
4 .snippet-form-holder 4 .snippet-form-holder
5 - = form_for [@project, @snippet] do |f| 5 + = form_for [@project, @snippet], as: :project_snippet, url: url do |f|
6 -if @snippet.errors.any? 6 -if @snippet.errors.any?
7 .alert.alert-error 7 .alert.alert-error
8 %ul 8 %ul
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 = f.submit 'Save', class: "btn-save btn" 30 = f.submit 'Save', class: "btn-save btn"
31 = link_to "Cancel", project_snippets_path(@project), class: " btn" 31 = link_to "Cancel", project_snippets_path(@project), class: " btn"
32 - unless @snippet.new_record? 32 - unless @snippet.new_record?
33 - .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}" 33 + .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}"
34 34
35 35
36 :javascript 36 :javascript
app/views/projects/snippets/edit.html.haml
1 -= render "snippets/form" 1 += render "projects/snippets/form", url: project_snippet_path(@project, @snippet)
app/views/projects/snippets/index.html.haml
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 %th Title 12 %th Title
13 %th File Name 13 %th File Name
14 %th Expires At 14 %th Expires At
15 - = render @snippets 15 + = render partial: "projects/snippets/snippet", collection: @snippets
16 - if @snippets.empty? 16 - if @snippets.empty?
17 %tr 17 %tr
18 %td{colspan: 3} 18 %td{colspan: 3}
app/views/projects/snippets/new.html.haml
1 -= render "snippets/form" 1 += render "projects/snippets/form", url: project_snippets_path(@project, @snippet)
app/views/projects/snippets/show.html.haml
@@ -5,5 +5,5 @@ @@ -5,5 +5,5 @@
5 = link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right", title: 'Edit Snippet' 5 = link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right", title: 'Edit Snippet'
6 6
7 %br 7 %br
8 -%div= render 'blob' 8 +%div= render 'projects/snippets/blob'
9 %div#notes= render "notes/notes_with_form" 9 %div#notes= render "notes/notes_with_form"
config/routes.rb
@@ -177,6 +177,14 @@ Gitlab::Application.routes.draw do @@ -177,6 +177,14 @@ Gitlab::Application.routes.draw do
177 match "/compare/:from...:to" => "compare#show", as: "compare", 177 match "/compare/:from...:to" => "compare#show", as: "compare",
178 :via => [:get, :post], constraints: {from: /.+/, to: /.+/} 178 :via => [:get, :post], constraints: {from: /.+/, to: /.+/}
179 179
  180 + scope module: :projects do
  181 + resources :snippets do
  182 + member do
  183 + get "raw"
  184 + end
  185 + end
  186 + end
  187 +
180 resources :wikis, only: [:show, :edit, :destroy, :create] do 188 resources :wikis, only: [:show, :edit, :destroy, :create] do
181 collection do 189 collection do
182 get :pages 190 get :pages
@@ -244,21 +252,12 @@ Gitlab::Application.routes.draw do @@ -244,21 +252,12 @@ Gitlab::Application.routes.draw do
244 end 252 end
245 end 253 end
246 254
247 - scope module: :projects do  
248 - resources :snippets do  
249 - member do  
250 - get "raw"  
251 - end  
252 - end  
253 - end  
254 -  
255 resources :hooks, only: [:index, :create, :destroy] do 255 resources :hooks, only: [:index, :create, :destroy] do
256 member do 256 member do
257 get :test 257 get :test
258 end 258 end
259 end 259 end
260 260
261 -  
262 resources :team, controller: 'team_members', only: [:index] 261 resources :team, controller: 'team_members', only: [:index]
263 resources :milestones, except: [:destroy] 262 resources :milestones, except: [:destroy]
264 resources :labels, only: [:index] 263 resources :labels, only: [:index]
db/migrate/20130324172327_change_project_id_to_null_in_snipepts.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class ChangeProjectIdToNullInSnipepts < ActiveRecord::Migration
  2 + def up
  3 + change_column :snippets, :project_id, :integer, :null => true
  4 + end
  5 +
  6 + def down
  7 + change_column :snippets, :project_id, :integer, :null => false
  8 + end
  9 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended to check this file into your version control system. 12 # It's strongly recommended to check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(:version => 20130324151736) do 14 +ActiveRecord::Schema.define(:version => 20130324172327) do
15 15
16 create_table "events", :force => true do |t| 16 create_table "events", :force => true do |t|
17 t.string "target_type" 17 t.string "target_type"
@@ -185,7 +185,7 @@ ActiveRecord::Schema.define(:version =&gt; 20130324151736) do @@ -185,7 +185,7 @@ ActiveRecord::Schema.define(:version =&gt; 20130324151736) do
185 t.string "title" 185 t.string "title"
186 t.text "content" 186 t.text "content"
187 t.integer "author_id", :null => false 187 t.integer "author_id", :null => false
188 - t.integer "project_id", :null => false 188 + t.integer "project_id"
189 t.datetime "created_at", :null => false 189 t.datetime "created_at", :null => false
190 t.datetime "updated_at", :null => false 190 t.datetime "updated_at", :null => false
191 t.string "file_name" 191 t.string "file_name"
features/project/snippets.feature 0 → 100644
@@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
  1 +Feature: Project Snippets
  2 + Background:
  3 + Given I sign in as a user
  4 + And I own project "Shop"
  5 + And project "Shop" have "Snippet one" snippet
  6 + And project "Shop" have no "Snippet two" snippet
  7 + And I visit project "Shop" snippets page
  8 +
  9 + Scenario: I should see snippets
  10 + Given I visit project "Shop" snippets page
  11 + Then I should see "Snippet one" in snippets
  12 + And I should not see "Snippet two" in snippets
  13 +
  14 + Scenario: I create new project snippet
  15 + Given I click link "New Snippet"
  16 + And I submit new snippet "Snippet three"
  17 + Then I should see snippet "Snippet three"
  18 +
  19 + @javascript
  20 + Scenario: I comment on a snippet "Snippet one"
  21 + Given I visit snippet page "Snippet one"
  22 + And I leave a comment like "Good snippet!"
  23 + Then I should see comment "Good snippet!"
  24 +
  25 + Scenario: I update "Snippet one"
  26 + Given I visit snippet page "Snippet one"
  27 + And I click link "Edit"
  28 + And I submit new title "Snippet new title"
  29 + Then I should see "Snippet new title"
  30 +
  31 + Scenario: I destroy "Snippet one"
  32 + Given I visit snippet page "Snippet one"
  33 + And I click link "Edit"
  34 + And I click link "Destroy"
  35 + Then I should not see "Snippet one" in snippets
features/steps/project/project_snippets.rb 0 → 100644
@@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
  1 +class ProjectSnippets < Spinach::FeatureSteps
  2 + include SharedAuthentication
  3 + include SharedProject
  4 + include SharedNote
  5 + include SharedPaths
  6 +
  7 + And 'project "Shop" have "Snippet one" snippet' do
  8 + create(:project_snippet,
  9 + title: "Snippet one",
  10 + content: "Test content",
  11 + file_name: "snippet.rb",
  12 + project: project,
  13 + author: project.users.first)
  14 + end
  15 +
  16 + And 'project "Shop" have no "Snippet two" snippet' do
  17 + create(:snippet,
  18 + title: "Snippet two",
  19 + content: "Test content",
  20 + file_name: "snippet.rb",
  21 + author: project.users.first)
  22 + end
  23 +
  24 + Given 'I click link "New Snippet"' do
  25 + click_link "Add new snippet"
  26 + end
  27 +
  28 + Given 'I click link "Snippet one"' do
  29 + click_link "Snippet one"
  30 + end
  31 +
  32 + Then 'I should see "Snippet one" in snippets' do
  33 + page.should have_content "Snippet one"
  34 + end
  35 +
  36 + And 'I should not see "Snippet two" in snippets' do
  37 + page.should_not have_content "Snippet two"
  38 + end
  39 +
  40 + And 'I should not see "Snippet one" in snippets' do
  41 + page.should_not have_content "Snippet one"
  42 + end
  43 +
  44 + And 'I click link "Edit"' do
  45 + within ".page_title" do
  46 + click_link "Edit"
  47 + end
  48 + end
  49 +
  50 + And 'I click link "Destroy"' do
  51 + click_link "Destroy"
  52 + end
  53 +
  54 + And 'I submit new snippet "Snippet three"' do
  55 + fill_in "project_snippet_title", :with => "Snippet three"
  56 + select "forever", :from => "project_snippet_expires_at"
  57 + fill_in "project_snippet_file_name", :with => "my_snippet.rb"
  58 + within('.file-editor') do
  59 + find(:xpath, "//input[@id='project_snippet_content']").set 'Content of snippet three'
  60 + end
  61 + click_button "Save"
  62 + end
  63 +
  64 + Then 'I should see snippet "Snippet three"' do
  65 + page.should have_content "Snippet three"
  66 + page.should have_content "Content of snippet three"
  67 + end
  68 +
  69 + And 'I submit new title "Snippet new title"' do
  70 + fill_in "project_snippet_title", :with => "Snippet new title"
  71 + click_button "Save"
  72 + end
  73 +
  74 + Then 'I should see "Snippet new title"' do
  75 + page.should have_content "Snippet new title"
  76 + end
  77 +
  78 + And 'I leave a comment like "Good snippet!"' do
  79 + within('.js-main-target-form') do
  80 + fill_in "note_note", with: "Good snippet!"
  81 + click_button "Add Comment"
  82 + end
  83 + end
  84 +
  85 + Then 'I should see comment "Good snippet!"' do
  86 + page.should have_content "Good snippet!"
  87 + end
  88 +
  89 + And 'I visit snippet page "Snippet one"' do
  90 + visit project_snippet_path(project, project_snippet)
  91 + end
  92 +
  93 + def project
  94 + @project ||= Project.find_by_name!("Shop")
  95 + end
  96 +
  97 + def project_snippet
  98 + @project_snippet ||= ProjectSnippet.find_by_title!("Snippet One")
  99 + end
  100 +end
features/steps/shared/paths.rb
@@ -263,6 +263,10 @@ module SharedPaths @@ -263,6 +263,10 @@ module SharedPaths
263 visit project_wiki_path(@project, :home) 263 visit project_wiki_path(@project, :home)
264 end 264 end
265 265
  266 + Given 'I visit project "Shop" snippets page' do
  267 + visit project_snippets_path(project)
  268 + end
  269 +
266 def root_ref 270 def root_ref
267 @project.repository.root_ref 271 @project.repository.root_ref
268 end 272 end
spec/factories.rb
@@ -196,7 +196,7 @@ FactoryGirl.define do @@ -196,7 +196,7 @@ FactoryGirl.define do
196 user 196 user
197 end 197 end
198 198
199 - factory :snippet do 199 + factory :project_snippet do
200 project 200 project
201 author 201 author
202 title 202 title
@@ -204,6 +204,13 @@ FactoryGirl.define do @@ -204,6 +204,13 @@ FactoryGirl.define do
204 file_name 204 file_name
205 end 205 end
206 206
  207 + factory :snippet do
  208 + author
  209 + title
  210 + content
  211 + file_name
  212 + end
  213 +
207 factory :protected_branch do 214 factory :protected_branch do
208 name 215 name
209 project 216 project
spec/features/projects/snippets_spec.rb
@@ -1,101 +0,0 @@ @@ -1,101 +0,0 @@
1 -require 'spec_helper'  
2 -  
3 -describe "Project::Snippets" do  
4 - let(:project) { create(:project) }  
5 -  
6 - before do  
7 - login_as :user  
8 - project.team << [@user, :developer]  
9 - end  
10 -  
11 - describe "GET /:project/snippets" do  
12 - before do  
13 - @snippet = create(:snippet,  
14 - author: @user,  
15 - project: project)  
16 -  
17 - visit project_snippets_path(project)  
18 - p project_snippets_path(project)  
19 -  
20 - end  
21 -  
22 - subject { page }  
23 -  
24 - it { should have_content(@snippet.title[0..10]) }  
25 - it { should have_content(@snippet.project.name) }  
26 -  
27 - describe "Destroy" do  
28 - before do  
29 - # admin access to remove snippet  
30 - @user.users_projects.destroy_all  
31 - project.team << [@user, :master]  
32 - visit edit_project_snippet_path(project, @snippet)  
33 - end  
34 -  
35 - it "should remove entry" do  
36 - expect {  
37 - click_link "destroy_snippet_#{@snippet.id}"  
38 - }.to change { Snippet.count }.by(-1)  
39 - end  
40 - end  
41 - end  
42 -  
43 - describe "New project snippet" do  
44 - before do  
45 - visit project_snippets_path(project)  
46 - click_link "New Snippet"  
47 - end  
48 -  
49 - it "should open new snippet popup" do  
50 - page.current_path.should == new_project_snippet_path(project)  
51 - end  
52 -  
53 - describe "fill in", js: true do  
54 - before do  
55 - fill_in "snippet_title", with: "login function"  
56 - fill_in "snippet_file_name", with: "test.rb"  
57 - page.execute_script("editor.insert('def login; end');")  
58 - end  
59 -  
60 - it { expect { click_button "Save" }.to change {Snippet.count}.by(1) }  
61 -  
62 - it "should add new snippet to table" do  
63 - click_button "Save"  
64 - page.current_path.should == project_snippet_path(project, Snippet.last)  
65 - page.should have_content "login function"  
66 - page.should have_content "test.rb"  
67 - end  
68 - end  
69 - end  
70 -  
71 - describe "Edit project snippet" do  
72 - before do  
73 - @snippet = create(:snippet,  
74 - author: @user,  
75 - project: project)  
76 - visit project_snippet_path(project, @snippet)  
77 - click_link "Edit Snippet"  
78 - end  
79 -  
80 - it "should open edit page" do  
81 - page.current_path.should == edit_project_snippet_path(project, @snippet)  
82 - end  
83 -  
84 - describe "fill in" do  
85 - before do  
86 - fill_in "snippet_title", with: "login function"  
87 - fill_in "snippet_file_name", with: "test.rb"  
88 - end  
89 -  
90 - it { expect { click_button "Save" }.to_not change {Snippet.count} }  
91 -  
92 - it "should update snippet fields" do  
93 - click_button "Save"  
94 -  
95 - page.current_path.should == project_snippet_path(project, @snippet)  
96 - page.should have_content "login function"  
97 - page.should have_content "test.rb"  
98 - end  
99 - end  
100 - end  
101 -end  
spec/features/snippets_spec.rb
@@ -1,99 +0,0 @@ @@ -1,99 +0,0 @@
1 -require 'spec_helper'  
2 -  
3 -describe "Snippets" do  
4 - let(:project) { create(:project) }  
5 -  
6 - before do  
7 - login_as :user  
8 - project.team << [@user, :developer]  
9 - end  
10 -  
11 - describe "GET /snippets" do  
12 - before do  
13 - @snippet = create(:snippet,  
14 - author: @user,  
15 - project: project)  
16 -  
17 - visit project_snippets_path(project)  
18 - end  
19 -  
20 - subject { page }  
21 -  
22 - it { should have_content(@snippet.title[0..10]) }  
23 - it { should have_content(@snippet.project.name) }  
24 -  
25 - describe "Destroy" do  
26 - before do  
27 - # admin access to remove snippet  
28 - @user.users_projects.destroy_all  
29 - project.team << [@user, :master]  
30 - visit edit_project_snippet_path(project, @snippet)  
31 - end  
32 -  
33 - it "should remove entry" do  
34 - expect {  
35 - click_link "destroy_snippet_#{@snippet.id}"  
36 - }.to change { Snippet.count }.by(-1)  
37 - end  
38 - end  
39 - end  
40 -  
41 - describe "New snippet" do  
42 - before do  
43 - visit project_snippets_path(project)  
44 - click_link "New Snippet"  
45 - end  
46 -  
47 - it "should open new snippet popup" do  
48 - page.current_path.should == new_project_snippet_path(project)  
49 - end  
50 -  
51 - describe "fill in", js: true do  
52 - before do  
53 - fill_in "snippet_title", with: "login function"  
54 - fill_in "snippet_file_name", with: "test.rb"  
55 - page.execute_script("editor.insert('def login; end');")  
56 - end  
57 -  
58 - it { expect { click_button "Save" }.to change {Snippet.count}.by(1) }  
59 -  
60 - it "should add new snippet to table" do  
61 - click_button "Save"  
62 - page.current_path.should == project_snippet_path(project, Snippet.last)  
63 - page.should have_content "login function"  
64 - page.should have_content "test.rb"  
65 - end  
66 - end  
67 - end  
68 -  
69 - describe "Edit snippet" do  
70 - before do  
71 - @snippet = create(:snippet,  
72 - author: @user,  
73 - project: project)  
74 - visit project_snippet_path(project, @snippet)  
75 - click_link "Edit Snippet"  
76 - end  
77 -  
78 - it "should open edit page" do  
79 - page.current_path.should == edit_project_snippet_path(project, @snippet)  
80 - end  
81 -  
82 - describe "fill in" do  
83 - before do  
84 - fill_in "snippet_title", with: "login function"  
85 - fill_in "snippet_file_name", with: "test.rb"  
86 - end  
87 -  
88 - it { expect { click_button "Save" }.to_not change {Snippet.count} }  
89 -  
90 - it "should update snippet fields" do  
91 - click_button "Save"  
92 -  
93 - page.current_path.should == project_snippet_path(project, @snippet)  
94 - page.should have_content "login function"  
95 - page.should have_content "test.rb"  
96 - end  
97 - end  
98 - end  
99 -end