Merge branch 'star' of https://github.com/cirosantilli/gitlabhq into cirosantilli-star
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> Conflicts: CHANGELOG
This commit is contained in:
commit
e21ca9f8b1
26 changed files with 380 additions and 37 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
v 7.2.0
|
||||||
|
- Add project stars (Ciro Santilli)
|
||||||
|
|
||||||
v 7.1.0
|
v 7.1.0
|
||||||
- Remove observers
|
- Remove observers
|
||||||
- Improve MR discussions
|
- Improve MR discussions
|
||||||
|
|
|
@ -46,3 +46,8 @@ $ ->
|
||||||
$.cookie('hide_no_ssh_message', 'false', { path: path })
|
$.cookie('hide_no_ssh_message', 'false', { path: path })
|
||||||
$(@).parents('.no-ssh-key-message').hide()
|
$(@).parents('.no-ssh-key-message').hide()
|
||||||
e.preventDefault()
|
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')
|
||||||
|
|
|
@ -4,3 +4,9 @@
|
||||||
.js-details-container .content.hide { display: block; }
|
.js-details-container .content.hide { display: block; }
|
||||||
.js-details-container.open .content { display: block; }
|
.js-details-container.open .content { display: block; }
|
||||||
.js-details-container.open .content.hide { display: none; }
|
.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; }
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-image: none;
|
background-image: none;
|
||||||
border: 1px solid transparent;
|
border: $btn-border;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
@ -19,7 +19,6 @@
|
||||||
user-select: none;
|
user-select: none;
|
||||||
color: #444444;
|
color: #444444;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-color: #ccc;
|
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
|
|
||||||
&.hover,
|
&.hover,
|
||||||
|
|
|
@ -10,6 +10,8 @@ $hover: #D9EDF7;
|
||||||
$link_color: #446e9b;
|
$link_color: #446e9b;
|
||||||
$link_hover_color: #2FA0BB;
|
$link_hover_color: #2FA0BB;
|
||||||
|
|
||||||
|
$btn-border: 1px solid #ccc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Success colors (green)
|
* Success colors (green)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -50,6 +50,22 @@
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
font-weight: 500;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,8 @@ class ProjectsController < ApplicationController
|
||||||
@events = event_filter.apply_filter(@events)
|
@events = event_filter.apply_filter(@events)
|
||||||
@events = @events.limit(limit).offset(params[:offset] || 0)
|
@events = @events.limit(limit).offset(params[:offset] || 0)
|
||||||
|
|
||||||
|
@show_star = !(current_user && current_user.starred?(@project))
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
if @project.empty_repo?
|
if @project.empty_repo?
|
||||||
|
@ -167,6 +169,12 @@ class ProjectsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def toggle_star
|
||||||
|
current_user.toggle_star(@project)
|
||||||
|
@project.reload
|
||||||
|
render json: { star_count: @project.star_count }
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def upload_path
|
def upload_path
|
||||||
|
|
|
@ -122,6 +122,28 @@ module ProjectsHelper
|
||||||
options_for_select(values, current_tracker)
|
options_for_select(values, current_tracker)
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def get_project_nav_tabs(project, current_user)
|
def get_project_nav_tabs(project, current_user)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
# visibility_level :integer default(0), not null
|
# visibility_level :integer default(0), not null
|
||||||
# archived :boolean default(FALSE), not null
|
# archived :boolean default(FALSE), not null
|
||||||
# import_status :string(255)
|
# import_status :string(255)
|
||||||
|
# star_count :integer
|
||||||
#
|
#
|
||||||
|
|
||||||
class Project < ActiveRecord::Base
|
class Project < ActiveRecord::Base
|
||||||
|
@ -81,6 +82,8 @@ class Project < ActiveRecord::Base
|
||||||
has_many :users, through: :users_projects
|
has_many :users, through: :users_projects
|
||||||
has_many :deploy_keys_projects, dependent: :destroy
|
has_many :deploy_keys_projects, dependent: :destroy
|
||||||
has_many :deploy_keys, through: :deploy_keys_projects
|
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 :name, to: :owner, allow_nil: true, prefix: true
|
||||||
delegate :members, to: :team, prefix: true
|
delegate :members, to: :team, prefix: true
|
||||||
|
@ -107,6 +110,7 @@ class Project < ActiveRecord::Base
|
||||||
validates :import_url,
|
validates :import_url,
|
||||||
format: { with: URI::regexp(%w(git http https)), message: "should be a valid url" },
|
format: { with: URI::regexp(%w(git http https)), message: "should be a valid url" },
|
||||||
if: :import?
|
if: :import?
|
||||||
|
validates :star_count, numericality: { greater_than_or_equal_to: 0 }
|
||||||
validate :check_limit, on: :create
|
validate :check_limit, on: :create
|
||||||
|
|
||||||
# Scopes
|
# Scopes
|
||||||
|
|
|
@ -91,6 +91,8 @@ class User < ActiveRecord::Base
|
||||||
has_many :personal_projects, through: :namespace, source: :projects
|
has_many :personal_projects, through: :namespace, source: :projects
|
||||||
has_many :projects, through: :users_projects
|
has_many :projects, through: :users_projects
|
||||||
has_many :created_projects, foreign_key: :creator_id, class_name: 'Project'
|
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 :snippets, dependent: :destroy, foreign_key: :author_id, class_name: "Snippet"
|
||||||
has_many :users_projects, dependent: :destroy
|
has_many :users_projects, dependent: :destroy
|
||||||
|
@ -517,4 +519,18 @@ class User < ActiveRecord::Base
|
||||||
def system_hook_service
|
def system_hook_service
|
||||||
SystemHooksService.new
|
SystemHooksService.new
|
||||||
end
|
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
|
end
|
||||||
|
|
19
app/models/users_star_project.rb
Normal file
19
app/models/users_star_project.rb
Normal file
|
@ -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
|
|
@ -27,10 +27,16 @@
|
||||||
= link_to project_blob_path(@project, tree_join(@repository.root_ref, readme.name)) do
|
= link_to project_blob_path(@project, tree_join(@repository.root_ref, readme.name)) do
|
||||||
= readme.name
|
= readme.name
|
||||||
|
|
||||||
- unless empty_repo
|
.col-md-5
|
||||||
.col-md-5
|
.project-home-links
|
||||||
.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.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.branch_names.count), 'branch'), project_branches_path(@project)
|
||||||
= link_to pluralize(number_with_delimiter(@repository.tag_names.count), 'tag'), project_tags_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.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)
|
||||||
|
|
|
@ -185,6 +185,7 @@ Gitlab::Application.routes.draw do
|
||||||
post :archive
|
post :archive
|
||||||
post :unarchive
|
post :unarchive
|
||||||
post :upload_image
|
post :upload_image
|
||||||
|
post :toggle_star
|
||||||
get :autocomplete_sources
|
get :autocomplete_sources
|
||||||
get :import
|
get :import
|
||||||
put :retry_import
|
put :retry_import
|
||||||
|
|
15
db/migrate/20140625115202_create_users_star_projects.rb
Normal file
15
db/migrate/20140625115202_create_users_star_projects.rb
Normal file
|
@ -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
|
15
db/schema.rb
15
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -224,11 +224,13 @@ ActiveRecord::Schema.define(version: 20140611135229) do
|
||||||
t.boolean "archived", default: false, null: false
|
t.boolean "archived", default: false, null: false
|
||||||
t.string "import_status"
|
t.string "import_status"
|
||||||
t.float "repository_size", default: 0.0
|
t.float "repository_size", default: 0.0
|
||||||
|
t.integer "star_count", default: 0, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree
|
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", ["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", ["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|
|
create_table "protected_branches", force: true do |t|
|
||||||
t.integer "project_id", null: false
|
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", ["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
|
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|
|
create_table "web_hooks", force: true do |t|
|
||||||
t.string "url"
|
t.string "url"
|
||||||
t.integer "project_id"
|
t.integer "project_id"
|
||||||
|
|
38
features/project/star.feature
Normal file
38
features/project/star.feature
Normal file
|
@ -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
|
|
@ -3,10 +3,6 @@ class Spinach::Features::ExploreProjectsFeature < Spinach::FeatureSteps
|
||||||
include SharedPaths
|
include SharedPaths
|
||||||
include SharedProject
|
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
|
step 'I should see project "Empty Public Project"' do
|
||||||
page.should have_content "Empty Public Project"
|
page.should have_content "Empty Public Project"
|
||||||
end
|
end
|
||||||
|
@ -20,16 +16,6 @@ class Spinach::Features::ExploreProjectsFeature < Spinach::FeatureSteps
|
||||||
page.should have_content 'README.md'
|
page.should have_content 'README.md'
|
||||||
end
|
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
|
step 'I should see empty public project details' do
|
||||||
page.should have_content 'Git global setup'
|
page.should have_content 'Git global setup'
|
||||||
end
|
end
|
||||||
|
@ -48,22 +34,12 @@ class Spinach::Features::ExploreProjectsFeature < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
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
|
step 'I should see project "Community" home page' do
|
||||||
within '.project-home-title' do
|
within '.project-home-title' do
|
||||||
page.should have_content 'Community'
|
page.should have_content 'Community'
|
||||||
end
|
end
|
||||||
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
|
step 'I should see project "Internal" home page' do
|
||||||
within '.project-home-title' do
|
within '.project-home-title' do
|
||||||
page.should have_content 'Internal'
|
page.should have_content 'Internal'
|
||||||
|
|
29
features/steps/project/star.rb
Normal file
29
features/steps/project/star.rb
Normal file
|
@ -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
|
|
@ -24,6 +24,10 @@ module SharedAuthentication
|
||||||
current_path.should == new_user_session_path
|
current_path.should == new_user_session_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
step "I logout" do
|
||||||
|
logout
|
||||||
|
end
|
||||||
|
|
||||||
def current_user
|
def current_user
|
||||||
@user || User.first
|
@user || User.first
|
||||||
end
|
end
|
||||||
|
|
|
@ -319,6 +319,34 @@ module SharedPaths
|
||||||
visit project_wiki_path(@project, :home)
|
visit project_wiki_path(@project, :home)
|
||||||
end
|
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
|
# Public Projects
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
|
@ -327,10 +355,6 @@ module SharedPaths
|
||||||
visit explore_projects_path
|
visit explore_projects_path
|
||||||
end
|
end
|
||||||
|
|
||||||
step 'I visit public page for "Community" project' do
|
|
||||||
visit public_project_path(Project.find_by(name: "Community"))
|
|
||||||
end
|
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# Public Groups
|
# Public Groups
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
|
|
|
@ -122,4 +122,12 @@ module SharedProject
|
||||||
project ||= create :empty_project, :public, name: 'Community', namespace: user.namespace
|
project ||= create :empty_project, :public, name: 'Community', namespace: user.namespace
|
||||||
project.team << [user, :master]
|
project.team << [user, :master]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------
|
||||||
|
# Empty projects
|
||||||
|
# ----------------------------------------
|
||||||
|
|
||||||
|
step 'public empty project "Empty Public Project"' do
|
||||||
|
create :empty_project, :public, name: "Empty Public Project"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,7 @@ require('spec_helper')
|
||||||
|
|
||||||
describe ProjectsController do
|
describe ProjectsController do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
|
let(:public_project) { create(:project, :public) }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:jpg) { fixture_file_upload(Rails.root + 'spec/fixtures/rails_sample.jpg', 'image/jpg') }
|
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') }
|
let(:txt) { fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') }
|
||||||
|
@ -40,4 +41,22 @@ describe ProjectsController do
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -226,7 +226,7 @@ describe "Issues", feature: true do
|
||||||
issue.save
|
issue.save
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows assignee text' do
|
it "shows assignee text", js: true do
|
||||||
logout
|
logout
|
||||||
login_with guest
|
login_with guest
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ describe "Issues", feature: true do
|
||||||
issue.save
|
issue.save
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows milestone text' do
|
it "shows milestone text", js: true do
|
||||||
logout
|
logout
|
||||||
login_with guest
|
login_with guest
|
||||||
|
|
||||||
|
|
|
@ -240,4 +240,73 @@ describe Project do
|
||||||
it { project.open_branches.map(&:name).should include('bootstrap') }
|
it { project.open_branches.map(&:name).should include('bootstrap') }
|
||||||
it { project.open_branches.map(&:name).should_not include('master') }
|
it { project.open_branches.map(&:name).should_not include('master') }
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -355,4 +355,44 @@ describe User do
|
||||||
expect(user.short_website_url).to eq 'test.com'
|
expect(user.short_website_url).to eq 'test.com'
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -19,7 +19,8 @@ module LoginHelpers
|
||||||
Thread.current[:current_user] = user
|
Thread.current[:current_user] = user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Requires Javascript driver.
|
||||||
def logout
|
def logout
|
||||||
click_link "Logout" rescue nil
|
page.find(:css, ".icon-signout").click
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue