summaryrefslogtreecommitdiff
path: root/spec/features
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2013-02-21 10:41:37 +0200
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2013-02-21 10:41:37 +0200
commit03f6a28ec0dab308070e83ec422f12fa289aad9f (patch)
treea2b72dd5944863f38f7c7397590626223ab0fc5a /spec/features
parent9f722427e5835e4aeb5c1dd6a9cc8720b40d87c0 (diff)
downloadgitlab-ce-03f6a28ec0dab308070e83ec422f12fa289aad9f.tar.gz
move capybara scenarios to spec/features
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_hooks_spec.rb51
-rw-r--r--spec/features/admin/admin_projects_spec.rb76
-rw-r--r--spec/features/admin/admin_users_spec.rb135
-rw-r--r--spec/features/admin/security_spec.rb27
-rw-r--r--spec/features/atom/dashboard_issues_spec.rb24
-rw-r--r--spec/features/atom/dashboard_spec.rb14
-rw-r--r--spec/features/atom/issues_spec.rb34
-rw-r--r--spec/features/gitlab_flavored_markdown_spec.rb223
-rw-r--r--spec/features/issues_spec.rb132
-rw-r--r--spec/features/notes_on_merge_requests_spec.rb234
-rw-r--r--spec/features/notes_on_wall_spec.rb85
-rw-r--r--spec/features/profile_spec.rb48
-rw-r--r--spec/features/projects_deploy_keys_spec.rb67
-rw-r--r--spec/features/projects_spec.rb17
-rw-r--r--spec/features/search_spec.rb17
-rw-r--r--spec/features/security/profile_access_spec.rb49
-rw-r--r--spec/features/security/project_access_spec.rb243
-rw-r--r--spec/features/snippets_spec.rb99
18 files changed, 1575 insertions, 0 deletions
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
new file mode 100644
index 00000000000..bc0586b2712
--- /dev/null
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -0,0 +1,51 @@
+require 'spec_helper'
+
+describe "Admin::Hooks" do
+ before do
+ @project = create(:project)
+ login_as :admin
+
+ @system_hook = create(:system_hook)
+
+ end
+
+ describe "GET /admin/hooks" do
+ it "should be ok" do
+ visit admin_root_path
+ within ".main_menu" do
+ click_on "Hooks"
+ end
+ current_path.should == admin_hooks_path
+ end
+
+ it "should have hooks list" do
+ visit admin_hooks_path
+ page.should have_content(@system_hook.url)
+ end
+ end
+
+ describe "New Hook" do
+ before do
+ @url = Faker::Internet.uri("http")
+ visit admin_hooks_path
+ fill_in "hook_url", with: @url
+ expect { click_button "Add System Hook" }.to change(SystemHook, :count).by(1)
+ end
+
+ it "should open new hook popup" do
+ page.current_path.should == admin_hooks_path
+ page.should have_content(@url)
+ end
+ end
+
+ describe "Test" do
+ before do
+ WebMock.stub_request(:post, @system_hook.url)
+ visit admin_hooks_path
+ click_link "Test Hook"
+ end
+
+ it { page.current_path.should == admin_hooks_path }
+ end
+
+end
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
new file mode 100644
index 00000000000..c9ddf1f4534
--- /dev/null
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -0,0 +1,76 @@
+require 'spec_helper'
+
+describe "Admin::Projects" do
+ before do
+ @project = create(:project)
+ login_as :admin
+ end
+
+ describe "GET /admin/projects" do
+ before do
+ visit admin_projects_path
+ end
+
+ it "should be ok" do
+ current_path.should == admin_projects_path
+ end
+
+ it "should have projects list" do
+ page.should have_content(@project.name)
+ end
+ end
+
+ describe "GET /admin/projects/:id" do
+ before do
+ visit admin_projects_path
+ click_link "#{@project.name}"
+ end
+
+ it "should have project info" do
+ page.should have_content(@project.path)
+ page.should have_content(@project.name)
+ end
+ end
+
+ describe "GET /admin/projects/:id/edit" do
+ before do
+ visit admin_projects_path
+ click_link "edit_project_#{@project.id}"
+ end
+
+ it "should have project edit page" do
+ page.should have_content("Edit project")
+ page.should have_button("Save Project")
+ end
+
+ describe "Update project" do
+ before do
+ fill_in "project_name", with: "Big Bang"
+ click_button "Save Project"
+ @project.reload
+ end
+
+ it "should show page with new data" do
+ page.should have_content("Big Bang")
+ end
+
+ it "should change project entry" do
+ @project.name.should == "Big Bang"
+ end
+ end
+ end
+
+ describe "Add new team member" do
+ before do
+ @new_user = create(:user)
+ visit admin_project_path(@project)
+ end
+
+ it "should create new user" do
+ select @new_user.name, from: "user_ids"
+ expect { click_button "Add" }.to change { UsersProject.count }.by(1)
+ page.should have_content @new_user.name
+ current_path.should == admin_project_path(@project)
+ end
+ end
+end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
new file mode 100644
index 00000000000..455caf4a376
--- /dev/null
+++ b/spec/features/admin/admin_users_spec.rb
@@ -0,0 +1,135 @@
+require 'spec_helper'
+
+describe "Admin::Users" do
+ before { login_as :admin }
+
+ describe "GET /admin/users" do
+ before do
+ visit admin_users_path
+ end
+
+ it "should be ok" do
+ current_path.should == admin_users_path
+ end
+
+ it "should have users list" do
+ page.should have_content(@user.email)
+ page.should have_content(@user.name)
+ end
+ end
+
+ describe "GET /admin/users/new" do
+ before do
+ @password = "123ABC"
+ visit new_admin_user_path
+ fill_in "user_name", with: "Big Bang"
+ fill_in "user_username", with: "bang"
+ fill_in "user_email", with: "bigbang@mail.com"
+ fill_in "user_password", with: @password
+ fill_in "user_password_confirmation", with: @password
+ end
+
+ it "should create new user" do
+ expect { click_button "Save" }.to change {User.count}.by(1)
+ end
+
+ it "should create user with valid data" do
+ click_button "Save"
+ user = User.last
+ user.name.should == "Big Bang"
+ user.email.should == "bigbang@mail.com"
+ end
+
+ it "should call send mail" do
+ Notify.should_receive(:new_user_email)
+
+ User.observers.enable :user_observer do
+ click_button "Save"
+ end
+ end
+
+ it "should send valid email to user with email & password" do
+ Gitlab.config.gitlab.stub(:signup_enabled).and_return(false)
+ User.observers.enable :user_observer do
+ click_button "Save"
+ user = User.last
+ email = ActionMailer::Base.deliveries.last
+ email.subject.should have_content("Account was created")
+ email.body.should have_content(user.email)
+ email.body.should have_content(@password)
+ end
+ end
+
+ it "should send valid email to user with email without password when signup is enabled" do
+ Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
+ User.observers.enable :user_observer do
+ click_button "Save"
+ user = User.last
+ email = ActionMailer::Base.deliveries.last
+ email.subject.should have_content("Account was created")
+ email.body.should have_content(user.email)
+ email.body.should_not have_content(@password)
+ end
+ end
+ end
+
+ describe "GET /admin/users/:id" do
+ before do
+ visit admin_users_path
+ click_link "#{@user.name}"
+ end
+
+ it "should have user info" do
+ page.should have_content(@user.email)
+ page.should have_content(@user.name)
+ page.should have_content(@user.projects_limit)
+ end
+ end
+
+ describe "GET /admin/users/:id/edit" do
+ before do
+ @simple_user = create(:user)
+ visit admin_users_path
+ click_link "edit_user_#{@simple_user.id}"
+ end
+
+ it "should have user edit page" do
+ page.should have_content("Name")
+ page.should have_content("Password")
+ end
+
+ describe "Update user" do
+ before do
+ fill_in "user_name", with: "Big Bang"
+ fill_in "user_email", with: "bigbang@mail.com"
+ check "user_admin"
+ click_button "Save"
+ end
+
+ it "should show page with new data" do
+ page.should have_content("bigbang@mail.com")
+ page.should have_content("Big Bang")
+ end
+
+ it "should change user entry" do
+ @simple_user.reload
+ @simple_user.name.should == "Big Bang"
+ @simple_user.is_admin?.should be_true
+ end
+ end
+ end
+
+ describe "Add new project" do
+ before do
+ @new_project = create(:project)
+ visit admin_user_path(@user)
+ end
+
+ it "should create new user" do
+ select @new_project.name, from: "project_ids"
+ expect { click_button "Add" }.to change { UsersProject.count }.by(1)
+ page.should have_content @new_project.name
+ current_path.should == admin_user_path(@user)
+ end
+ end
+end
diff --git a/spec/features/admin/security_spec.rb b/spec/features/admin/security_spec.rb
new file mode 100644
index 00000000000..6306832628b
--- /dev/null
+++ b/spec/features/admin/security_spec.rb
@@ -0,0 +1,27 @@
+require 'spec_helper'
+
+describe "Admin::Projects" do
+ describe "GET /admin/projects" do
+ subject { admin_projects_path }
+
+ it { should be_allowed_for :admin }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /admin/users" do
+ subject { admin_users_path }
+
+ it { should be_allowed_for :admin }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /admin/hooks" do
+ subject { admin_hooks_path }
+
+ it { should be_allowed_for :admin }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+end
diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb
new file mode 100644
index 00000000000..6f5d51d16b6
--- /dev/null
+++ b/spec/features/atom/dashboard_issues_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe "Dashboard Issues Feed" do
+ describe "GET /issues" do
+ let!(:user) { create(:user) }
+ let!(:project1) { create(:project) }
+ let!(:project2) { create(:project) }
+ let!(:issue1) { create(:issue, author: user, assignee: user, project: project1) }
+ let!(:issue2) { create(:issue, author: user, assignee: user, project: project2) }
+
+ describe "atom feed" do
+ it "should render atom feed via private token" do
+ visit issues_dashboard_path(:atom, private_token: user.private_token)
+
+ page.response_headers['Content-Type'].should have_content("application/atom+xml")
+ page.body.should have_selector("title", text: "#{user.name} issues")
+ page.body.should have_selector("author email", text: issue1.author_email)
+ page.body.should have_selector("entry summary", text: issue1.title)
+ page.body.should have_selector("author email", text: issue2.author_email)
+ page.body.should have_selector("entry summary", text: issue2.title)
+ end
+ end
+ end
+end
diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb
new file mode 100644
index 00000000000..6257ad5c895
--- /dev/null
+++ b/spec/features/atom/dashboard_spec.rb
@@ -0,0 +1,14 @@
+require 'spec_helper'
+
+describe "Dashboard Feed" do
+ describe "GET /" do
+ let!(:user) { create(:user) }
+
+ context "projects atom feed via private token" do
+ it "should render projects atom feed" do
+ visit dashboard_path(:atom, private_token: user.private_token)
+ page.body.should have_selector("feed title")
+ end
+ end
+ end
+end
diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb
new file mode 100644
index 00000000000..0488c1f2266
--- /dev/null
+++ b/spec/features/atom/issues_spec.rb
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+describe "Issues Feed" do
+ describe "GET /issues" do
+ let!(:user) { create(:user) }
+ let!(:project) { create(:project, namespace: user.namespace) }
+ let!(:issue) { create(:issue, author: user, project: project) }
+
+ before { project.team << [user, :developer] }
+
+ context "when authenticated" do
+ it "should render atom feed" do
+ login_with user
+ visit project_issues_path(project, :atom)
+
+ page.response_headers['Content-Type'].should have_content("application/atom+xml")
+ page.body.should have_selector("title", text: "#{project.name} issues")
+ page.body.should have_selector("author email", text: issue.author_email)
+ page.body.should have_selector("entry summary", text: issue.title)
+ end
+ end
+
+ context "when authenticated via private token" do
+ it "should render atom feed" do
+ visit project_issues_path(project, :atom, private_token: user.private_token)
+
+ page.response_headers['Content-Type'].should have_content("application/atom+xml")
+ page.body.should have_selector("title", text: "#{project.name} issues")
+ page.body.should have_selector("author email", text: issue.author_email)
+ page.body.should have_selector("entry summary", text: issue.title)
+ end
+ end
+ end
+end
diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb
new file mode 100644
index 00000000000..9a568511fa0
--- /dev/null
+++ b/spec/features/gitlab_flavored_markdown_spec.rb
@@ -0,0 +1,223 @@
+require 'spec_helper'
+
+describe "Gitlab Flavored Markdown" do
+ let(:project) { create(:project) }
+ let(:issue) { create(:issue, project: project) }
+ let(:merge_request) { create(:merge_request, project: project) }
+ let(:fred) do
+ u = create(:user, name: "fred")
+ project.team << [u, :master]
+ u
+ end
+
+ before do
+ # add test branch
+ @branch_name = "gfm-test"
+ r = project.repo
+ i = r.index
+ # add test file
+ @test_file = "gfm_test_file"
+ i.add(@test_file, "foo\nbar\n")
+ # add commit with gfm
+ i.commit("fix ##{issue.id}\n\nask @#{fred.username} for details", head: @branch_name)
+
+ # add test tag
+ @tag_name = "gfm-test-tag"
+ r.git.native(:tag, {}, @tag_name, commit.id)
+ end
+
+ after do
+ # delete test branch and tag
+ project.repo.git.native(:branch, {D: true}, @branch_name)
+ project.repo.git.native(:tag, {d: true}, @tag_name)
+ project.repo.gc_auto
+ end
+
+ let(:commit) { project.repository.commits(@branch_name).first }
+
+ before do
+ login_as :user
+ project.team << [@user, :developer]
+ end
+
+ describe "for commits" do
+ it "should render title in commits#index" do
+ visit project_commits_path(project, @branch_name, limit: 1)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render title in commits#show" do
+ visit project_commit_path(project, commit)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render description in commits#show" do
+ visit project_commit_path(project, commit)
+
+ page.should have_link("@#{fred.username}")
+ end
+
+ it "should render title in refs#tree", js: true do
+ visit project_tree_path(project, @branch_name)
+
+ within(".tree_commit") do
+ page.should have_link("##{issue.id}")
+ end
+ end
+
+ # @wip
+ #it "should render title in refs#blame" do
+ #visit project_blame_path(project, File.join(@branch_name, @test_file))
+
+ #within(".blame_commit") do
+ #page.should have_link("##{issue.id}")
+ #end
+ #end
+
+ it "should render title in repositories#branches" do
+ visit branches_project_repository_path(project)
+
+ page.should have_link("##{issue.id}")
+ end
+ end
+
+ describe "for issues" do
+ before do
+ @other_issue = create(:issue,
+ author: @user,
+ assignee: @user,
+ project: project)
+ @issue = create(:issue,
+ author: @user,
+ assignee: @user,
+ project: project,
+ title: "fix ##{@other_issue.id}",
+ description: "ask @#{fred.username} for details")
+ end
+
+ it "should render subject in issues#index" do
+ visit project_issues_path(project)
+
+ page.should have_link("##{@other_issue.id}")
+ end
+
+ it "should render subject in issues#show" do
+ visit project_issue_path(project, @issue)
+
+ page.should have_link("##{@other_issue.id}")
+ end
+
+ it "should render details in issues#show" do
+ visit project_issue_path(project, @issue)
+
+ page.should have_link("@#{fred.username}")
+ end
+ end
+
+
+ describe "for merge requests" do
+ before do
+ @merge_request = create(:merge_request,
+ project: project,
+ title: "fix ##{issue.id}")
+ end
+
+ it "should render title in merge_requests#index" do
+ visit project_merge_requests_path(project)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render title in merge_requests#show" do
+ visit project_merge_request_path(project, @merge_request)
+
+ page.should have_link("##{issue.id}")
+ end
+ end
+
+
+ describe "for milestones" do
+ before do
+ @milestone = create(:milestone,
+ project: project,
+ title: "fix ##{issue.id}",
+ description: "ask @#{fred.username} for details")
+ end
+
+ it "should render title in milestones#index" do
+ visit project_milestones_path(project)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render title in milestones#show" do
+ visit project_milestone_path(project, @milestone)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render description in milestones#show" do
+ visit project_milestone_path(project, @milestone)
+
+ page.should have_link("@#{fred.username}")
+ end
+ end
+
+
+ describe "for notes" do
+ it "should render in commits#show", js: true do
+ visit project_commit_path(project, commit)
+ fill_in "note_note", with: "see ##{issue.id}"
+ click_button "Add Comment"
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render in issue#show", js: true do
+ visit project_issue_path(project, issue)
+ fill_in "note_note", with: "see ##{issue.id}"
+ click_button "Add Comment"
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render in merge_request#show", js: true do
+ visit project_merge_request_path(project, merge_request)
+ fill_in "note_note", with: "see ##{issue.id}"
+ click_button "Add Comment"
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render in projects#wall", js: true do
+ visit wall_project_path(project)
+ fill_in "note_note", with: "see ##{issue.id}"
+ click_button "Add Comment"
+
+ page.should have_link("##{issue.id}")
+ end
+ end
+
+
+ describe "for wikis" do
+ before do
+ visit project_wiki_path(project, :index)
+ fill_in "Title", with: "Circumvent ##{issue.id}"
+ fill_in "Content", with: "# Other pages\n\n* [Foo](foo)\n* [Bar](bar)\n\nAlso look at ##{issue.id} :-)"
+ click_on "Save"
+ end
+
+ it "should NOT render title in wikis#show" do
+ within(".content h3") do # page title
+ page.should have_content("Circumvent ##{issue.id}")
+ page.should_not have_link("##{issue.id}")
+ end
+ end
+
+ it "should render content in wikis#show" do
+ page.should have_link("##{issue.id}")
+ end
+ end
+end
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
new file mode 100644
index 00000000000..6fff59f036f
--- /dev/null
+++ b/spec/features/issues_spec.rb
@@ -0,0 +1,132 @@
+require 'spec_helper'
+
+describe "Issues" do
+ let(:project) { create(:project) }
+
+ before do
+ login_as :user
+ user2 = create(:user)
+
+ project.team << [[@user, user2], :developer]
+ end
+
+ describe "Edit issue" do
+ let!(:issue) do
+ create(:issue,
+ author: @user,
+ assignee: @user,
+ project: project)
+ end
+
+ before do
+ visit project_issues_path(project)
+ click_link "Edit"
+ end
+
+ it "should open new issue popup" do
+ page.should have_content("Issue ##{issue.id}")
+ end
+
+ describe "fill in" do
+ before do
+ fill_in "issue_title", with: "bug 345"
+ fill_in "issue_description", with: "bug description"
+ end
+
+ it { expect { click_button "Save changes" }.to_not change {Issue.count} }
+
+ it "should update issue fields" do
+ click_button "Save changes"
+
+ page.should have_content @user.name
+ page.should have_content "bug 345"
+ page.should have_content project.name
+ end
+ end
+ end
+
+ describe "Search issue", js: true do
+ before do
+ ['foobar', 'foobar2', 'gitlab'].each do |title|
+ create(:issue,
+ author: @user,
+ assignee: @user,
+ project: project,
+ title: title)
+ end
+ end
+
+ it "should be able to search on different statuses" do
+ issue = Issue.first # with title 'foobar'
+ issue.close
+
+ visit project_issues_path(project)
+ click_link 'Closed'
+ fill_in 'issue_search', with: 'foobar'
+
+ page.should have_content 'foobar'
+ page.should_not have_content 'foobar2'
+ page.should_not have_content 'gitlab'
+ end
+
+ it "should search for term and return the correct results" do
+ visit project_issues_path(project)
+ fill_in 'issue_search', with: 'foobar'
+
+ page.should have_content 'foobar'
+ page.should have_content 'foobar2'
+ page.should_not have_content 'gitlab'
+ end
+ end
+
+ describe "Filter issue" do
+ before do
+ ['foobar', 'barbaz', 'gitlab'].each do |title|
+ create(:issue,
+ author: @user,
+ assignee: @user,
+ project: project,
+ title: title)
+ end
+
+ @issue = Issue.first # with title 'foobar'
+ @issue.milestone = create(:milestone, project: project)
+ @issue.assignee = nil
+ @issue.save
+ end
+
+ let(:issue) { @issue }
+
+ it "should allow filtering by issues with no specified milestone" do
+ visit project_issues_path(project, milestone_id: '0')
+
+ page.should_not have_content 'foobar'
+ page.should have_content 'barbaz'
+ page.should have_content 'gitlab'
+ end
+
+ it "should allow filtering by a specified milestone" do
+ visit project_issues_path(project, milestone_id: issue.milestone.id)
+
+ page.should have_content 'foobar'
+ page.should_not have_content 'barbaz'
+ page.should_not have_content 'gitlab'
+ end
+
+ it "should allow filtering by issues with no specified assignee" do
+ visit project_issues_path(project, assignee_id: '0')
+
+ page.should have_content 'foobar'
+ page.should_not have_content 'barbaz'
+ page.should_not have_content 'gitlab'
+ end
+
+ it "should allow filtering by a specified assignee" do
+ visit project_issues_path(project, assignee_id: @user.id)
+
+ page.should_not have_content 'foobar'
+ page.should have_content 'barbaz'
+ page.should have_content 'gitlab'
+ end
+ end
+end
diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb
new file mode 100644
index 00000000000..37fc85c87f8
--- /dev/null
+++ b/spec/features/notes_on_merge_requests_spec.rb
@@ -0,0 +1,234 @@
+require 'spec_helper'
+
+describe "On a merge request", js: true do
+ let!(:project) { create(:project) }
+ let!(:merge_request) { create(:merge_request, project: project) }
+
+ before do
+ login_as :user
+ project.team << [@user, :master]
+
+ visit project_merge_request_path(project, merge_request)
+ end
+
+ subject { page }
+
+ describe "the note form" do
+ # main target form creation
+ it { should have_css(".js-main-target-form", visible: true, count: 1) }
+
+ # button initalization
+ it { within(".js-main-target-form") { should have_button("Add Comment") } }
+ it { within(".js-main-target-form") { should_not have_link("Cancel") } }
+
+ # notifiactions
+ it { within(".js-main-target-form") { should have_checked_field("Notify team via email") } }
+ it { within(".js-main-target-form") { should_not have_checked_field("Notify commit author") } }
+ it { within(".js-main-target-form") { should_not have_unchecked_field("Notify commit author") } }
+
+ describe "without text" do
+ it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) } }
+ end
+
+ describe "with text" do
+ before do
+ within(".js-main-target-form") do
+ fill_in "note[note]", with: "This is awesome"
+ end
+ end
+
+ it { within(".js-main-target-form") { should_not have_css(".js-comment-button[disabled]") } }
+
+ it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: true) } }
+ end
+
+ describe "with preview" do
+ before do
+ within(".js-main-target-form") do
+ fill_in "note[note]", with: "This is awesome"
+ find(".js-note-preview-button").trigger("click")
+ end
+ end
+
+ it { within(".js-main-target-form") { should have_css(".js-note-preview", text: "This is awesome", visible: true) } }
+
+ it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) } }
+ it { within(".js-main-target-form") { should have_css(".js-note-edit-button", visible: true) } }
+ end
+ end
+
+ describe "when posting a note" do
+ before do
+ within(".js-main-target-form") do
+ fill_in "note[note]", with: "This is awsome!"
+ find(".js-note-preview-button").trigger("click")
+ click_button "Add Comment"
+ end
+ end
+
+ # note added
+ it { within(".js-main-target-form") { should have_content("This is awsome!") } }
+
+ # reset form
+ it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } }
+
+ # return from preview
+ it { within(".js-main-target-form") { should have_css(".js-note-preview", visible: false) } }
+ it { within(".js-main-target-form") { should have_css(".js-note-text", visible: true) } }
+
+
+ it "should be removable" do
+ find(".js-note-delete").trigger("click")
+
+ should_not have_css(".note")
+ end
+ end
+end
+
+
+
+describe "On a merge request diff", js: true, focus: true do
+ let!(:project) { create(:project) }
+ let!(:merge_request) { create(:merge_request_with_diffs, project: project) }
+
+ before do
+ login_as :user
+ project.team << [@user, :master]
+
+ visit diffs_project_merge_request_path(project, merge_request)
+
+ within '.diffs-tab' do
+ click_link("Diff")
+ end
+ end
+
+ subject { page }
+
+ describe "when adding a note" do
+ before do
+ find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder .js-add-diff-note-button").trigger("click")
+ end
+
+ describe "the notes holder" do
+ it { should have_css("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder + .js-temp-notes-holder") }
+
+ it { within(".js-temp-notes-holder") { should have_css(".new_note") } }
+ end
+
+ describe "the note form" do
+ # set up hidden fields correctly
+ it { within(".js-temp-notes-holder") { find("#note_noteable_type").value.should == "MergeRequest" } }
+ it { within(".js-temp-notes-holder") { find("#note_noteable_id").value.should == merge_request.id.to_s } }
+ it { within(".js-temp-notes-holder") { find("#note_commit_id").value.should == "" } }
+ it { within(".js-temp-notes-holder") { find("#note_line_code").value.should == "4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185" } }
+
+ # buttons
+ it { should have_button("Add Comment") }
+ it { should have_css(".js-close-discussion-note-form", text: "Cancel") }
+
+ # notification options
+ it { should have_checked_field("Notify team via email") }
+
+ it "shouldn't add a second form for same row" do
+ find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder .js-add-diff-note-button").trigger("click")
+
+ should have_css("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder + .js-temp-notes-holder form", count: 1)
+ end
+
+ it "should be removed when canceled" do
+ find(".js-close-discussion-note-form").trigger("click")
+
+ should have_no_css(".js-temp-notes-holder")
+ end
+ end
+ end
+
+ describe "with muliple note forms" do
+ before do
+ find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder .js-add-diff-note-button").trigger("click")
+ find("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder .js-add-diff-note-button").trigger("click")
+ end
+
+ # has two line forms
+ it { should have_css(".js-temp-notes-holder", count: 2) }
+
+ describe "previewing them separately" do
+ before do
+ # add two separate texts and trigger previews on both
+ within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "One comment on line 185"
+ find(".js-note-preview-button").trigger("click")
+ end
+ within("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "Another comment on line 17"
+ find(".js-note-preview-button").trigger("click")
+ end
+ end
+
+ # check if previews were rendered separately
+ it { within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185.line_holder + .js-temp-notes-holder") { should have_css(".js-note-preview", text: "One comment on line 185") } }
+ it { within("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .js-temp-notes-holder") { should have_css(".js-note-preview", text: "Another comment on line 17") } }
+ end
+
+ describe "posting a note" do
+ before do
+ within("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "Another comment on line 17"
+ click_button("Add Comment")
+ end
+ end
+
+ # removed form after submit
+ it { should have_no_css("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .js-temp-notes-holder") }
+
+ # added discussion
+ it { should have_content("Another comment on line 17") }
+ it { should have_css("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .notes_holder") }
+ it { should have_css("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .notes_holder .note", count: 1) }
+ it { should have_link("Reply") }
+
+ it "should remove last note of a discussion" do
+ within("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + .notes_holder") do
+ find(".js-note-delete").trigger("click")
+ end
+
+ # removed whole discussion
+ should_not have_css(".note_holder")
+ should have_css("#342e16cbbd482ac2047dc679b2749d248cc1428f_18_17.line_holder + #342e16cbbd482ac2047dc679b2749d248cc1428f_18_18.line_holder")
+ end
+ end
+ end
+
+ describe "when replying to a note" do
+ before do
+ # create first note
+ find("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder .js-add-diff-note-button").trigger("click")
+ within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "One comment on line 184"
+ click_button("Add Comment")
+ end
+ # create second note
+ within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .notes_holder") do
+ find(".js-discussion-reply-button").trigger("click")
+ fill_in "note[note]", with: "An additional comment in reply"
+ click_button("Add Comment")
+ end
+ end
+
+ # inserted note
+ it { should have_content("An additional comment in reply") }
+ it { within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .notes_holder") { should have_css(".note", count: 2) } }
+
+ # removed form after reply
+ it { within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .notes_holder") { should have_no_css("form") } }
+ it { within("#4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184.line_holder + .notes_holder") { should have_link("Reply") } }
+ end
+end
+
+
+
+describe "On merge request discussion", js: true do
+ describe "with merge request diff note"
+ describe "with commit note"
+ describe "with commit diff note"
+end
diff --git a/spec/features/notes_on_wall_spec.rb b/spec/features/notes_on_wall_spec.rb
new file mode 100644
index 00000000000..4adcf74e0b6
--- /dev/null
+++ b/spec/features/notes_on_wall_spec.rb
@@ -0,0 +1,85 @@
+require 'spec_helper'
+
+describe "On the project wall", js: true do
+ let!(:project) { create(:project) }
+ let!(:commit) { project.repository.commit("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
+
+ before do
+ login_as :user
+ project.team << [@user, :master]
+ visit wall_project_path(project)
+ end
+
+ subject { page }
+
+ describe "the note form" do
+ # main target form creation
+ it { should have_css(".js-main-target-form", visible: true, count: 1) }
+
+ # button initalization
+ it { within(".js-main-target-form") { should have_button("Add Comment") } }
+ it { within(".js-main-target-form") { should_not have_link("Cancel") } }
+
+ # notifiactions
+ it { within(".js-main-target-form") { should have_checked_field("Notify team via email") } }
+ it { within(".js-main-target-form") { should_not have_checked_field("Notify commit author") } }
+ it { within(".js-main-target-form") { should_not have_unchecked_field("Notify commit author") } }
+
+ describe "without text" do
+ it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) } }
+ end
+
+ describe "with text" do
+ before do
+ within(".js-main-target-form") do
+ fill_in "note[note]", with: "This is awesome"
+ end
+ end
+
+ it { within(".js-main-target-form") { should_not have_css(".js-comment-button[disabled]") } }
+
+ it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: true) } }
+ end
+
+ describe "with preview" do
+ before do
+ within(".js-main-target-form") do
+ fill_in "note[note]", with: "This is awesome"
+ find(".js-note-preview-button").trigger("click")
+ end
+ end
+
+ it { within(".js-main-target-form") { should have_css(".js-note-preview", text: "This is awesome", visible: true) } }
+
+ it { within(".js-main-target-form") { should have_css(".js-note-preview-button", visible: false) } }
+ it { within(".js-main-target-form") { should have_css(".js-note-edit-button", visible: true) } }
+ end
+ end
+
+ describe "when posting a note" do
+ before do
+ within(".js-main-target-form") do
+ fill_in "note[note]", with: "This is awsome!"
+ find(".js-note-preview-button").trigger("click")
+ click_button "Add Comment"
+ end
+ end
+
+ # note added
+ it { within(".js-main-target-form") { should have_content("This is awsome!") } }
+
+ # reset form
+ it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } }
+
+ # return from preview
+ it { within(".js-main-target-form") { should have_css(".js-note-preview", visible: false) } }
+ it { within(".js-main-target-form") { should have_css(".js-note-text", visible: true) } }
+
+
+ it "should be removable" do
+ find(".js-note-delete").trigger("click")
+
+ should_not have_css(".note")
+ end
+ end
+end
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
new file mode 100644
index 00000000000..c18d8f921a3
--- /dev/null
+++ b/spec/features/profile_spec.rb
@@ -0,0 +1,48 @@
+require 'spec_helper'
+
+describe "Profile account page" do
+ let(:user) { create(:user) }
+
+ before do
+ login_as :user
+ end
+
+ describe "when signup is enabled" do
+ before do
+ Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
+ visit account_profile_path
+ end
+ it { page.should have_content("Remove account") }
+
+ it "should delete the account", js: true do
+ expect { click_link "Delete account" }.to change {User.count}.by(-1)
+ current_path.should == new_user_session_path
+ end
+ end
+
+ describe "when signup is enabled and user has a project" do
+ before do
+ Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
+ @project = create(:project, namespace: @user.namespace)
+ @project.team << [@user, :master]
+ visit account_profile_path
+ end
+ it { page.should have_content("Remove account") }
+
+ it "should not allow user to delete the account" do
+ expect { click_link "Delete account" }.not_to change {User.count}.by(-1)
+ end
+ end
+
+ describe "when signup is disabled" do
+ before do
+ Gitlab.config.gitlab.stub(:signup_enabled).and_return(false)
+ visit account_profile_path
+ end
+
+ it "should not have option to remove account" do
+ page.should_not have_content("Remove account")
+ current_path.should == account_profile_path
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/features/projects_deploy_keys_spec.rb b/spec/features/projects_deploy_keys_spec.rb
new file mode 100644
index 00000000000..25b1da9ebd8
--- /dev/null
+++ b/spec/features/projects_deploy_keys_spec.rb
@@ -0,0 +1,67 @@
+require 'spec_helper'
+
+describe "Projects", "DeployKeys" do
+ let(:project) { create(:project) }
+
+ before do
+ login_as :user
+ project.team << [@user, :master]
+ end
+
+ describe "GET /keys" do
+ before do
+ @key = create(:key, project: project)
+ visit project_deploy_keys_path(project)
+ end
+
+ subject { page }
+
+ it { should have_content(@key.title) }
+
+ describe "Destroy" do
+ before { visit project_deploy_key_path(project, @key) }
+
+ it "should remove entry" do
+ expect {
+ click_link "Remove"
+ }.to change { project.deploy_keys.count }.by(-1)
+ end
+ end
+ end
+
+ describe "New key" do
+ before do
+ visit project_deploy_keys_path(project)
+ click_link "New Deploy Key"
+ end
+
+ it "should open new key popup" do
+ page.should have_content("New Deploy key")
+ end
+
+ describe "fill in" do
+ before do
+ fill_in "key_title", with: "laptop"
+ fill_in "key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop"
+ end
+
+ it { expect { click_button "Save" }.to change {Key.count}.by(1) }
+
+ it "should add new key to table" do
+ click_button "Save"
+
+ page.should have_content "laptop"
+ end
+ end
+ end
+
+ describe "Show page" do
+ before do
+ @key = create(:key, project: project)
+ visit project_deploy_key_path(project, @key)
+ end
+
+ it { page.should have_content @key.title }
+ it { page.should have_content @key.key[0..10] }
+ end
+end
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
new file mode 100644
index 00000000000..7bc48260935
--- /dev/null
+++ b/spec/features/projects_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe "Projects" do
+ before { login_as :user }
+
+ describe "DELETE /projects/:id" do
+ before do
+ @project = create(:project, namespace: @user.namespace)
+ @project.team << [@user, :master]
+ visit edit_project_path(@project)
+ end
+
+ it "should be correct path" do
+ expect { click_link "Remove" }.to change {Project.count}.by(-1)
+ end
+ end
+end
diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb
new file mode 100644
index 00000000000..e338f359f88
--- /dev/null
+++ b/spec/features/search_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe "Search" do
+ before do
+ login_as :user
+ @project = create(:project)
+ @project.team << [@user, :reporter]
+ visit search_path
+ fill_in "search", with: @project.name[0..3]
+ click_button "Search"
+ end
+
+ it "should show project in search results" do
+ page.should have_content @project.name
+ end
+end
+
diff --git a/spec/features/security/profile_access_spec.rb b/spec/features/security/profile_access_spec.rb
new file mode 100644
index 00000000000..f854f3fb066
--- /dev/null
+++ b/spec/features/security/profile_access_spec.rb
@@ -0,0 +1,49 @@
+require 'spec_helper'
+
+describe "Users Security" do
+ describe "Project" do
+ before do
+ @u1 = create(:user)
+ end
+
+ describe "GET /login" do
+ it { new_user_session_path.should_not be_404_for :visitor }
+ end
+
+ describe "GET /keys" do
+ subject { keys_path }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /profile" do
+ subject { profile_path }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /profile/account" do
+ subject { account_profile_path }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /profile/design" do
+ subject { design_profile_path }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+ end
+end
diff --git a/spec/features/security/project_access_spec.rb b/spec/features/security/project_access_spec.rb
new file mode 100644
index 00000000000..a35175102ec
--- /dev/null
+++ b/spec/features/security/project_access_spec.rb
@@ -0,0 +1,243 @@
+require 'spec_helper'
+
+describe "Application access" do
+ describe "GET /" do
+ it { root_path.should be_allowed_for :admin }
+ it { root_path.should be_allowed_for :user }
+ it { root_path.should be_denied_for :visitor }
+ end
+
+ describe "GET /projects/new" do
+ it { new_project_path.should be_allowed_for :admin }
+ it { new_project_path.should be_allowed_for :user }
+ it { new_project_path.should be_denied_for :visitor }
+ end
+
+ describe "Project" do
+ let(:project) { create(:project) }
+
+ let(:master) { create(:user) }
+ let(:guest) { create(:user) }
+ let(:reporter) { create(:user) }
+
+ before do
+ # full access
+ project.team << [master, :master]
+
+ # readonly
+ project.team << [reporter, :reporter]
+ end
+
+ describe "GET /project_code" do
+ subject { project_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/tree/master" do
+ subject { project_tree_path(project, project.repository.root_ref) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/commits/master" do
+ subject { project_commits_path(project, project.repository.root_ref, limit: 1) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/commit/:sha" do
+ subject { project_commit_path(project, project.repository.commit) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/compare" do
+ subject { project_compare_index_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/team" do
+ subject { project_team_index_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/wall" do
+ subject { wall_project_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/blob" do
+ before do
+ commit = project.repository.commit
+ path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name
+ @blob_path = project_blob_path(project, File.join(commit.id, path))
+ end
+
+ it { @blob_path.should be_allowed_for master }
+ it { @blob_path.should be_allowed_for reporter }
+ it { @blob_path.should be_denied_for :admin }
+ it { @blob_path.should be_denied_for guest }
+ it { @blob_path.should be_denied_for :user }
+ it { @blob_path.should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/edit" do
+ subject { edit_project_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_denied_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/deploy_keys" do
+ subject { project_deploy_keys_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_denied_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/issues" do
+ subject { project_issues_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/snippets" do
+ subject { project_snippets_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/merge_requests" do
+ subject { project_merge_requests_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/repository" do
+ subject { project_repository_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/repository/branches" do
+ subject { branches_project_repository_path(project) }
+
+ before do
+ # Speed increase
+ Project.any_instance.stub(:branches).and_return([])
+ end
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/repository/tags" do
+ subject { tags_project_repository_path(project) }
+
+ before do
+ # Speed increase
+ Project.any_instance.stub(:tags).and_return([])
+ end
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/hooks" do
+ subject { project_hooks_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/files" do
+ subject { files_project_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+ end
+end
diff --git a/spec/features/snippets_spec.rb b/spec/features/snippets_spec.rb
new file mode 100644
index 00000000000..770e34dc07c
--- /dev/null
+++ b/spec/features/snippets_spec.rb
@@ -0,0 +1,99 @@
+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"
+ 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