Commit 057737c75948c927671135f03db78f471acfa942

Authored by Heitor
Committed by Diego Camarinha
1 parent df999352

Fix ProjectAttributes association with Project

  * Renamed ProjectAttributes' column hidden to public and inverted
    default values
  * Implemented Project#"public_or_owned_by_user"
  * All features now create ProjectAttributes after creating a Project
  * Implemented ProjectAttributes#project and ProjectAttributes#project=
  * Fix Project#attributes to return nil when there is no
    ProjectAttribute
  * Fixes #263

Signed off by: Diego Araújo <diegoamc90@gmail.com>
app/controllers/projects_controller.rb
@@ -13,7 +13,7 @@ class ProjectsController &lt; ApplicationController @@ -13,7 +13,7 @@ class ProjectsController &lt; ApplicationController
13 # GET /projects 13 # GET /projects
14 # GET /projects.json 14 # GET /projects.json
15 def index 15 def index
16 - @projects = Project.all.select { |project| !project.attributes.hidden } 16 + @projects = Project.public_or_owned_by_user(current_user)
17 end 17 end
18 18
19 # POST /projects 19 # POST /projects
app/models/project.rb
@@ -3,18 +3,30 @@ class Project &lt; KalibroClient::Entities::Processor::Project @@ -3,18 +3,30 @@ class Project &lt; KalibroClient::Entities::Processor::Project
3 3
4 attr_writer :attributes 4 attr_writer :attributes
5 5
  6 + def self.public_or_owned_by_user(user = nil)
  7 + project_attributes = ProjectAttributes.where(public: true)
  8 + project_attributes += ProjectAttributes.where(user_id: user.id, public: false) if user
  9 +
  10 + project_attributes.map do |attribute|
  11 + begin
  12 + self.find(attribute.project_id)
  13 + rescue KalibroClient::Errors::RecordNotFound
  14 + nil
  15 + end
  16 + end.compact
  17 + end
  18 +
6 def self.latest(count = 1) 19 def self.latest(count = 1)
7 - all.sort { |a,b| b.id <=> a.id }.select { |project| !project.attributes.hidden}.first(count) 20 + all.sort { |a, b| b.id <=> a.id }.select { |project| project.attributes.public }.first(count)
8 end 21 end
9 22
10 def attributes 23 def attributes
11 - @project_attributes ||= ProjectAttributes.find_by_project_id(self.id)  
12 - @project_attributes.nil? ? ProjectAttributes.new : @project_attributes 24 + @attributes ||= ProjectAttributes.find_by_project_id(@id)
13 end 25 end
14 26
15 def destroy 27 def destroy
16 - self.attributes.destroy if self.attributes  
17 - @project_attributes = nil 28 + self.attributes.destroy unless self.attributes.nil?
  29 + @attributes = nil
18 super 30 super
19 end 31 end
20 end 32 end
app/models/project_attributes.rb
@@ -4,6 +4,11 @@ class ProjectAttributes &lt; ActiveRecord::Base @@ -4,6 +4,11 @@ class ProjectAttributes &lt; ActiveRecord::Base
4 validates :user, presence: true 4 validates :user, presence: true
5 5
6 def project 6 def project
7 - Project.find(self.project_id) 7 + @project ||= Project.find(project_id)
  8 + end
  9 +
  10 + def project=(project)
  11 + @project = project
  12 + self.project_id = project.id
8 end 13 end
9 end 14 end
db/migrate/20151106182639_change_project_attributes_public_default.rb 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +class ChangeProjectAttributesPublicDefault < ActiveRecord::Migration
  2 + def change
  3 + rename_column :project_attributes, :hidden, :public
  4 + change_column_default :project_attributes, :public, true
  5 + end
  6 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended that you check this file into your version control system. 12 # It's strongly recommended that you check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(version: 20150616164352) do 14 +ActiveRecord::Schema.define(version: 20151106182639) do
15 15
16 create_table "kalibro_configuration_attributes", force: :cascade do |t| 16 create_table "kalibro_configuration_attributes", force: :cascade do |t|
17 t.integer "user_id" 17 t.integer "user_id"
@@ -25,9 +25,9 @@ ActiveRecord::Schema.define(version: 20150616164352) do @@ -25,9 +25,9 @@ ActiveRecord::Schema.define(version: 20150616164352) do
25 t.integer "project_id" 25 t.integer "project_id"
26 t.string "image_url" 26 t.string "image_url"
27 t.integer "user_id" 27 t.integer "user_id"
28 - t.boolean "hidden", default: false  
29 - t.datetime "created_at", null: false  
30 - t.datetime "updated_at", null: false 28 + t.boolean "public", default: true
  29 + t.datetime "created_at", null: false
  30 + t.datetime "updated_at", null: false
31 end 31 end
32 32
33 create_table "reading_group_attributes", force: :cascade do |t| 33 create_table "reading_group_attributes", force: :cascade do |t|
@@ -48,19 +48,19 @@ ActiveRecord::Schema.define(version: 20150616164352) do @@ -48,19 +48,19 @@ ActiveRecord::Schema.define(version: 20150616164352) do
48 add_index "repository_attributes", ["user_id"], name: "index_repository_attributes_on_user_id" 48 add_index "repository_attributes", ["user_id"], name: "index_repository_attributes_on_user_id"
49 49
50 create_table "users", force: :cascade do |t| 50 create_table "users", force: :cascade do |t|
51 - t.string "name", limit: 255, default: "", null: false  
52 - t.string "email", limit: 255, default: "", null: false 51 + t.string "name", default: "", null: false
  52 + t.string "email", default: "", null: false
53 t.datetime "created_at" 53 t.datetime "created_at"
54 t.datetime "updated_at" 54 t.datetime "updated_at"
55 - t.string "encrypted_password", limit: 255, default: "", null: false  
56 - t.string "reset_password_token", limit: 255 55 + t.string "encrypted_password", default: "", null: false
  56 + t.string "reset_password_token"
57 t.datetime "reset_password_sent_at" 57 t.datetime "reset_password_sent_at"
58 t.datetime "remember_created_at" 58 t.datetime "remember_created_at"
59 - t.integer "sign_in_count", default: 0 59 + t.integer "sign_in_count", default: 0
60 t.datetime "current_sign_in_at" 60 t.datetime "current_sign_in_at"
61 t.datetime "last_sign_in_at" 61 t.datetime "last_sign_in_at"
62 - t.string "current_sign_in_ip", limit: 255  
63 - t.string "last_sign_in_ip", limit: 255 62 + t.string "current_sign_in_ip"
  63 + t.string "last_sign_in_ip"
64 end 64 end
65 65
66 add_index "users", ["email"], name: "index_users_on_email", unique: true 66 add_index "users", ["email"], name: "index_users_on_email", unique: true
features/project/deletion.feature
@@ -22,7 +22,6 @@ Feature: Project Deletion @@ -22,7 +22,6 @@ Feature: Project Deletion
22 Given I am a regular user 22 Given I am a regular user
23 And I am signed in 23 And I am signed in
24 And I own a sample project 24 And I own a sample project
25 - And I have sample project_attributes  
26 And I am at the Sample Project page 25 And I am at the Sample Project page
27 When I click the Destroy Project link 26 When I click the Destroy Project link
28 Then I should be in the All Projects page 27 Then I should be in the All Projects page
features/project/edition.feature
@@ -8,13 +8,12 @@ Feature: Project @@ -8,13 +8,12 @@ Feature: Project
8 Given I am a regular user 8 Given I am a regular user
9 And I am signed in 9 And I am signed in
10 And I own a sample project 10 And I own a sample project
11 - And I have sample project_attributes  
12 And I am at the All Projects page 11 And I am at the All Projects page
13 When I click the Edit link 12 When I click the Edit link
14 Then I should be in the Edit Project page 13 Then I should be in the Edit Project page
15 14
16 @kalibro_processor_restart 15 @kalibro_processor_restart
17 - Scenario: Should not show edit links from projects that doesn't belongs to me 16 + Scenario: Should not show edit links from projects that doesn't belong to me
18 Given I am a regular user 17 Given I am a regular user
19 And I am signed in 18 And I am signed in
20 And I have a sample project 19 And I have a sample project
@@ -22,7 +21,7 @@ Feature: Project @@ -22,7 +21,7 @@ Feature: Project
22 Then I should not see Edit within table 21 Then I should not see Edit within table
23 22
24 @kalibro_processor_restart 23 @kalibro_processor_restart
25 - Scenario: Should not render the edit page if the project doesn't belongs to the current user 24 + Scenario: Should not render the edit page if the project doesn't belong to the current user
26 Given I am a regular user 25 Given I am a regular user
27 And I am signed in 26 And I am signed in
28 And I have a sample project 27 And I have a sample project
@@ -35,7 +34,6 @@ Feature: Project @@ -35,7 +34,6 @@ Feature: Project
35 Given I am a regular user 34 Given I am a regular user
36 And I am signed in 35 And I am signed in
37 And I own a sample project 36 And I own a sample project
38 - And I have sample project_attributes  
39 And I am at the All Projects page 37 And I am at the All Projects page
40 When I click the Edit link 38 When I click the Edit link
41 Then The field "project[name]" should be filled with the sample project "name" 39 Then The field "project[name]" should be filled with the sample project "name"
@@ -46,7 +44,6 @@ Feature: Project @@ -46,7 +44,6 @@ Feature: Project
46 Given I am a regular user 44 Given I am a regular user
47 And I am signed in 45 And I am signed in
48 And I own a sample project 46 And I own a sample project
49 - And I have sample project_attributes  
50 And I am at the sample project edit page 47 And I am at the sample project edit page
51 And I fill the Name field with "Kalibro" 48 And I fill the Name field with "Kalibro"
52 And I fill the Description field with "Web Service to collect metrics" 49 And I fill the Description field with "Web Service to collect metrics"
@@ -61,7 +58,6 @@ Feature: Project @@ -61,7 +58,6 @@ Feature: Project
61 And I have a project named "Qt-Calculator" 58 And I have a project named "Qt-Calculator"
62 And I own a project named "Kalibro" 59 And I own a project named "Kalibro"
63 And I am at the sample project edit page 60 And I am at the sample project edit page
64 - And I have sample project_attributes  
65 And I fill the Name field with "Qt-Calculator" 61 And I fill the Name field with "Qt-Calculator"
66 When I press the Save button 62 When I press the Save button
67 Then I should see "Name has already been taken" 63 Then I should see "Name has already been taken"
@@ -71,7 +67,6 @@ Feature: Project @@ -71,7 +67,6 @@ Feature: Project
71 Given I am a regular user 67 Given I am a regular user
72 And I am signed in 68 And I am signed in
73 And I own a sample project 69 And I own a sample project
74 - And I have sample project_attributes  
75 And I am at the sample project edit page 70 And I am at the sample project edit page
76 And I fill the Description field with "Web Service to collect metrics" 71 And I fill the Description field with "Web Service to collect metrics"
77 When I press the Save button 72 When I press the Save button
@@ -82,7 +77,6 @@ Feature: Project @@ -82,7 +77,6 @@ Feature: Project
82 Given I am a regular user 77 Given I am a regular user
83 And I am signed in 78 And I am signed in
84 And I own a sample project 79 And I own a sample project
85 - And I have sample project_attributes  
86 And I am at the sample project edit page 80 And I am at the sample project edit page
87 And I fill the Name field with " " 81 And I fill the Name field with " "
88 When I press the Save button 82 When I press the Save button
features/project/listing.feature
@@ -25,7 +25,6 @@ Feature: Project listing @@ -25,7 +25,6 @@ Feature: Project listing
25 Given I am a regular user 25 Given I am a regular user
26 And I am signed in 26 And I am signed in
27 And I have a sample project 27 And I have a sample project
28 - And I have sample project_attributes  
29 And I am at the All Projects page 28 And I am at the All Projects page
30 When I click the Show link 29 When I click the Show link
31 Then the sample project should be there 30 Then the sample project should be there
features/project/show.feature
@@ -7,7 +7,6 @@ Feature: Show Project @@ -7,7 +7,6 @@ Feature: Show Project
7 Scenario: Should not show the create repository link to user that doesn't own the project 7 Scenario: Should not show the create repository link to user that doesn't own the project
8 Given I am a regular user 8 Given I am a regular user
9 And I have a sample project 9 And I have a sample project
10 - And I have sample project_attributes  
11 And I have a sample configuration with native metrics 10 And I have a sample configuration with native metrics
12 And I have a sample repository within the sample project 11 And I have a sample repository within the sample project
13 When I am at the Sample Project page 12 When I am at the Sample Project page
@@ -20,7 +19,6 @@ Scenario: Should show the create repository link the project owner @@ -20,7 +19,6 @@ Scenario: Should show the create repository link the project owner
20 Given I am a regular user 19 Given I am a regular user
21 And I am signed in 20 And I am signed in
22 And I own a sample project 21 And I own a sample project
23 - And I have sample project_attributes  
24 When I am at the Sample Project page 22 When I am at the Sample Project page
25 Then I should see "New Repository" 23 Then I should see "New Repository"
26 24
@@ -29,7 +27,6 @@ Scenario: Should not show the independent repositories for a project @@ -29,7 +27,6 @@ Scenario: Should not show the independent repositories for a project
29 Given I am a regular user 27 Given I am a regular user
30 And I am signed in 28 And I am signed in
31 And I own a sample project 29 And I own a sample project
32 - And I have sample project_attributes  
33 And I have a sample configuration 30 And I have a sample configuration
34 And I have a sample repository 31 And I have a sample repository
35 When I am at the Sample Project page 32 When I am at the Sample Project page
@@ -39,7 +36,6 @@ Scenario: Should not show the independent repositories for a project @@ -39,7 +36,6 @@ Scenario: Should not show the independent repositories for a project
39 Scenario: Considering the project has no repositories 36 Scenario: Considering the project has no repositories
40 Given I am a regular user 37 Given I am a regular user
41 And I have a sample project 38 And I have a sample project
42 - And I have sample project_attributes  
43 When I am at the Sample Project page 39 When I am at the Sample Project page
44 Then I should see "There are no Repositories yet!" 40 Then I should see "There are no Repositories yet!"
45 41
@@ -56,6 +52,5 @@ Scenario: Considering the project has repositories @@ -56,6 +52,5 @@ Scenario: Considering the project has repositories
56 Scenario: Checking project contents 52 Scenario: Checking project contents
57 Given I am a regular user 53 Given I am a regular user
58 And I have a sample project 54 And I have a sample project
59 - And I have sample project_attributes  
60 When I am at the Sample Project page 55 When I am at the Sample Project page
61 Then the sample project should be there 56 Then the sample project should be there
features/repository/create.feature
@@ -8,7 +8,6 @@ Scenario: repository creation associated with a project @@ -8,7 +8,6 @@ Scenario: repository creation associated with a project
8 Given I am a regular user 8 Given I am a regular user
9 And I am signed in 9 And I am signed in
10 And I own a sample project 10 And I own a sample project
11 - And I have sample project_attributes  
12 And I have a sample configuration with native metrics 11 And I have a sample configuration with native metrics
13 And I am at the New Repository page 12 And I am at the New Repository page
14 And I fill the Name field with "Kalibro" 13 And I fill the Name field with "Kalibro"
features/step_definitions/project_steps.rb
@@ -6,14 +6,12 @@ end @@ -6,14 +6,12 @@ end
6 6
7 Given(/^I have a sample project$/) do 7 Given(/^I have a sample project$/) do
8 @project = FactoryGirl.create(:project) 8 @project = FactoryGirl.create(:project)
9 -end  
10 -  
11 -Given(/^I have sample project_attributes$/) do  
12 - @project_attributes = FactoryGirl.create(:project_attributes, {id: nil, user_id: @user.id}) 9 + @project.attributes = FactoryGirl.create(:project_attributes, project: @project)
13 end 10 end
14 11
15 Given(/^I have a project named "(.*?)"$/) do |name| 12 Given(/^I have a project named "(.*?)"$/) do |name|
16 @project = FactoryGirl.create(:project, {name: name}) 13 @project = FactoryGirl.create(:project, {name: name})
  14 + @project.attributes = FactoryGirl.create(:project_attributes, project: @project)
17 end 15 end
18 16
19 Given(/^I own a sample project$/) do 17 Given(/^I own a sample project$/) do
spec/controllers/projects_controller_spec.rb
@@ -148,12 +148,10 @@ describe ProjectsController, :type =&gt; :controller do @@ -148,12 +148,10 @@ describe ProjectsController, :type =&gt; :controller do
148 end 148 end
149 149
150 describe 'index' do 150 describe 'index' do
151 - let(:project_attributes) { FactoryGirl.build(:project_attributes) } 151 + subject { FactoryGirl.build(:project_with_id) }
152 152
153 before :each do 153 before :each do
154 - @subject = FactoryGirl.build(:project_with_id)  
155 - Project.expects(:all).returns([@subject])  
156 - @subject.expects(:attributes).returns(project_attributes) 154 + Project.expects(:public_or_owned_by_user).returns([subject])
157 get :index 155 get :index
158 end 156 end
159 157
spec/factories/project_attributes.rb
1 FactoryGirl.define do 1 FactoryGirl.define do
2 factory :project_attributes, :class => 'ProjectAttributes' do 2 factory :project_attributes, :class => 'ProjectAttributes' do
3 - project_id 1  
4 image_url '' 3 image_url ''
5 - user_id 1  
6 - hidden false 4 + self.public true
  5 + association :project, :with_id, strategy: :build
  6 + association :user, strategy: :build
7 7
8 trait :with_image do 8 trait :with_image do
9 image_url '#' 9 image_url '#'
10 end 10 end
  11 +
  12 + trait :private do
  13 + self.public false
  14 + end
  15 +
  16 + trait :bare do
  17 + project_id nil
  18 + user_id nil
  19 + end
11 end 20 end
12 end 21 end
spec/models/project_attributes_spec.rb
@@ -11,10 +11,9 @@ RSpec.describe ProjectAttributes, type: :model do @@ -11,10 +11,9 @@ RSpec.describe ProjectAttributes, type: :model do
11 end 11 end
12 12
13 describe 'methods' do 13 describe 'methods' do
  14 + let(:project) { FactoryGirl.build(:project_with_id) }
14 describe 'project' do 15 describe 'project' do
15 - subject { FactoryGirl.build(:project_attributes) }  
16 - let(:project) {FactoryGirl.build(:project_with_id)}  
17 - 16 + subject { FactoryGirl.build(:project_attributes, :bare, project_id: project.id) }
18 before :each do 17 before :each do
19 Project.expects(:find).with(subject.project_id).returns(project) 18 Project.expects(:find).with(subject.project_id).returns(project)
20 end 19 end
@@ -23,5 +22,21 @@ RSpec.describe ProjectAttributes, type: :model do @@ -23,5 +22,21 @@ RSpec.describe ProjectAttributes, type: :model do
23 expect(subject.project).to eq(project) 22 expect(subject.project).to eq(project)
24 end 23 end
25 end 24 end
  25 +
  26 + describe 'project=' do
  27 + subject { FactoryGirl.build(:project_attributes, :bare) }
  28 +
  29 + before do
  30 + subject.project = project
  31 + end
  32 +
  33 + it 'is expected to set the project' do
  34 + expect(subject.project).to eq project
  35 + end
  36 +
  37 + it 'is expected to set the project_id' do
  38 + expect(subject.project_id).to eq project.id
  39 + end
  40 + end
26 end 41 end
27 end 42 end
spec/models/project_spec.rb
@@ -28,33 +28,47 @@ describe Project, :type =&gt; :model do @@ -28,33 +28,47 @@ describe Project, :type =&gt; :model do
28 describe 'attributes' do 28 describe 'attributes' do
29 subject { FactoryGirl.build(:project_with_id) } 29 subject { FactoryGirl.build(:project_with_id) }
30 30
31 - let!(:project_attributes) { FactoryGirl.build(:project_attributes) } 31 + context 'when there are attributes' do
  32 + let!(:project_attributes) { FactoryGirl.build(:project_attributes) }
32 33
33 - before :each do  
34 - ProjectAttributes.expects(:find_by_project_id).returns(project_attributes) 34 + before :each do
  35 + ProjectAttributes.expects(:find_by_project_id).returns(project_attributes)
  36 + end
  37 +
  38 + it 'is expected to return the project attributes' do
  39 + expect(subject.attributes).to eq(project_attributes)
  40 + end
35 end 41 end
36 42
37 - it 'is expected to return the project attributes' do  
38 - expect(subject.attributes).to eq(project_attributes) 43 + context 'when there are no attributes' do
  44 + before :each do
  45 + ProjectAttributes.expects(:find_by_project_id).returns(nil)
  46 + end
  47 +
  48 + it 'is expected to return the project attributes' do
  49 + expect(subject.attributes).to be_nil
  50 + end
39 end 51 end
40 end 52 end
41 53
42 describe 'destroy' do 54 describe 'destroy' do
  55 + let!(:project) { FactoryGirl.build(:project) }
  56 +
43 context 'when attributes exist' do 57 context 'when attributes exist' do
44 - let!(:project) { FactoryGirl.build(:project) }  
45 let!(:project_attributes) { FactoryGirl.build(:project_attributes, project_id: project.id) } 58 let!(:project_attributes) { FactoryGirl.build(:project_attributes, project_id: project.id) }
  59 + before :each do
  60 + KalibroClient::Entities::Processor::Project.any_instance.expects(:destroy).returns(project)
  61 + end
46 62
47 - it 'should be destroyed' do 63 + it 'is expected to be destroyed' do
48 project.expects(:attributes).twice.returns(project_attributes) 64 project.expects(:attributes).twice.returns(project_attributes)
49 project_attributes.expects(:destroy) 65 project_attributes.expects(:destroy)
50 - KalibroClient::Entities::Processor::Project.any_instance.expects(:destroy).returns(project)  
51 project.destroy 66 project.destroy
52 end 67 end
53 68
54 it 'is expected to clean the attributes memoization' do 69 it 'is expected to clean the attributes memoization' do
55 # Call attributes once so it memoizes 70 # Call attributes once so it memoizes
56 ProjectAttributes.expects(:find_by).with(project_id: project.id).returns(project_attributes) 71 ProjectAttributes.expects(:find_by).with(project_id: project.id).returns(project_attributes)
57 - KalibroClient::Entities::Processor::Project.any_instance.expects(:destroy).returns(project)  
58 expect(project.attributes).to eq(project_attributes) 72 expect(project.attributes).to eq(project_attributes)
59 73
60 # Destroying 74 # Destroying
@@ -65,6 +79,76 @@ describe Project, :type =&gt; :model do @@ -65,6 +79,76 @@ describe Project, :type =&gt; :model do
65 expect(project.attributes).to_not eq(project_attributes) 79 expect(project.attributes).to_not eq(project_attributes)
66 end 80 end
67 end 81 end
  82 +
  83 + context 'when attributes is nil' do
  84 + before do
  85 + project.expects(:attributes).returns(nil)
  86 + KalibroClient::Entities::Processor::Project.any_instance.expects(:destroy).returns(project)
  87 + end
  88 +
  89 + it 'is expected to not try to destroy the attributes' do
  90 + project.destroy
  91 + end
  92 + end
  93 + end
  94 + end
  95 +
  96 + describe 'class methods' do
  97 + describe 'public_or_owned_by_user' do
  98 + let!(:user) { FactoryGirl.build(:user, :with_id) }
  99 +
  100 + let!(:owned_private_attrs) { FactoryGirl.build(:project_attributes, :private, user_id: user.id) }
  101 + let!(:owned_public_attrs) { FactoryGirl.build(:project_attributes, user_id: user.id) }
  102 + let!(:not_owned_private_attrs) { FactoryGirl.build(:project_attributes, :private, user_id: user.id + 1) }
  103 + let!(:not_owned_public_attrs) { FactoryGirl.build(:project_attributes, user_id: user.id + 1) }
  104 +
  105 + let!(:public_attrs) { [owned_public_attrs, not_owned_public_attrs] }
  106 + let(:public_projects) { public_attrs.map(&:project) }
  107 +
  108 + let!(:owned_or_public_attrs) { public_attrs + [owned_private_attrs] }
  109 + let!(:owned_or_public_projects) { owned_or_public_attrs.map(&:project) }
  110 +
  111 + let(:all_projects) { owned_or_public_projects + [not_owned_private_attrs.project] }
  112 +
  113 + context 'when projects exist' do
  114 + before :each do
  115 + all_projects.each do |project|
  116 + described_class.stubs(:find).with(project.id).returns(project)
  117 + end
  118 +
  119 + ProjectAttributes.expects(:where).with(public: true).returns(public_attrs)
  120 + end
  121 +
  122 + context 'when user is not provided' do
  123 + it 'is expected to find all public reading groups' do
  124 + expect(described_class.public_or_owned_by_user).to eq(public_projects)
  125 + end
  126 + end
  127 +
  128 + context 'when user is provided' do
  129 + before do
  130 + ProjectAttributes.expects(:where).with(user_id: user.id, public: false).returns([owned_private_attrs])
  131 + end
  132 +
  133 + it 'is expected to find all public and owned reading groups' do
  134 + expect(described_class.public_or_owned_by_user(user)).to eq(owned_or_public_projects)
  135 + end
  136 + end
  137 + end
  138 +
  139 + context 'when no reading groups exist' do
  140 + before :each do
  141 + all_projects.each do |project|
  142 + described_class.stubs(:find).with(project.id).raises(KalibroClient::Errors::RecordNotFound)
  143 + end
  144 +
  145 + ProjectAttributes.expects(:where).with(public: true).returns(public_attrs)
  146 + end
  147 +
  148 + it 'is expected to be empty' do
  149 + expect(described_class.public_or_owned_by_user).to be_empty
  150 + end
  151 + end
68 end 152 end
69 end 153 end
70 end 154 end