diff --git a/CHANGELOG b/CHANGELOG index 2675db90543416573d54127c6e61d4b67d77b4b9..4ca3f997f8438e2f1789dae9060f066c99210eab 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +v 7.2.0 + - Add project stars (Ciro Santilli) + v 7.1.0 - Remove observers - Improve MR discussions diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee index 4262418fd5ec8b65f3b191ae13e6ecc5c8a95d46..d81cc087df9b7b91c3f138ddf02bc1fcabb63b7b 100644 --- a/app/assets/javascripts/project.js.coffee +++ b/app/assets/javascripts/project.js.coffee @@ -46,3 +46,8 @@ $ -> $.cookie('hide_no_ssh_message', 'false', { path: path }) $(@).parents('.no-ssh-key-message').hide() e.preventDefault() + + $('.project-home-panel .star').on 'ajax:success', (e, data, status, xhr) -> + $(@).toggleClass('on').find('.count').html(data.star_count) + .on 'ajax:error', (e, xhr, status, error) -> + new Flash('Star toggle failed. Try again later.', 'alert') diff --git a/app/assets/stylesheets/behaviors.scss b/app/assets/stylesheets/behaviors.scss index 23f206ce3dc6c1ed7f8303f2a314a7977f2b8c44..034692a67e1b7cb0977560d8d44d251b425d485d 100644 --- a/app/assets/stylesheets/behaviors.scss +++ b/app/assets/stylesheets/behaviors.scss @@ -4,3 +4,9 @@ .js-details-container .content.hide { display: block; } .js-details-container.open .content { display: block; } .js-details-container.open .content.hide { display: none; } + +// Toggle between two states. +.js-toggler-container .turn-on { display: inline-block; } +.js-toggler-container .turn-off { display: none; } +.js-toggler-container.on .turn-on { display: none; } +.js-toggler-container.on .turn-off { display: inline-block; } diff --git a/app/assets/stylesheets/generic/buttons.scss b/app/assets/stylesheets/generic/buttons.scss index 046e5040fb2e77463dee1f04684eaa568e9b5afd..d098f1ecaa2193f61ffc69527b915a421b4491e3 100644 --- a/app/assets/stylesheets/generic/buttons.scss +++ b/app/assets/stylesheets/generic/buttons.scss @@ -6,7 +6,7 @@ vertical-align: middle; cursor: pointer; background-image: none; - border: 1px solid transparent; + border: $btn-border; white-space: nowrap; padding: 6px 12px; font-size: 13px; @@ -19,7 +19,6 @@ user-select: none; color: #444444; background-color: #fff; - border-color: #ccc; text-shadow: none; &.hover, diff --git a/app/assets/stylesheets/main/variables.scss b/app/assets/stylesheets/main/variables.scss index c49f7db788e724beacbdd24267dbc9abe74c1b07..02ce2c8338ff848d1b6b61b8c9cdc6ef47e09187 100644 --- a/app/assets/stylesheets/main/variables.scss +++ b/app/assets/stylesheets/main/variables.scss @@ -10,6 +10,8 @@ $hover: #D9EDF7; $link_color: #446e9b; $link_hover_color: #2FA0BB; +$btn-border: 1px solid #ccc; + /* * Success colors (green) */ diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss index c9188fb751c68f3656cf1d848dfcd3193908aeb1..eecc49620fdd152e6b6f47874d1d4f5a683c6087 100644 --- a/app/assets/stylesheets/sections/projects.scss +++ b/app/assets/stylesheets/sections/projects.scss @@ -50,6 +50,22 @@ margin-left: 10px; font-weight: 500; } + + .star .btn { + font-weight: bold; + line-height: 22px; + padding: 0px; + $margin-x: 6px; + .toggle { + display: inline-block; + padding: 0px $margin-x; + } + .count { + border-left: $btn-border; + display: inline-block; + padding: 0px $margin-x; + } + } } } diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 3d012b7e16463ec943d0bc40303b8423cdf6dff9..1b1b0eb7ad1d0254e9e855fc67580bb1fb095a6d 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -60,6 +60,8 @@ class ProjectsController < ApplicationController @events = event_filter.apply_filter(@events) @events = @events.limit(limit).offset(params[:offset] || 0) + @show_star = !(current_user && current_user.starred?(@project)) + respond_to do |format| format.html do if @project.empty_repo? @@ -167,6 +169,12 @@ class ProjectsController < ApplicationController end end + def toggle_star + current_user.toggle_star(@project) + @project.reload + render json: { star_count: @project.star_count } + end + private def upload_path diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index bc2ec84302d817db1e1aaf6c06e4a45a801ef424..1304e2dea23677992a55c223dc627f6ff792a5cc 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -122,6 +122,28 @@ module ProjectsHelper options_for_select(values, current_tracker) end + def link_to_toggle_star(title, starred, signed_in) + cls = 'btn' + cls += ' disabled' unless signed_in + content_tag 'span', class: starred ? 'turn-on' : 'turn-off' do + link_to toggle_star_project_path(@project), + title: title, class: cls, method: :post, remote: true, + data: {type: 'json'} do + content_tag('span', class: 'toggle') do + content_tag('i', ' ', class: 'icon-star') << + if starred + 'Unstar' + else + 'Star' + end + end << + content_tag('span', class: 'count') do + @project.star_count.to_s + end + end + end + end + private def get_project_nav_tabs(project, current_user) diff --git a/app/models/project.rb b/app/models/project.rb index 339143196a731756f731078066de3424572de814..10882ea97cc9769d1064605a481faa2e5d60f14e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -22,6 +22,7 @@ # visibility_level :integer default(0), not null # archived :boolean default(FALSE), not null # import_status :string(255) +# star_count :integer # class Project < ActiveRecord::Base @@ -81,6 +82,8 @@ class Project < ActiveRecord::Base has_many :users, through: :users_projects has_many :deploy_keys_projects, dependent: :destroy has_many :deploy_keys, through: :deploy_keys_projects + has_many :users_star_projects, dependent: :destroy + has_many :starrers, through: :users_star_projects, source: :user delegate :name, to: :owner, allow_nil: true, prefix: true delegate :members, to: :team, prefix: true @@ -107,6 +110,7 @@ class Project < ActiveRecord::Base validates :import_url, format: { with: URI::regexp(%w(git http https)), message: "should be a valid url" }, if: :import? + validates :star_count, numericality: { greater_than_or_equal_to: 0 } validate :check_limit, on: :create # Scopes diff --git a/app/models/user.rb b/app/models/user.rb index 350e30f16186ee2d1c7b59b364956cb0ecf9f8f8..9ab3ea025c36248a7cc08b7e7355f5a33b1006a7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -91,6 +91,8 @@ class User < ActiveRecord::Base has_many :personal_projects, through: :namespace, source: :projects has_many :projects, through: :users_projects has_many :created_projects, foreign_key: :creator_id, class_name: 'Project' + has_many :users_star_projects, dependent: :destroy + has_many :starred_projects, through: :users_star_projects, source: :project has_many :snippets, dependent: :destroy, foreign_key: :author_id, class_name: "Snippet" has_many :users_projects, dependent: :destroy @@ -517,4 +519,18 @@ class User < ActiveRecord::Base def system_hook_service SystemHooksService.new end + + def starred?(project) + starred_projects.exists?(project) + end + + def toggle_star(project) + user_star_project = users_star_projects. + where(project: project, user: self).take + if user_star_project + user_star_project.destroy + else + UsersStarProject.create!(project: project, user: self) + end + end end diff --git a/app/models/users_star_project.rb b/app/models/users_star_project.rb new file mode 100644 index 0000000000000000000000000000000000000000..80e756bd00c167157b7cdc8a48017bc7c18b9c66 --- /dev/null +++ b/app/models/users_star_project.rb @@ -0,0 +1,19 @@ +# == Schema Information +# +# Table name: users_star_projects +# +# id :integer not null, primary key +# starrer_id :integer not null +# project_id :integer not null +# created_at :datetime +# updated_at :datetime +# + +class UsersStarProject < ActiveRecord::Base + belongs_to :project, counter_cache: :star_count + belongs_to :user + + validates :user, presence: true + validates :user_id, uniqueness: { scope: [:project_id] } + validates :project, presence: true +end diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index ddf815ebd996a68baaf3bfc302b4ce222dd2f146..bf9301d70c44ecb8a0b78107ca9b54280dc16520 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -27,10 +27,16 @@ = link_to project_blob_path(@project, tree_join(@repository.root_ref, readme.name)) do = readme.name - - unless empty_repo - .col-md-5 - .project-home-links + .col-md-5 + .project-home-links + - unless empty_repo = link_to pluralize(number_with_delimiter(@repository.commit_count), 'commit'), project_commits_path(@project, @ref || @repository.root_ref) = link_to pluralize(number_with_delimiter(@repository.branch_names.count), 'branch'), project_branches_path(@project) = link_to pluralize(number_with_delimiter(@repository.tag_names.count), 'tag'), project_tags_path(@project) %span.light.prepend-left-20= repository_size + %span.star.js-toggler-container{class: @show_star ? 'on' : ''} + - if current_user + = link_to_toggle_star('Star this project.', false, true) + = link_to_toggle_star('Unstar this project.', true, true) + - else + = link_to_toggle_star('You must sign in to star a project.', false, false) diff --git a/config/routes.rb b/config/routes.rb index f54f9ea53416281980b5284769606e7f5ceb678d..f8c68eb11a1fb46757d48ed457c23edd149b82ee 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -185,6 +185,7 @@ Gitlab::Application.routes.draw do post :archive post :unarchive post :upload_image + post :toggle_star get :autocomplete_sources get :import put :retry_import diff --git a/db/migrate/20140625115202_create_users_star_projects.rb b/db/migrate/20140625115202_create_users_star_projects.rb new file mode 100644 index 0000000000000000000000000000000000000000..412f0f6f34be75240d3f66552239a9c04d596f2c --- /dev/null +++ b/db/migrate/20140625115202_create_users_star_projects.rb @@ -0,0 +1,15 @@ +class CreateUsersStarProjects < ActiveRecord::Migration + def change + create_table :users_star_projects do |t| + t.integer :project_id, null: false + t.integer :user_id, null: false + t.timestamps + end + add_index :users_star_projects, :user_id + add_index :users_star_projects, :project_id + add_index :users_star_projects, [:user_id, :project_id], unique: true + + add_column :projects, :star_count, :integer, default: 0, null: false + add_index :projects, :star_count, using: :btree + end +end diff --git a/db/schema.rb b/db/schema.rb index 345b6fd3b68f710c0ea9577e1f0fb89624ecc58a..e4dcdf5bea2b6d554e7b9eba64ab4b7aeecf1210 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140611135229) do +ActiveRecord::Schema.define(version: 20140625115202) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -224,11 +224,13 @@ ActiveRecord::Schema.define(version: 20140611135229) do t.boolean "archived", default: false, null: false t.string "import_status" t.float "repository_size", default: 0.0 + t.integer "star_count", default: 0, null: false end add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree add_index "projects", ["last_activity_at"], name: "index_projects_on_last_activity_at", using: :btree add_index "projects", ["namespace_id"], name: "index_projects_on_namespace_id", using: :btree + add_index "projects", ["star_count"], name: "index_projects_on_star_count", using: :btree create_table "protected_branches", force: true do |t| t.integer "project_id", null: false @@ -369,6 +371,17 @@ ActiveRecord::Schema.define(version: 20140611135229) do add_index "users_projects", ["project_id"], name: "index_users_projects_on_project_id", using: :btree add_index "users_projects", ["user_id"], name: "index_users_projects_on_user_id", using: :btree + create_table "users_star_projects", force: true do |t| + t.integer "project_id", null: false + t.integer "user_id", null: false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "users_star_projects", ["project_id"], name: "index_users_star_projects_on_project_id", using: :btree + add_index "users_star_projects", ["user_id", "project_id"], name: "index_users_star_projects_on_user_id_and_project_id", unique: true, using: :btree + add_index "users_star_projects", ["user_id"], name: "index_users_star_projects_on_user_id", using: :btree + create_table "web_hooks", force: true do |t| t.string "url" t.integer "project_id" diff --git a/features/project/star.feature b/features/project/star.feature new file mode 100644 index 0000000000000000000000000000000000000000..d8d898155feb27c7f0d5acb066eb5d83424e3766 --- /dev/null +++ b/features/project/star.feature @@ -0,0 +1,38 @@ +Feature: Project Star + Scenario: New projects have 0 stars + Given public project "Community" + When I visit project "Community" page + Then The project has 0 stars + + Scenario: Empty projects show star count + Given public empty project "Empty Public Project" + When I visit empty project page + Then The project has 0 stars + + Scenario: Signed off users can't star projects + Given public project "Community" + And I visit project "Community" page + When I click on the star toggle button + Then The project has 0 stars + + @javascript + Scenario: Signed in users can toggle star + Given I sign in as "John Doe" + And public project "Community" + And I visit project "Community" page + When I click on the star toggle button + Then The project has 1 star + When I click on the star toggle button + Then The project has 0 stars + + @javascript + Scenario: Star count sums stars + Given I sign in as "John Doe" + And public project "Community" + And I visit project "Community" page + And I click on the star toggle button + And I logout + And I sign in as "Mary Jane" + And I visit project "Community" page + When I click on the star toggle button + Then The project has 2 stars diff --git a/features/steps/explore/projects.rb b/features/steps/explore/projects.rb index 8aa2916014bcfe9380b09a44ad9a47c760659827..dfd51060738ecc5438f5d93e5e2b451ed035535c 100644 --- a/features/steps/explore/projects.rb +++ b/features/steps/explore/projects.rb @@ -3,10 +3,6 @@ class Spinach::Features::ExploreProjectsFeature < Spinach::FeatureSteps include SharedPaths include SharedProject - step 'public empty project "Empty Public Project"' do - create :empty_project, :public, name: 'Empty Public Project' - end - step 'I should see project "Empty Public Project"' do page.should have_content "Empty Public Project" end @@ -20,16 +16,6 @@ class Spinach::Features::ExploreProjectsFeature < Spinach::FeatureSteps page.should have_content 'README.md' end - step 'I visit empty project page' do - project = Project.find_by(name: 'Empty Public Project') - visit project_path(project) - end - - step 'I visit project "Community" page' do - project = Project.find_by(name: 'Community') - visit project_path(project) - end - step 'I should see empty public project details' do page.should have_content 'Git global setup' end @@ -48,22 +34,12 @@ class Spinach::Features::ExploreProjectsFeature < Spinach::FeatureSteps end end - step 'I visit project "Enterprise" page' do - project = Project.find_by(name: 'Enterprise') - visit project_path(project) - end - step 'I should see project "Community" home page' do within '.project-home-title' do page.should have_content 'Community' end end - step 'I visit project "Internal" page' do - project = Project.find_by(name: 'Internal') - visit project_path(project) - end - step 'I should see project "Internal" home page' do within '.project-home-title' do page.should have_content 'Internal' diff --git a/features/steps/project/star.rb b/features/steps/project/star.rb new file mode 100644 index 0000000000000000000000000000000000000000..11102900ed4e4b4576a95ac130ca81290e98c7fe --- /dev/null +++ b/features/steps/project/star.rb @@ -0,0 +1,29 @@ +class Spinach::Features::ProjectStar < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + include SharedUser + + step "The project has 0 stars" do + has_n_stars(0) + end + + step "The project has 1 star" do + has_n_stars(1) + end + + step "The project has 2 stars" do + has_n_stars(2) + end + + # Requires @javascript + step "I click on the star toggle button" do + page.find(".star .toggle", visible: true).click + end + + protected + + def has_n_stars(n) + expect(page).to have_css(".star .count", text: /^#{n}$/, visible: true) + end +end diff --git a/features/steps/shared/authentication.rb b/features/steps/shared/authentication.rb index b8c11ce0a23d32eb5f80bfda8784e3cfd37568fe..b48021dc146548e42f0470b4a29df38511edd590 100644 --- a/features/steps/shared/authentication.rb +++ b/features/steps/shared/authentication.rb @@ -24,6 +24,10 @@ module SharedAuthentication current_path.should == new_user_session_path end + step "I logout" do + logout + end + def current_user @user || User.first end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index a0b4099ab3ed3b065e4080942e712a9e0bbe6e61..111d40c0e1b9c23230a45b0409104f315f28972f 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -319,6 +319,34 @@ module SharedPaths visit project_wiki_path(@project, :home) end + # ---------------------------------------- + # Visibility Projects + # ---------------------------------------- + + step 'I visit project "Community" page' do + project = Project.find_by(name: "Community") + visit project_path(project) + end + + step 'I visit project "Internal" page' do + project = Project.find_by(name: "Internal") + visit project_path(project) + end + + step 'I visit project "Enterprise" page' do + project = Project.find_by(name: "Enterprise") + visit project_path(project) + end + + # ---------------------------------------- + # Empty Projects + # ---------------------------------------- + + step "I visit empty project page" do + project = Project.find_by(name: "Empty Public Project") + visit project_path(project) + end + # ---------------------------------------- # Public Projects # ---------------------------------------- @@ -327,10 +355,6 @@ module SharedPaths visit explore_projects_path end - step 'I visit public page for "Community" project' do - visit public_project_path(Project.find_by(name: "Community")) - end - # ---------------------------------------- # Public Groups # ---------------------------------------- diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index ddb87daeeb78ed361409ec319def6033d3599f3d..ba6f090a7069dd701765d060095d49d861162660 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -122,4 +122,12 @@ module SharedProject project ||= create :empty_project, :public, name: 'Community', namespace: user.namespace project.team << [user, :master] end + + # ---------------------------------------- + # Empty projects + # ---------------------------------------- + + step 'public empty project "Empty Public Project"' do + create :empty_project, :public, name: "Empty Public Project" + end end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 944df5314bd04c6e3c9c4fd9196c7340ea9e621b..71bc49787cccdb42b00a3a1f999a2e7b04a7bb6f 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -2,6 +2,7 @@ require('spec_helper') describe ProjectsController do let(:project) { create(:project) } + let(:public_project) { create(:project, :public) } let(:user) { create(:user) } let(:jpg) { fixture_file_upload(Rails.root + 'spec/fixtures/rails_sample.jpg', 'image/jpg') } let(:txt) { fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') } @@ -40,4 +41,22 @@ describe ProjectsController do end end end + + describe "POST #toggle_star" do + it "toggles star if user is signed in" do + sign_in(user) + expect(user.starred?(public_project)).to be_false + post :toggle_star, id: public_project.to_param + expect(user.starred?(public_project)).to be_true + post :toggle_star, id: public_project.to_param + expect(user.starred?(public_project)).to be_false + end + + it "does nothing if user is not signed in" do + post :toggle_star, id: public_project.to_param + expect(user.starred?(public_project)).to be_false + post :toggle_star, id: public_project.to_param + expect(user.starred?(public_project)).to be_false + end + end end diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index d7f3f3a302c9c04f5fa10f2cec8e107af0c239d4..f0daf081018ed376a06f83e338e226fda9c2788b 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -226,7 +226,7 @@ describe "Issues", feature: true do issue.save end - it 'shows assignee text' do + it "shows assignee text", js: true do logout login_with guest @@ -262,7 +262,7 @@ describe "Issues", feature: true do issue.save end - it 'shows milestone text' do + it "shows milestone text", js: true do logout login_with guest diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index c3263ed0fe79c91876f8e3a0a65dbe5b19e0b94c..bc537b7312b94c038129bc4910bfa27df09a46f9 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -240,4 +240,73 @@ describe Project do it { project.open_branches.map(&:name).should include('bootstrap') } it { project.open_branches.map(&:name).should_not include('master') } end + + describe '#star_count' do + it 'counts stars from multiple users' do + user1 = create :user + user2 = create :user + project = create :project, :public + + expect(project.star_count).to eq(0) + + user1.toggle_star(project) + expect(project.reload.star_count).to eq(1) + + user2.toggle_star(project) + project.reload + expect(project.reload.star_count).to eq(2) + + user1.toggle_star(project) + project.reload + expect(project.reload.star_count).to eq(1) + + user2.toggle_star(project) + project.reload + expect(project.reload.star_count).to eq(0) + end + + it 'counts stars on the right project' do + user = create :user + project1 = create :project, :public + project2 = create :project, :public + + expect(project1.star_count).to eq(0) + expect(project2.star_count).to eq(0) + + user.toggle_star(project1) + project1.reload + project2.reload + expect(project1.star_count).to eq(1) + expect(project2.star_count).to eq(0) + + user.toggle_star(project1) + project1.reload + project2.reload + expect(project1.star_count).to eq(0) + expect(project2.star_count).to eq(0) + + user.toggle_star(project2) + project1.reload + project2.reload + expect(project1.star_count).to eq(0) + expect(project2.star_count).to eq(1) + + user.toggle_star(project2) + project1.reload + project2.reload + expect(project1.star_count).to eq(0) + expect(project2.star_count).to eq(0) + end + + it 'is decremented when an upvoter account is deleted' do + user = create :user + project = create :project, :public + user.toggle_star(project) + project.reload + expect(project.star_count).to eq(1) + user.destroy + project.reload + expect(project.star_count).to eq(0) + end + end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a36b57a95de8d41eadf2a24dd25fe3c10b7be71e..ef6b8a94502b298d7052791e03fbff594928baf5 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -355,4 +355,44 @@ describe User do expect(user.short_website_url).to eq 'test.com' end end + + describe "#starred?" do + it "determines if user starred a project" do + user = create :user + project1 = create :project, :public + project2 = create :project, :public + + expect(user.starred?(project1)).to be_false + expect(user.starred?(project2)).to be_false + + star1 = UsersStarProject.create!(project: project1, user: user) + expect(user.starred?(project1)).to be_true + expect(user.starred?(project2)).to be_false + + star2 = UsersStarProject.create!(project: project2, user: user) + expect(user.starred?(project1)).to be_true + expect(user.starred?(project2)).to be_true + + star1.destroy + expect(user.starred?(project1)).to be_false + expect(user.starred?(project2)).to be_true + + star2.destroy + expect(user.starred?(project1)).to be_false + expect(user.starred?(project2)).to be_false + end + end + + describe "#toggle_star" do + it "toggles stars" do + user = create :user + project = create :project, :public + + expect(user.starred?(project)).to be_false + user.toggle_star(project) + expect(user.starred?(project)).to be_true + user.toggle_star(project) + expect(user.starred?(project)).to be_false + end + end end diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb index 7713e9f17d7257179896c9628c110686c0aa00e3..238ac7c6611a4637568562e6a17639ba6aea0f7b 100644 --- a/spec/support/login_helpers.rb +++ b/spec/support/login_helpers.rb @@ -19,7 +19,8 @@ module LoginHelpers Thread.current[:current_user] = user end + # Requires Javascript driver. def logout - click_link "Logout" rescue nil + page.find(:css, ".icon-signout").click end end