Commit 9b5c7a4d authored by Ciro Santilli's avatar Ciro Santilli

Add star count, view logic, more tests.

parent ecd771cc
...@@ -60,6 +60,8 @@ class ProjectsController < ApplicationController ...@@ -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 and 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?
...@@ -169,6 +171,7 @@ class ProjectsController < ApplicationController ...@@ -169,6 +171,7 @@ class ProjectsController < ApplicationController
def toggle_star def toggle_star
current_user.toggle_star(@project) current_user.toggle_star(@project)
@project.reload
render json: { star_count: @project.star_count } render json: { star_count: @project.star_count }
end end
......
...@@ -22,6 +22,7 @@ ...@@ -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
...@@ -109,6 +110,7 @@ class Project < ActiveRecord::Base ...@@ -109,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
...@@ -577,8 +579,4 @@ class Project < ActiveRecord::Base ...@@ -577,8 +579,4 @@ class Project < ActiveRecord::Base
def update_repository_size def update_repository_size
update_attribute(:repository_size, repository.size) update_attribute(:repository_size, repository.size)
end end
def star_count
starrers.count
end
end end
...@@ -516,7 +516,8 @@ class User < ActiveRecord::Base ...@@ -516,7 +516,8 @@ class User < ActiveRecord::Base
end end
def toggle_star(project) def toggle_star(project)
user_star_project = users_star_projects.where(project: project).take user_star_project = users_star_projects.
where(project: project, user: self).take
if user_star_project if user_star_project
user_star_project.destroy user_star_project.destroy
else else
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
class UsersStarProject < ActiveRecord::Base class UsersStarProject < ActiveRecord::Base
belongs_to :project belongs_to :project, counter_cache: :star_count
belongs_to :user belongs_to :user
validates :user, presence: true validates :user, presence: true
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
= 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.on %span.star.js-toggler-container{class: @show_star ? 'on' : ''}
- if current_user - if current_user
= render 'link_to_toggle_star', = render 'link_to_toggle_star',
title: 'Star this project.', title: 'Star this project.',
......
...@@ -5,9 +5,11 @@ class CreateUsersStarProjects < ActiveRecord::Migration ...@@ -5,9 +5,11 @@ class CreateUsersStarProjects < ActiveRecord::Migration
t.integer :user_id, null: false t.integer :user_id, null: false
t.timestamps t.timestamps
end end
add_index :users_star_projects, :user_id add_index :users_star_projects, :user_id
add_index :users_star_projects, :project_id add_index :users_star_projects, :project_id
add_index :users_star_projects, [:user_id, :project_id], unique: true 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
end end
...@@ -224,11 +224,13 @@ ActiveRecord::Schema.define(version: 20140625115202) do ...@@ -224,11 +224,13 @@ ActiveRecord::Schema.define(version: 20140625115202) 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
......
...@@ -43,15 +43,20 @@ describe ProjectsController do ...@@ -43,15 +43,20 @@ describe ProjectsController do
end end
describe "POST #toggle_star" do describe "POST #toggle_star" do
it "increases star count if user is signed in" do it "toggles star if user is signed in" do
sign_in(user) sign_in(user)
expect(user.starred?(public_project)).to be_false
post :toggle_star, id: public_project.to_param post :toggle_star, id: public_project.to_param
expect(public_project.star_count).to eq(1) 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 end
it "does nothing if user is not signed in" do it "does nothing if user is not signed in" do
post :toggle_star, id: public_project.to_param post :toggle_star, id: public_project.to_param
expect(public_project.star_count).to eq(0) 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
end end
...@@ -241,21 +241,61 @@ describe Project do ...@@ -241,21 +241,61 @@ describe Project do
it { project.open_branches.map(&:name).should_not include('master') } it { project.open_branches.map(&:name).should_not include('master') }
end end
describe "#count_star" do describe "#star_count" do
it "counts stars" do it "counts stars from multiple users" do
user1 = create :user user1 = create :user
user2 = create :user user2 = create :user
project = create :project, :public project = create :project, :public
expect(project.star_count).to eq(0) expect(project.star_count).to eq(0)
user1.toggle_star(project) user1.toggle_star(project)
expect(project.star_count).to eq(1) expect(project.reload.star_count).to eq(1)
user2.toggle_star(project) user2.toggle_star(project)
expect(project.star_count).to eq(2) project.reload
expect(project.reload.star_count).to eq(2)
user1.toggle_star(project) user1.toggle_star(project)
expect(project.star_count).to eq(1) project.reload
expect(project.reload.star_count).to eq(1)
user2.toggle_star(project) user2.toggle_star(project)
expect(project.star_count).to eq(0) 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 end
end end
end end
...@@ -356,6 +356,33 @@ describe User do ...@@ -356,6 +356,33 @@ describe User do
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 describe "#toggle_star" do
it "toggles stars" do it "toggles stars" do
user = create :user user = create :user
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment