Commit 00a1f5bc2cc2c98bda3818e770eaae95e664480a
1 parent
91995909
Exists in
master
and in
4 other branches
Project has now correct owner and creator. Increased test coverage
Showing
15 changed files
with
241 additions
and
113 deletions
Show diff stats
app/controllers/dashboard_controller.rb
... | ... | @@ -20,7 +20,7 @@ class DashboardController < ApplicationController |
20 | 20 | |
21 | 21 | @projects = @projects.page(params[:page]).per(30) |
22 | 22 | |
23 | - @events = Event.in_projects(current_user.project_ids) | |
23 | + @events = Event.in_projects(current_user.authorized_projects.pluck(:id)) | |
24 | 24 | @events = @event_filter.apply_filter(@events) |
25 | 25 | @events = @events.limit(20).offset(params[:offset] || 0) |
26 | 26 | ... | ... |
app/controllers/groups_controller.rb
... | ... | @@ -70,7 +70,7 @@ class GroupsController < ApplicationController |
70 | 70 | end |
71 | 71 | |
72 | 72 | def projects |
73 | - @projects ||= group.projects.authorized_for(current_user).sorted_by_activity | |
73 | + @projects ||= current_user.authorized_projects.where(namespace_id: group.id).sorted_by_activity | |
74 | 74 | end |
75 | 75 | |
76 | 76 | def project_ids | ... | ... |
app/models/project.rb
... | ... | @@ -32,7 +32,7 @@ class Project < ActiveRecord::Base |
32 | 32 | attr_accessible :name, :path, :description, :default_branch, :issues_enabled, |
33 | 33 | :wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin] |
34 | 34 | |
35 | - attr_accessible :namespace_id, :owner_id, as: :admin | |
35 | + attr_accessible :namespace_id, :creator_id, as: :admin | |
36 | 36 | |
37 | 37 | attr_accessor :error_code |
38 | 38 | |
... | ... | @@ -40,10 +40,10 @@ class Project < ActiveRecord::Base |
40 | 40 | belongs_to :group, foreign_key: "namespace_id", conditions: "type = 'Group'" |
41 | 41 | belongs_to :namespace |
42 | 42 | |
43 | - # TODO: replace owner with creator. | |
44 | - # With namespaces a project owner will be a namespace owner | |
45 | - # so this field makes sense only for global projects | |
46 | - belongs_to :owner, class_name: "User" | |
43 | + belongs_to :creator, | |
44 | + class_name: "User", | |
45 | + foreign_key: "creator_id" | |
46 | + | |
47 | 47 | has_many :users, through: :users_projects |
48 | 48 | has_many :events, dependent: :destroy |
49 | 49 | has_many :merge_requests, dependent: :destroy |
... | ... | @@ -62,7 +62,7 @@ class Project < ActiveRecord::Base |
62 | 62 | delegate :name, to: :owner, allow_nil: true, prefix: true |
63 | 63 | |
64 | 64 | # Validations |
65 | - validates :owner, presence: true | |
65 | + validates :creator, presence: true | |
66 | 66 | validates :description, length: { within: 0..2000 } |
67 | 67 | validates :name, presence: true, length: { within: 0..255 }, |
68 | 68 | format: { with: Gitlab::Regex.project_name_regex, |
... | ... | @@ -89,8 +89,7 @@ class Project < ActiveRecord::Base |
89 | 89 | |
90 | 90 | class << self |
91 | 91 | def authorized_for user |
92 | - projects = includes(:users_projects, :namespace) | |
93 | - projects = projects.where("users_projects.user_id = :user_id or projects.owner_id = :user_id or namespaces.owner_id = :user_id", user_id: user.id) | |
92 | + raise "DERECATED" | |
94 | 93 | end |
95 | 94 | |
96 | 95 | def active |
... | ... | @@ -104,8 +103,10 @@ class Project < ActiveRecord::Base |
104 | 103 | def find_with_namespace(id) |
105 | 104 | if id.include?("/") |
106 | 105 | id = id.split("/") |
107 | - namespace_id = Namespace.find_by_path(id.first).id | |
108 | - where(namespace_id: namespace_id).find_by_path(id.second) | |
106 | + namespace = Namespace.find_by_path(id.first) | |
107 | + return nil unless namespace | |
108 | + | |
109 | + where(namespace_id: namespace.id).find_by_path(id.second) | |
109 | 110 | else |
110 | 111 | where(path: id, namespace_id: nil).last |
111 | 112 | end |
... | ... | @@ -125,7 +126,7 @@ class Project < ActiveRecord::Base |
125 | 126 | # |
126 | 127 | project.path = project.name.dup.parameterize |
127 | 128 | |
128 | - project.owner = user | |
129 | + project.creator = user | |
129 | 130 | |
130 | 131 | # Apply namespace if user has access to it |
131 | 132 | # else fallback to user namespace |
... | ... | @@ -174,8 +175,8 @@ class Project < ActiveRecord::Base |
174 | 175 | end |
175 | 176 | |
176 | 177 | def check_limit |
177 | - unless owner.can_create_project? | |
178 | - errors[:base] << ("Your own projects limit is #{owner.projects_limit}! Please contact administrator to increase it") | |
178 | + unless creator.can_create_project? | |
179 | + errors[:base] << ("Your own projects limit is #{creator.projects_limit}! Please contact administrator to increase it") | |
179 | 180 | end |
180 | 181 | rescue |
181 | 182 | errors[:base] << ("Can't check your ability to create project") |
... | ... | @@ -268,4 +269,12 @@ class Project < ActiveRecord::Base |
268 | 269 | Notify.project_was_moved_email(member.id).deliver |
269 | 270 | end |
270 | 271 | end |
272 | + | |
273 | + def owner | |
274 | + if namespace | |
275 | + namespace_owner | |
276 | + else | |
277 | + creator | |
278 | + end | |
279 | + end | |
271 | 280 | end | ... | ... |
app/models/user.rb
... | ... | @@ -51,7 +51,6 @@ class User < ActiveRecord::Base |
51 | 51 | has_many :groups, class_name: "Group", foreign_key: :owner_id |
52 | 52 | |
53 | 53 | has_many :keys, dependent: :destroy |
54 | - has_many :projects, through: :users_projects | |
55 | 54 | has_many :users_projects, dependent: :destroy |
56 | 55 | has_many :issues, foreign_key: :author_id, dependent: :destroy |
57 | 56 | has_many :notes, foreign_key: :author_id, dependent: :destroy |
... | ... | @@ -82,6 +81,9 @@ class User < ActiveRecord::Base |
82 | 81 | scope :active, where(blocked: false) |
83 | 82 | scope :alphabetically, order('name ASC') |
84 | 83 | |
84 | + # | |
85 | + # Class methods | |
86 | + # | |
85 | 87 | class << self |
86 | 88 | def filter filter_name |
87 | 89 | case filter_name |
... | ... | @@ -126,9 +128,63 @@ class User < ActiveRecord::Base |
126 | 128 | end |
127 | 129 | end |
128 | 130 | |
131 | + # | |
132 | + # Instance methods | |
133 | + # | |
129 | 134 | def generate_password |
130 | 135 | if self.force_random_password |
131 | 136 | self.password = self.password_confirmation = Devise.friendly_token.first(8) |
132 | 137 | end |
133 | 138 | end |
139 | + | |
140 | + | |
141 | + # Namespaces user has access to | |
142 | + def namespaces | |
143 | + namespaces = [] | |
144 | + | |
145 | + # Add user account namespace | |
146 | + namespaces << self.namespace if self.namespace | |
147 | + | |
148 | + # Add groups you can manage | |
149 | + namespaces += if admin | |
150 | + Group.all | |
151 | + else | |
152 | + groups.all | |
153 | + end | |
154 | + namespaces | |
155 | + end | |
156 | + | |
157 | + # Groups where user is an owner | |
158 | + def owned_groups | |
159 | + groups | |
160 | + end | |
161 | + | |
162 | + # Groups user has access to | |
163 | + def authorized_groups | |
164 | + @authorized_groups ||= begin | |
165 | + groups = Group.where(id: self.authorized_projects.pluck(:namespace_id)).all | |
166 | + groups = groups + self.groups | |
167 | + groups.uniq | |
168 | + end | |
169 | + end | |
170 | + | |
171 | + | |
172 | + # Projects user has access to | |
173 | + def authorized_projects | |
174 | + project_ids = users_projects.pluck(:project_id) | |
175 | + project_ids = project_ids | owned_projects.pluck(:id) | |
176 | + Project.where(id: project_ids) | |
177 | + end | |
178 | + | |
179 | + # Projects in user namespace | |
180 | + def personal_projects | |
181 | + Project.personal(self) | |
182 | + end | |
183 | + | |
184 | + # Projects where user is an owner | |
185 | + def owned_projects | |
186 | + Project.where("(projects.namespace_id IN (:namespaces)) OR | |
187 | + (projects.namespace_id IS NULL AND projects.creator_id = :user_id)", | |
188 | + namespaces: namespaces.map(&:id), user_id: self.id) | |
189 | + end | |
134 | 190 | end | ... | ... |
app/roles/account.rb
... | ... | @@ -25,7 +25,7 @@ module Account |
25 | 25 | end |
26 | 26 | |
27 | 27 | def can_create_project? |
28 | - projects_limit > my_own_projects.count | |
28 | + projects_limit > personal_projects.count | |
29 | 29 | end |
30 | 30 | |
31 | 31 | def can_create_group? |
... | ... | @@ -56,10 +56,6 @@ module Account |
56 | 56 | MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id) |
57 | 57 | end |
58 | 58 | |
59 | - def project_ids | |
60 | - projects.map(&:id) | |
61 | - end | |
62 | - | |
63 | 59 | # Remove user from all projects and |
64 | 60 | # set blocked attribute to true |
65 | 61 | def block |
... | ... | @@ -86,22 +82,7 @@ module Account |
86 | 82 | end |
87 | 83 | |
88 | 84 | def projects_sorted_by_activity |
89 | - projects.sorted_by_activity | |
90 | - end | |
91 | - | |
92 | - def namespaces | |
93 | - namespaces = [] | |
94 | - | |
95 | - # Add user account namespace | |
96 | - namespaces << self.namespace if self.namespace | |
97 | - | |
98 | - # Add groups you can manage | |
99 | - namespaces += if admin | |
100 | - Group.all | |
101 | - else | |
102 | - groups.all | |
103 | - end | |
104 | - namespaces | |
85 | + authorized_projects.sorted_by_activity | |
105 | 86 | end |
106 | 87 | |
107 | 88 | def several_namespaces? |
... | ... | @@ -111,20 +92,4 @@ module Account |
111 | 92 | def namespace_id |
112 | 93 | namespace.try :id |
113 | 94 | end |
114 | - | |
115 | - def authorized_groups | |
116 | - @authorized_groups ||= begin | |
117 | - groups = Group.where(id: self.projects.pluck(:namespace_id)).all | |
118 | - groups = groups + self.groups | |
119 | - groups.uniq | |
120 | - end | |
121 | - end | |
122 | - | |
123 | - def authorized_projects | |
124 | - Project.authorized_for(self) | |
125 | - end | |
126 | - | |
127 | - def my_own_projects | |
128 | - Project.personal(self) | |
129 | - end | |
130 | 95 | end | ... | ... |
app/roles/namespaced_project.rb
app/views/admin/projects/show.html.haml
... | ... | @@ -49,8 +49,8 @@ |
49 | 49 | %b |
50 | 50 | Owned by: |
51 | 51 | %td |
52 | - - if @project.chief | |
53 | - = link_to @project.chief.name, admin_user_path(@project.chief) | |
52 | + - if @project.owner | |
53 | + = link_to @project.owner_name, admin_user_path(@project.owner) | |
54 | 54 | - else |
55 | 55 | (deleted) |
56 | 56 | %tr |
... | ... | @@ -58,7 +58,7 @@ |
58 | 58 | %b |
59 | 59 | Created by: |
60 | 60 | %td |
61 | - = @project.owner_name || '(deleted)' | |
61 | + = @project.creator.try(:name) || '(deleted)' | |
62 | 62 | %tr |
63 | 63 | %td |
64 | 64 | %b | ... | ... |
app/views/dashboard/_groups.html.haml
db/migrate/20130102143055_rename_owner_to_creator_for_project.rb
0 → 100644
db/schema.rb
... | ... | @@ -11,7 +11,7 @@ |
11 | 11 | # |
12 | 12 | # It's strongly recommended to check this file into your version control system. |
13 | 13 | |
14 | -ActiveRecord::Schema.define(:version => 20121219095402) do | |
14 | +ActiveRecord::Schema.define(:version => 20130102143055) do | |
15 | 15 | |
16 | 16 | create_table "events", :force => true do |t| |
17 | 17 | t.string "target_type" |
... | ... | @@ -148,7 +148,7 @@ ActiveRecord::Schema.define(:version => 20121219095402) do |
148 | 148 | t.datetime "created_at", :null => false |
149 | 149 | t.datetime "updated_at", :null => false |
150 | 150 | t.boolean "private_flag", :default => true, :null => false |
151 | - t.integer "owner_id" | |
151 | + t.integer "creator_id" | |
152 | 152 | t.string "default_branch" |
153 | 153 | t.boolean "issues_enabled", :default => true, :null => false |
154 | 154 | t.boolean "wall_enabled", :default => true, :null => false |
... | ... | @@ -157,8 +157,8 @@ ActiveRecord::Schema.define(:version => 20121219095402) do |
157 | 157 | t.integer "namespace_id" |
158 | 158 | end |
159 | 159 | |
160 | + add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id" | |
160 | 161 | add_index "projects", ["namespace_id"], :name => "index_projects_on_namespace_id" |
161 | - add_index "projects", ["owner_id"], :name => "index_projects_on_owner_id" | |
162 | 162 | |
163 | 163 | create_table "protected_branches", :force => true do |t| |
164 | 164 | t.integer "project_id", :null => false | ... | ... |
spec/factories.rb
... | ... | @@ -9,7 +9,7 @@ FactoryGirl.define do |
9 | 9 | |
10 | 10 | sequence(:url) { Faker::Internet.uri('http') } |
11 | 11 | |
12 | - factory :user, aliases: [:author, :assignee, :owner] do | |
12 | + factory :user, aliases: [:author, :assignee, :owner, :creator] do | |
13 | 13 | email { Faker::Internet.email } |
14 | 14 | name |
15 | 15 | username { Faker::Internet.user_name } |
... | ... | @@ -26,7 +26,7 @@ FactoryGirl.define do |
26 | 26 | factory :project do |
27 | 27 | sequence(:name) { |n| "project#{n}" } |
28 | 28 | path { name.downcase.gsub(/\s/, '_') } |
29 | - owner | |
29 | + creator | |
30 | 30 | end |
31 | 31 | |
32 | 32 | factory :group do | ... | ... |
spec/models/project_security_spec.rb
spec/models/project_spec.rb
... | ... | @@ -24,7 +24,7 @@ describe Project do |
24 | 24 | describe "Associations" do |
25 | 25 | it { should belong_to(:group) } |
26 | 26 | it { should belong_to(:namespace) } |
27 | - it { should belong_to(:owner).class_name('User') } | |
27 | + it { should belong_to(:creator).class_name('User') } | |
28 | 28 | it { should have_many(:users) } |
29 | 29 | it { should have_many(:events).dependent(:destroy) } |
30 | 30 | it { should have_many(:merge_requests).dependent(:destroy) } |
... | ... | @@ -41,7 +41,7 @@ describe Project do |
41 | 41 | |
42 | 42 | describe "Mass assignment" do |
43 | 43 | it { should_not allow_mass_assignment_of(:namespace_id) } |
44 | - it { should_not allow_mass_assignment_of(:owner_id) } | |
44 | + it { should_not allow_mass_assignment_of(:creator_id) } | |
45 | 45 | it { should_not allow_mass_assignment_of(:private_flag) } |
46 | 46 | end |
47 | 47 | |
... | ... | @@ -55,20 +55,15 @@ describe Project do |
55 | 55 | it { should validate_presence_of(:path) } |
56 | 56 | it { should validate_uniqueness_of(:path) } |
57 | 57 | it { should ensure_length_of(:path).is_within(0..255) } |
58 | - # TODO: Formats | |
59 | - | |
60 | 58 | it { should ensure_length_of(:description).is_within(0..2000) } |
61 | - | |
62 | - # TODO: Formats | |
63 | - | |
64 | - it { should validate_presence_of(:owner) } | |
59 | + it { should validate_presence_of(:creator) } | |
65 | 60 | it { should ensure_inclusion_of(:issues_enabled).in_array([true, false]) } |
66 | 61 | it { should ensure_inclusion_of(:wall_enabled).in_array([true, false]) } |
67 | 62 | it { should ensure_inclusion_of(:merge_requests_enabled).in_array([true, false]) } |
68 | 63 | it { should ensure_inclusion_of(:wiki_enabled).in_array([true, false]) } |
69 | 64 | |
70 | 65 | it "should not allow new projects beyond user limits" do |
71 | - project.stub(:owner).and_return(double(can_create_project?: false, projects_limit: 1)) | |
66 | + project.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 1)) | |
72 | 67 | project.should_not be_valid |
73 | 68 | project.errors[:base].first.should match(/Your own projects limit is 1/) |
74 | 69 | end |
... | ... | @@ -134,7 +129,7 @@ describe Project do |
134 | 129 | it { should respond_to(:transfer) } |
135 | 130 | it { should respond_to(:name_with_namespace) } |
136 | 131 | it { should respond_to(:namespace_owner) } |
137 | - it { should respond_to(:chief) } | |
132 | + it { should respond_to(:owner) } | |
138 | 133 | it { should respond_to(:path_with_namespace) } |
139 | 134 | end |
140 | 135 | |
... | ... | @@ -211,4 +206,75 @@ describe Project do |
211 | 206 | @merge_request.last_commit.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" |
212 | 207 | end |
213 | 208 | end |
209 | + | |
210 | + describe :create_by_user do | |
211 | + before do | |
212 | + @user = create :user | |
213 | + @opts = { | |
214 | + name: "GitLab" | |
215 | + } | |
216 | + end | |
217 | + | |
218 | + context 'user namespace' do | |
219 | + before do | |
220 | + @project = Project.create_by_user(@opts, @user) | |
221 | + end | |
222 | + | |
223 | + it { @project.should be_valid } | |
224 | + it { @project.owner.should == @user } | |
225 | + it { @project.namespace.should == @user.namespace } | |
226 | + end | |
227 | + | |
228 | + context 'user namespace' do | |
229 | + before do | |
230 | + @group = create :group, owner: @user | |
231 | + @opts.merge!(namespace_id: @group.id) | |
232 | + @project = Project.create_by_user(@opts, @user) | |
233 | + end | |
234 | + | |
235 | + it { @project.should be_valid } | |
236 | + it { @project.owner.should == @user } | |
237 | + it { @project.namespace.should == @group } | |
238 | + end | |
239 | + end | |
240 | + | |
241 | + describe :find_with_namespace do | |
242 | + context 'with namespace' do | |
243 | + before do | |
244 | + @group = create :group, name: 'gitlab' | |
245 | + @project = create(:project, name: 'gitlab-ci', namespace: @group) | |
246 | + end | |
247 | + | |
248 | + it { Project.find_with_namespace('gitlab/gitlab-ci').should == @project } | |
249 | + it { Project.find_with_namespace('gitlab-ci').should be_nil } | |
250 | + end | |
251 | + | |
252 | + context 'w/o namespace' do | |
253 | + before do | |
254 | + @project = create(:project, name: 'gitlab-ci') | |
255 | + end | |
256 | + | |
257 | + it { Project.find_with_namespace('gitlab-ci').should == @project } | |
258 | + it { Project.find_with_namespace('gitlab/gitlab-ci').should be_nil } | |
259 | + end | |
260 | + end | |
261 | + | |
262 | + describe :to_param do | |
263 | + context 'with namespace' do | |
264 | + before do | |
265 | + @group = create :group, name: 'gitlab' | |
266 | + @project = create(:project, name: 'gitlab-ci', namespace: @group) | |
267 | + end | |
268 | + | |
269 | + it { @project.to_param.should == "gitlab/gitlab-ci" } | |
270 | + end | |
271 | + | |
272 | + context 'w/o namespace' do | |
273 | + before do | |
274 | + @project = create(:project, name: 'gitlab-ci') | |
275 | + end | |
276 | + | |
277 | + it { @project.to_param.should == "gitlab-ci" } | |
278 | + end | |
279 | + end | |
214 | 280 | end | ... | ... |
spec/models/user_spec.rb
... | ... | @@ -39,7 +39,6 @@ describe User do |
39 | 39 | describe "Associations" do |
40 | 40 | it { should have_one(:namespace) } |
41 | 41 | it { should have_many(:users_projects).dependent(:destroy) } |
42 | - it { should have_many(:projects) } | |
43 | 42 | it { should have_many(:groups) } |
44 | 43 | it { should have_many(:keys).dependent(:destroy) } |
45 | 44 | it { should have_many(:events).class_name('Event').dependent(:destroy) } |
... | ... | @@ -119,4 +118,71 @@ describe User do |
119 | 118 | user.authentication_token.should_not be_blank |
120 | 119 | end |
121 | 120 | end |
121 | + | |
122 | + describe 'projects' do | |
123 | + before do | |
124 | + ActiveRecord::Base.observers.enable(:user_observer) | |
125 | + @user = create :user | |
126 | + @project = create :project, namespace: @user.namespace | |
127 | + end | |
128 | + | |
129 | + it { @user.authorized_projects.should include(@project) } | |
130 | + it { @user.owned_projects.should include(@project) } | |
131 | + it { @user.personal_projects.should include(@project) } | |
132 | + end | |
133 | + | |
134 | + describe 'groups' do | |
135 | + before do | |
136 | + ActiveRecord::Base.observers.enable(:user_observer) | |
137 | + @user = create :user | |
138 | + @group = create :group, owner: @user | |
139 | + end | |
140 | + | |
141 | + it { @user.several_namespaces?.should be_true } | |
142 | + it { @user.namespaces.should == [@user.namespace, @group] } | |
143 | + it { @user.authorized_groups.should == [@group] } | |
144 | + it { @user.owned_groups.should == [@group] } | |
145 | + end | |
146 | + | |
147 | + describe 'namespaced' do | |
148 | + before do | |
149 | + ActiveRecord::Base.observers.enable(:user_observer) | |
150 | + @user = create :user | |
151 | + @project = create :project, namespace: @user.namespace | |
152 | + end | |
153 | + | |
154 | + it { @user.several_namespaces?.should be_false } | |
155 | + it { @user.namespaces.should == [@user.namespace] } | |
156 | + end | |
157 | + | |
158 | + describe 'blocking user' do | |
159 | + let(:user) { create(:user, name: 'John Smith') } | |
160 | + | |
161 | + it "should block user" do | |
162 | + user.block | |
163 | + user.blocked.should be_true | |
164 | + end | |
165 | + end | |
166 | + | |
167 | + describe 'filter' do | |
168 | + before do | |
169 | + @user = create :user | |
170 | + @admin = create :user, admin: true | |
171 | + @blocked = create :user, blocked: true | |
172 | + end | |
173 | + | |
174 | + it { User.filter("admins").should == [@admin] } | |
175 | + it { User.filter("blocked").should == [@blocked] } | |
176 | + it { User.filter("wop").should == [@user, @admin, @blocked] } | |
177 | + it { User.filter(nil).should == [@user, @admin] } | |
178 | + end | |
179 | + | |
180 | + describe :not_in_project do | |
181 | + before do | |
182 | + @user = create :user | |
183 | + @project = create :project | |
184 | + end | |
185 | + | |
186 | + it { User.not_in_project(@project).should == [@user, @project.owner] } | |
187 | + end | |
122 | 188 | end | ... | ... |
spec/roles/account_role_spec.rb
... | ... | @@ -10,35 +10,4 @@ describe User, "Account" do |
10 | 10 | it { user.can_create_project?.should be_true } |
11 | 11 | it { user.first_name.should == 'John' } |
12 | 12 | end |
13 | - | |
14 | - describe 'blocking user' do | |
15 | - let(:user) { create(:user, name: 'John Smith') } | |
16 | - | |
17 | - it "should block user" do | |
18 | - user.block | |
19 | - user.blocked.should be_true | |
20 | - end | |
21 | - end | |
22 | - | |
23 | - describe 'projects' do | |
24 | - before do | |
25 | - ActiveRecord::Base.observers.enable(:user_observer) | |
26 | - @user = create :user | |
27 | - @project = create :project, namespace: @user.namespace | |
28 | - end | |
29 | - | |
30 | - it { @user.authorized_projects.should include(@project) } | |
31 | - it { @user.my_own_projects.should include(@project) } | |
32 | - end | |
33 | - | |
34 | - describe 'namespaced' do | |
35 | - before do | |
36 | - ActiveRecord::Base.observers.enable(:user_observer) | |
37 | - @user = create :user | |
38 | - @project = create :project, namespace: @user.namespace | |
39 | - end | |
40 | - | |
41 | - it { @user.several_namespaces?.should be_false } | |
42 | - it { @user.namespaces.should == [@user.namespace] } | |
43 | - end | |
44 | 13 | end | ... | ... |