Commit 1c7aecc8f5be4eee30b44a188cbae8341a67f740
Exists in
spb-stable
and in
3 other branches
Merge branch 'refacoring/selectors' into 'master'
Refacoring: Finders Services -> change data Finders -> select data
Showing
21 changed files
with
440 additions
and
370 deletions
Show diff stats
app/controllers/dashboard_controller.rb
... | ... | @@ -53,13 +53,13 @@ class DashboardController < ApplicationController |
53 | 53 | end |
54 | 54 | |
55 | 55 | def merge_requests |
56 | - @merge_requests = FilteringService.new.execute(MergeRequest, current_user, params) | |
56 | + @merge_requests = MergeRequestsFinder.new.execute(current_user, params) | |
57 | 57 | @merge_requests = @merge_requests.page(params[:page]).per(20) |
58 | 58 | @merge_requests = @merge_requests.preload(:author, :target_project) |
59 | 59 | end |
60 | 60 | |
61 | 61 | def issues |
62 | - @issues = FilteringService.new.execute(Issue, current_user, params) | |
62 | + @issues = IssuesFinder.new.execute(current_user, params) | |
63 | 63 | @issues = @issues.page(params[:page]).per(20) |
64 | 64 | @issues = @issues.preload(:author, :project) |
65 | 65 | ... | ... |
app/controllers/groups_controller.rb
... | ... | @@ -47,13 +47,13 @@ class GroupsController < ApplicationController |
47 | 47 | end |
48 | 48 | |
49 | 49 | def merge_requests |
50 | - @merge_requests = FilteringService.new.execute(MergeRequest, current_user, params) | |
50 | + @merge_requests = MergeRequestsFinder.new.execute(current_user, params) | |
51 | 51 | @merge_requests = @merge_requests.page(params[:page]).per(20) |
52 | 52 | @merge_requests = @merge_requests.preload(:author, :target_project) |
53 | 53 | end |
54 | 54 | |
55 | 55 | def issues |
56 | - @issues = FilteringService.new.execute(Issue, current_user, params) | |
56 | + @issues = IssuesFinder.new.execute(current_user, params) | |
57 | 57 | @issues = @issues.page(params[:page]).per(20) |
58 | 58 | @issues = @issues.preload(:author, :project) |
59 | 59 | |
... | ... | @@ -100,7 +100,7 @@ class GroupsController < ApplicationController |
100 | 100 | end |
101 | 101 | |
102 | 102 | def projects |
103 | - @projects ||= Projects::CollectService.new.execute(current_user, group: group) | |
103 | + @projects ||= ProjectsFinder.new.execute(current_user, group: group) | |
104 | 104 | end |
105 | 105 | |
106 | 106 | def project_ids | ... | ... |
app/controllers/projects/issues_controller.rb
... | ... | @@ -121,7 +121,7 @@ class Projects::IssuesController < Projects::ApplicationController |
121 | 121 | def issues_filtered |
122 | 122 | params[:scope] = 'all' if params[:scope].blank? |
123 | 123 | params[:state] = 'opened' if params[:state].blank? |
124 | - @issues = FilteringService.new.execute(Issue, current_user, params.merge(project_id: @project.id)) | |
124 | + @issues = IssuesFinder.new.execute(current_user, params.merge(project_id: @project.id)) | |
125 | 125 | end |
126 | 126 | |
127 | 127 | # Since iids are implemented only in 6.1 | ... | ... |
app/controllers/projects/merge_requests_controller.rb
... | ... | @@ -21,7 +21,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController |
21 | 21 | params[:scope] = 'all' if params[:scope].blank? |
22 | 22 | params[:state] = 'opened' if params[:state].blank? |
23 | 23 | |
24 | - @merge_requests = FilteringService.new.execute(MergeRequest, current_user, params.merge(project_id: @project.id)) | |
24 | + @merge_requests = MergeRequestsFinder.new.execute(current_user, params.merge(project_id: @project.id)) | |
25 | 25 | @merge_requests = @merge_requests.page(params[:page]).per(20) |
26 | 26 | |
27 | 27 | @sort = params[:sort].humanize | ... | ... |
app/controllers/projects/notes_controller.rb
... | ... | @@ -5,7 +5,7 @@ class Projects::NotesController < Projects::ApplicationController |
5 | 5 | before_filter :authorize_admin_note!, only: [:update, :destroy] |
6 | 6 | |
7 | 7 | def index |
8 | - @notes = Notes::LoadService.new(project, current_user, params).execute | |
8 | + @notes = NotesFinder.new.execute(project, current_user, params) | |
9 | 9 | |
10 | 10 | notes_json = { notes: [] } |
11 | 11 | ... | ... |
... | ... | @@ -0,0 +1,22 @@ |
1 | +# Finders | |
2 | + | |
3 | +This type of classes responsible for collectiong items based on different conditions. | |
4 | +To prevent lookup methods in models like this: | |
5 | + | |
6 | +```ruby | |
7 | +class Project | |
8 | + def issues_for_user_filtered_by(user, filter) | |
9 | + # A lot of logic not related to project model itself | |
10 | + end | |
11 | +end | |
12 | + | |
13 | +issues = project.issues_for_user_filtered_by(user, params) | |
14 | +``` | |
15 | + | |
16 | +Better use this: | |
17 | + | |
18 | +```ruby | |
19 | +issues = IssuesFinder.new.execute(project, user, filter) | |
20 | +``` | |
21 | + | |
22 | +It will help keep models thiner | ... | ... |
... | ... | @@ -0,0 +1,137 @@ |
1 | +# BaseFinder | |
2 | +# | |
3 | +# Used to filter Issues and MergeRequests collections by set of params | |
4 | +# | |
5 | +# Arguments: | |
6 | +# klass - actual class like Issue or MergeRequest | |
7 | +# current_user - which user use | |
8 | +# params: | |
9 | +# scope: 'created-by-me' or 'assigned-to-me' or 'all' | |
10 | +# state: 'open' or 'closed' or 'all' | |
11 | +# group_id: integer | |
12 | +# project_id: integer | |
13 | +# milestone_id: integer | |
14 | +# assignee_id: integer | |
15 | +# search: string | |
16 | +# label_name: string | |
17 | +# sort: string | |
18 | +# | |
19 | +class BaseFinder | |
20 | + attr_accessor :current_user, :params | |
21 | + | |
22 | + def execute(current_user, params) | |
23 | + @current_user = current_user | |
24 | + @params = params | |
25 | + | |
26 | + items = init_collection | |
27 | + items = by_scope(items) | |
28 | + items = by_state(items) | |
29 | + items = by_group(items) | |
30 | + items = by_project(items) | |
31 | + items = by_search(items) | |
32 | + items = by_milestone(items) | |
33 | + items = by_assignee(items) | |
34 | + items = by_label(items) | |
35 | + items = sort(items) | |
36 | + end | |
37 | + | |
38 | + private | |
39 | + | |
40 | + def init_collection | |
41 | + table_name = klass.table_name | |
42 | + | |
43 | + if project | |
44 | + if project.public? || (current_user && current_user.can?(:read_project, project)) | |
45 | + project.send(table_name) | |
46 | + else | |
47 | + [] | |
48 | + end | |
49 | + elsif current_user && params[:authorized_only].presence | |
50 | + klass.of_projects(current_user.authorized_projects) | |
51 | + else | |
52 | + klass.of_projects(Project.accessible_to(current_user)) | |
53 | + end | |
54 | + end | |
55 | + | |
56 | + def by_scope(items) | |
57 | + case params[:scope] | |
58 | + when 'created-by-me', 'authored' then | |
59 | + items.where(author_id: current_user.id) | |
60 | + when 'all' then | |
61 | + items | |
62 | + when 'assigned-to-me' then | |
63 | + items.where(assignee_id: current_user.id) | |
64 | + else | |
65 | + raise 'You must specify default scope' | |
66 | + end | |
67 | + end | |
68 | + | |
69 | + def by_state(items) | |
70 | + case params[:state] | |
71 | + when 'closed' | |
72 | + items.closed | |
73 | + when 'all' | |
74 | + items | |
75 | + when 'opened' | |
76 | + items.opened | |
77 | + else | |
78 | + raise 'You must specify default state' | |
79 | + end | |
80 | + end | |
81 | + | |
82 | + def by_group(items) | |
83 | + if params[:group_id].present? | |
84 | + items = items.of_group(Group.find(params[:group_id])) | |
85 | + end | |
86 | + | |
87 | + items | |
88 | + end | |
89 | + | |
90 | + def by_project(items) | |
91 | + if params[:project_id].present? | |
92 | + items = items.of_projects(params[:project_id]) | |
93 | + end | |
94 | + | |
95 | + items | |
96 | + end | |
97 | + | |
98 | + def by_search(items) | |
99 | + if params[:search].present? | |
100 | + items = items.search(params[:search]) | |
101 | + end | |
102 | + | |
103 | + items | |
104 | + end | |
105 | + | |
106 | + def sort(items) | |
107 | + items.sort(params[:sort]) | |
108 | + end | |
109 | + | |
110 | + def by_milestone(items) | |
111 | + if params[:milestone_id].present? | |
112 | + items = items.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) | |
113 | + end | |
114 | + | |
115 | + items | |
116 | + end | |
117 | + | |
118 | + def by_assignee(items) | |
119 | + if params[:assignee_id].present? | |
120 | + items = items.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id])) | |
121 | + end | |
122 | + | |
123 | + items | |
124 | + end | |
125 | + | |
126 | + def by_label(items) | |
127 | + if params[:label_name].present? | |
128 | + items = items.tagged_with(params[:label_name]) | |
129 | + end | |
130 | + | |
131 | + items | |
132 | + end | |
133 | + | |
134 | + def project | |
135 | + Project.where(id: params[:project_id]).first if params[:project_id].present? | |
136 | + end | |
137 | +end | ... | ... |
... | ... | @@ -0,0 +1,22 @@ |
1 | +# Finders::Issues class | |
2 | +# | |
3 | +# Used to filter Issues collections by set of params | |
4 | +# | |
5 | +# Arguments: | |
6 | +# current_user - which user use | |
7 | +# params: | |
8 | +# scope: 'created-by-me' or 'assigned-to-me' or 'all' | |
9 | +# state: 'open' or 'closed' or 'all' | |
10 | +# group_id: integer | |
11 | +# project_id: integer | |
12 | +# milestone_id: integer | |
13 | +# assignee_id: integer | |
14 | +# search: string | |
15 | +# label_name: string | |
16 | +# sort: string | |
17 | +# | |
18 | +class IssuesFinder < BaseFinder | |
19 | + def klass | |
20 | + Issue | |
21 | + end | |
22 | +end | ... | ... |
... | ... | @@ -0,0 +1,22 @@ |
1 | +# Finders::MergeRequest class | |
2 | +# | |
3 | +# Used to filter MergeRequests collections by set of params | |
4 | +# | |
5 | +# Arguments: | |
6 | +# current_user - which user use | |
7 | +# params: | |
8 | +# scope: 'created-by-me' or 'assigned-to-me' or 'all' | |
9 | +# state: 'open' or 'closed' or 'all' | |
10 | +# group_id: integer | |
11 | +# project_id: integer | |
12 | +# milestone_id: integer | |
13 | +# assignee_id: integer | |
14 | +# search: string | |
15 | +# label_name: string | |
16 | +# sort: string | |
17 | +# | |
18 | +class MergeRequestsFinder < BaseFinder | |
19 | + def klass | |
20 | + MergeRequest | |
21 | + end | |
22 | +end | ... | ... |
... | ... | @@ -0,0 +1,17 @@ |
1 | +class NotesFinder | |
2 | + def execute(project, current_user, params) | |
3 | + target_type = params[:target_type] | |
4 | + target_id = params[:target_id] | |
5 | + | |
6 | + case target_type | |
7 | + when "commit" | |
8 | + project.notes.for_commit_id(target_id).not_inline.fresh | |
9 | + when "issue" | |
10 | + project.issues.find(target_id).notes.inc_author.fresh | |
11 | + when "merge_request" | |
12 | + project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh | |
13 | + when "snippet" | |
14 | + project.snippets.find(target_id).notes.fresh | |
15 | + end | |
16 | + end | |
17 | +end | ... | ... |
... | ... | @@ -0,0 +1,63 @@ |
1 | +class ProjectsFinder | |
2 | + def execute(current_user, options) | |
3 | + group = options[:group] | |
4 | + | |
5 | + if group | |
6 | + group_projects(current_user, group) | |
7 | + else | |
8 | + all_projects(current_user) | |
9 | + end | |
10 | + end | |
11 | + | |
12 | + private | |
13 | + | |
14 | + def group_projects(current_user, group) | |
15 | + if current_user | |
16 | + if group.users.include?(current_user) | |
17 | + # User is group member | |
18 | + # | |
19 | + # Return ALL group projects | |
20 | + group.projects | |
21 | + else | |
22 | + projects_members = UsersProject.where( | |
23 | + project_id: group.projects, | |
24 | + user_id: current_user | |
25 | + ) | |
26 | + | |
27 | + if projects_members.any? | |
28 | + # User is a project member | |
29 | + # | |
30 | + # Return only: | |
31 | + # public projects | |
32 | + # internal projects | |
33 | + # joined projects | |
34 | + # | |
35 | + group.projects.where( | |
36 | + "projects.id IN (?) OR projects.visibility_level IN (?)", | |
37 | + projects_members.pluck(:project_id), | |
38 | + Project.public_and_internal_levels | |
39 | + ) | |
40 | + else | |
41 | + # User has no access to group or group projects | |
42 | + # | |
43 | + # Return only: | |
44 | + # public projects | |
45 | + # internal projects | |
46 | + # | |
47 | + group.projects.public_and_internal_only | |
48 | + end | |
49 | + end | |
50 | + else | |
51 | + # Not authenticated | |
52 | + # | |
53 | + # Return only: | |
54 | + # public projects | |
55 | + group.projects.public_only | |
56 | + end | |
57 | + end | |
58 | + | |
59 | + def all_projects | |
60 | + # TODO: implement | |
61 | + raise 'Not implemented yet' | |
62 | + end | |
63 | +end | ... | ... |
app/models/ability.rb
... | ... | @@ -184,7 +184,7 @@ class Ability |
184 | 184 | def group_abilities user, group |
185 | 185 | rules = [] |
186 | 186 | |
187 | - if user.admin? || group.users.include?(user) || Projects::CollectService.new.execute(user, group: group).any? | |
187 | + if user.admin? || group.users.include?(user) || ProjectsFinder.new.execute(user, group: group).any? | |
188 | 188 | rules << :read_group |
189 | 189 | end |
190 | 190 | ... | ... |
app/services/filtering_service.rb
... | ... | @@ -1,138 +0,0 @@ |
1 | -# FilteringService class | |
2 | -# | |
3 | -# Used to filter Issues and MergeRequests collections by set of params | |
4 | -# | |
5 | -# Arguments: | |
6 | -# klass - actual class like Issue or MergeRequest | |
7 | -# current_user - which user use | |
8 | -# params: | |
9 | -# scope: 'created-by-me' or 'assigned-to-me' or 'all' | |
10 | -# state: 'open' or 'closed' or 'all' | |
11 | -# group_id: integer | |
12 | -# project_id: integer | |
13 | -# milestone_id: integer | |
14 | -# assignee_id: integer | |
15 | -# search: string | |
16 | -# label_name: string | |
17 | -# sort: string | |
18 | -# | |
19 | -class FilteringService | |
20 | - attr_accessor :klass, :current_user, :params | |
21 | - | |
22 | - def execute(klass, current_user, params) | |
23 | - @klass = klass | |
24 | - @current_user = current_user | |
25 | - @params = params | |
26 | - | |
27 | - items = init_collection | |
28 | - items = by_scope(items) | |
29 | - items = by_state(items) | |
30 | - items = by_group(items) | |
31 | - items = by_project(items) | |
32 | - items = by_search(items) | |
33 | - items = by_milestone(items) | |
34 | - items = by_assignee(items) | |
35 | - items = by_label(items) | |
36 | - items = sort(items) | |
37 | - end | |
38 | - | |
39 | - private | |
40 | - | |
41 | - def init_collection | |
42 | - table_name = klass.table_name | |
43 | - | |
44 | - if project | |
45 | - if project.public? || (current_user && current_user.can?(:read_project, project)) | |
46 | - project.send(table_name) | |
47 | - else | |
48 | - [] | |
49 | - end | |
50 | - elsif current_user && params[:authorized_only].presence | |
51 | - klass.of_projects(current_user.authorized_projects) | |
52 | - else | |
53 | - klass.of_projects(Project.accessible_to(current_user)) | |
54 | - end | |
55 | - end | |
56 | - | |
57 | - def by_scope(items) | |
58 | - case params[:scope] | |
59 | - when 'created-by-me', 'authored' then | |
60 | - items.where(author_id: current_user.id) | |
61 | - when 'all' then | |
62 | - items | |
63 | - when 'assigned-to-me' then | |
64 | - items.where(assignee_id: current_user.id) | |
65 | - else | |
66 | - raise 'You must specify default scope' | |
67 | - end | |
68 | - end | |
69 | - | |
70 | - def by_state(items) | |
71 | - case params[:state] | |
72 | - when 'closed' | |
73 | - items.closed | |
74 | - when 'all' | |
75 | - items | |
76 | - when 'opened' | |
77 | - items.opened | |
78 | - else | |
79 | - raise 'You must specify default state' | |
80 | - end | |
81 | - end | |
82 | - | |
83 | - def by_group(items) | |
84 | - if params[:group_id].present? | |
85 | - items = items.of_group(Group.find(params[:group_id])) | |
86 | - end | |
87 | - | |
88 | - items | |
89 | - end | |
90 | - | |
91 | - def by_project(items) | |
92 | - if params[:project_id].present? | |
93 | - items = items.of_projects(params[:project_id]) | |
94 | - end | |
95 | - | |
96 | - items | |
97 | - end | |
98 | - | |
99 | - def by_search(items) | |
100 | - if params[:search].present? | |
101 | - items = items.search(params[:search]) | |
102 | - end | |
103 | - | |
104 | - items | |
105 | - end | |
106 | - | |
107 | - def sort(items) | |
108 | - items.sort(params[:sort]) | |
109 | - end | |
110 | - | |
111 | - def by_milestone(items) | |
112 | - if params[:milestone_id].present? | |
113 | - items = items.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) | |
114 | - end | |
115 | - | |
116 | - items | |
117 | - end | |
118 | - | |
119 | - def by_assignee(items) | |
120 | - if params[:assignee_id].present? | |
121 | - items = items.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id])) | |
122 | - end | |
123 | - | |
124 | - items | |
125 | - end | |
126 | - | |
127 | - def by_label(items) | |
128 | - if params[:label_name].present? | |
129 | - items = items.tagged_with(params[:label_name]) | |
130 | - end | |
131 | - | |
132 | - items | |
133 | - end | |
134 | - | |
135 | - def project | |
136 | - Project.where(id: params[:project_id]).first if params[:project_id].present? | |
137 | - end | |
138 | -end |
app/services/notes/load_service.rb
... | ... | @@ -1,20 +0,0 @@ |
1 | -module Notes | |
2 | - class LoadService < BaseService | |
3 | - def execute | |
4 | - target_type = params[:target_type] | |
5 | - target_id = params[:target_id] | |
6 | - | |
7 | - | |
8 | - @notes = case target_type | |
9 | - when "commit" | |
10 | - project.notes.for_commit_id(target_id).not_inline.fresh | |
11 | - when "issue" | |
12 | - project.issues.find(target_id).notes.inc_author.fresh | |
13 | - when "merge_request" | |
14 | - project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh | |
15 | - when "snippet" | |
16 | - project.snippets.find(target_id).notes.fresh | |
17 | - end | |
18 | - end | |
19 | - end | |
20 | -end |
app/services/projects/collect_service.rb
... | ... | @@ -1,69 +0,0 @@ |
1 | -# Projects::CollectService class | |
2 | -# | |
3 | -# Used to collect projects user has access to | |
4 | -# | |
5 | -module Projects | |
6 | - class CollectService | |
7 | - def execute(current_user, options) | |
8 | - group = options[:group] | |
9 | - | |
10 | - if group | |
11 | - group_projects(current_user, group) | |
12 | - else | |
13 | - all_projects(current_user) | |
14 | - end | |
15 | - end | |
16 | - | |
17 | - private | |
18 | - | |
19 | - def group_projects(current_user, group) | |
20 | - if current_user | |
21 | - if group.users.include?(current_user) | |
22 | - # User is group member | |
23 | - # | |
24 | - # Return ALL group projects | |
25 | - group.projects | |
26 | - else | |
27 | - projects_members = UsersProject.where( | |
28 | - project_id: group.projects, | |
29 | - user_id: current_user | |
30 | - ) | |
31 | - | |
32 | - if projects_members.any? | |
33 | - # User is a project member | |
34 | - # | |
35 | - # Return only: | |
36 | - # public projects | |
37 | - # internal projects | |
38 | - # joined projects | |
39 | - # | |
40 | - group.projects.where( | |
41 | - "projects.id IN (?) OR projects.visibility_level IN (?)", | |
42 | - projects_members.pluck(:project_id), | |
43 | - Project.public_and_internal_levels | |
44 | - ) | |
45 | - else | |
46 | - # User has no access to group or group projects | |
47 | - # | |
48 | - # Return only: | |
49 | - # public projects | |
50 | - # internal projects | |
51 | - # | |
52 | - group.projects.public_and_internal_only | |
53 | - end | |
54 | - end | |
55 | - else | |
56 | - # Not authenticated | |
57 | - # | |
58 | - # Return only: | |
59 | - # public projects | |
60 | - group.projects.public_only | |
61 | - end | |
62 | - end | |
63 | - end | |
64 | - | |
65 | - def all_projects | |
66 | - # TODO: implement | |
67 | - raise 'Not implemented yet' | |
68 | - end | |
69 | -end |
config/application.rb
... | ... | @@ -12,7 +12,7 @@ module Gitlab |
12 | 12 | # -- all .rb files in that directory are automatically loaded. |
13 | 13 | |
14 | 14 | # Custom directories with classes and modules you want to be autoloadable. |
15 | - config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/models/concerns #{config.root}/app/models/project_services) | |
15 | + config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/finders #{config.root}/app/models/concerns #{config.root}/app/models/project_services) | |
16 | 16 | |
17 | 17 | # Only load the plugins named here, in the order given (default is alphabetical). |
18 | 18 | # :all can be used as a placeholder for all plugins not explicitly named. |
... | ... | @@ -64,7 +64,7 @@ module Gitlab |
64 | 64 | config.assets.enabled = true |
65 | 65 | config.assets.paths << Emoji.images_path |
66 | 66 | config.assets.precompile << "emoji/*.png" |
67 | - | |
67 | + | |
68 | 68 | # Version of your assets, change this if you want to expire all your assets |
69 | 69 | config.assets.version = '1.0' |
70 | 70 | ... | ... |
... | ... | @@ -0,0 +1,58 @@ |
1 | +require 'spec_helper' | |
2 | + | |
3 | +describe IssuesFinder do | |
4 | + let(:user) { create :user } | |
5 | + let(:user2) { create :user } | |
6 | + let(:project1) { create(:project) } | |
7 | + let(:project2) { create(:project) } | |
8 | + let(:issue1) { create(:issue, assignee: user, project: project1) } | |
9 | + let(:issue2) { create(:issue, assignee: user, project: project2) } | |
10 | + let(:issue3) { create(:issue, assignee: user2, project: project2) } | |
11 | + | |
12 | + before do | |
13 | + project1.team << [user, :master] | |
14 | + project2.team << [user, :developer] | |
15 | + project2.team << [user2, :developer] | |
16 | + end | |
17 | + | |
18 | + describe :execute do | |
19 | + before :each do | |
20 | + issue1 | |
21 | + issue2 | |
22 | + issue3 | |
23 | + end | |
24 | + | |
25 | + it 'should filter by all' do | |
26 | + params = { scope: "all", state: 'opened' } | |
27 | + issues = IssuesFinder.new.execute(user, params) | |
28 | + issues.size.should == 3 | |
29 | + end | |
30 | + | |
31 | + it 'should filter by assignee' do | |
32 | + params = { scope: "assigned-to-me", state: 'opened' } | |
33 | + issues = IssuesFinder.new.execute(user, params) | |
34 | + issues.size.should == 2 | |
35 | + end | |
36 | + | |
37 | + it 'should filter by project' do | |
38 | + params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id } | |
39 | + issues = IssuesFinder.new.execute(user, params) | |
40 | + issues.size.should == 1 | |
41 | + end | |
42 | + | |
43 | + it 'should be empty for unauthorized user' do | |
44 | + params = { scope: "all", state: 'opened' } | |
45 | + issues = IssuesFinder.new.execute(nil, params) | |
46 | + issues.size.should be_zero | |
47 | + end | |
48 | + | |
49 | + it 'should not include unauthorized issues' do | |
50 | + params = { scope: "all", state: 'opened' } | |
51 | + issues = IssuesFinder.new.execute(user2, params) | |
52 | + issues.size.should == 2 | |
53 | + issues.should_not include(issue1) | |
54 | + issues.should include(issue2) | |
55 | + issues.should include(issue3) | |
56 | + end | |
57 | + end | |
58 | +end | ... | ... |
... | ... | @@ -0,0 +1,37 @@ |
1 | +require 'spec_helper' | |
2 | + | |
3 | +describe MergeRequestsFinder do | |
4 | + let(:user) { create :user } | |
5 | + let(:user2) { create :user } | |
6 | + let(:project1) { create(:project) } | |
7 | + let(:project2) { create(:project) } | |
8 | + let(:merge_request1) { create(:merge_request, author: user, source_project: project1, target_project: project2) } | |
9 | + let(:merge_request2) { create(:merge_request, author: user, source_project: project2, target_project: project1) } | |
10 | + let(:merge_request3) { create(:merge_request, author: user, source_project: project2, target_project: project2) } | |
11 | + | |
12 | + before do | |
13 | + project1.team << [user, :master] | |
14 | + project2.team << [user, :developer] | |
15 | + project2.team << [user2, :developer] | |
16 | + end | |
17 | + | |
18 | + describe :execute do | |
19 | + before :each do | |
20 | + merge_request1 | |
21 | + merge_request2 | |
22 | + merge_request3 | |
23 | + end | |
24 | + | |
25 | + it 'should filter by scope' do | |
26 | + params = { scope: 'authored', state: 'opened' } | |
27 | + merge_requests = MergeRequestsFinder.new.execute(user, params) | |
28 | + merge_requests.size.should == 3 | |
29 | + end | |
30 | + | |
31 | + it 'should filter by project' do | |
32 | + params = { project_id: project1.id, scope: 'authored', state: 'opened' } | |
33 | + merge_requests = MergeRequestsFinder.new.execute(user, params) | |
34 | + merge_requests.size.should == 1 | |
35 | + end | |
36 | + end | |
37 | +end | ... | ... |
... | ... | @@ -0,0 +1,51 @@ |
1 | +require 'spec_helper' | |
2 | + | |
3 | +describe ProjectsFinder do | |
4 | + let(:user) { create :user } | |
5 | + let(:group) { create :group } | |
6 | + | |
7 | + let(:project1) { create(:empty_project, group: group, visibility_level: Project::PUBLIC) } | |
8 | + let(:project2) { create(:empty_project, group: group, visibility_level: Project::INTERNAL) } | |
9 | + let(:project3) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) } | |
10 | + let(:project4) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) } | |
11 | + | |
12 | + context 'non authenticated' do | |
13 | + subject { ProjectsFinder.new.execute(nil, group: group) } | |
14 | + | |
15 | + it { should include(project1) } | |
16 | + it { should_not include(project2) } | |
17 | + it { should_not include(project3) } | |
18 | + it { should_not include(project4) } | |
19 | + end | |
20 | + | |
21 | + context 'authenticated' do | |
22 | + subject { ProjectsFinder.new.execute(user, group: group) } | |
23 | + | |
24 | + it { should include(project1) } | |
25 | + it { should include(project2) } | |
26 | + it { should_not include(project3) } | |
27 | + it { should_not include(project4) } | |
28 | + end | |
29 | + | |
30 | + context 'authenticated, project member' do | |
31 | + before { project3.team << [user, :developer] } | |
32 | + | |
33 | + subject { ProjectsFinder.new.execute(user, group: group) } | |
34 | + | |
35 | + it { should include(project1) } | |
36 | + it { should include(project2) } | |
37 | + it { should include(project3) } | |
38 | + it { should_not include(project4) } | |
39 | + end | |
40 | + | |
41 | + context 'authenticated, group member' do | |
42 | + before { group.add_user(user, Gitlab::Access::DEVELOPER) } | |
43 | + | |
44 | + subject { ProjectsFinder.new.execute(user, group: group) } | |
45 | + | |
46 | + it { should include(project1) } | |
47 | + it { should include(project2) } | |
48 | + it { should include(project3) } | |
49 | + it { should include(project4) } | |
50 | + end | |
51 | +end | ... | ... |
spec/services/filtering_service_spec.rb
... | ... | @@ -1,81 +0,0 @@ |
1 | -require 'spec_helper' | |
2 | - | |
3 | -describe FilteringService do | |
4 | - let(:user) { create :user } | |
5 | - let(:user2) { create :user } | |
6 | - let(:project1) { create(:project) } | |
7 | - let(:project2) { create(:project) } | |
8 | - let(:merge_request1) { create(:merge_request, author: user, source_project: project1, target_project: project2) } | |
9 | - let(:merge_request2) { create(:merge_request, author: user, source_project: project2, target_project: project1) } | |
10 | - let(:merge_request3) { create(:merge_request, author: user, source_project: project2, target_project: project2) } | |
11 | - let(:issue1) { create(:issue, assignee: user, project: project1) } | |
12 | - let(:issue2) { create(:issue, assignee: user, project: project2) } | |
13 | - let(:issue3) { create(:issue, assignee: user2, project: project2) } | |
14 | - | |
15 | - before do | |
16 | - project1.team << [user, :master] | |
17 | - project2.team << [user, :developer] | |
18 | - project2.team << [user2, :developer] | |
19 | - end | |
20 | - | |
21 | - describe 'merge requests' do | |
22 | - before :each do | |
23 | - merge_request1 | |
24 | - merge_request2 | |
25 | - merge_request3 | |
26 | - end | |
27 | - | |
28 | - it 'should filter by scope' do | |
29 | - params = { scope: 'authored', state: 'opened' } | |
30 | - merge_requests = FilteringService.new.execute(MergeRequest, user, params) | |
31 | - merge_requests.size.should == 3 | |
32 | - end | |
33 | - | |
34 | - it 'should filter by project' do | |
35 | - params = { project_id: project1.id, scope: 'authored', state: 'opened' } | |
36 | - merge_requests = FilteringService.new.execute(MergeRequest, user, params) | |
37 | - merge_requests.size.should == 1 | |
38 | - end | |
39 | - end | |
40 | - | |
41 | - describe 'issues' do | |
42 | - before :each do | |
43 | - issue1 | |
44 | - issue2 | |
45 | - issue3 | |
46 | - end | |
47 | - | |
48 | - it 'should filter by all' do | |
49 | - params = { scope: "all", state: 'opened' } | |
50 | - issues = FilteringService.new.execute(Issue, user, params) | |
51 | - issues.size.should == 3 | |
52 | - end | |
53 | - | |
54 | - it 'should filter by assignee' do | |
55 | - params = { scope: "assigned-to-me", state: 'opened' } | |
56 | - issues = FilteringService.new.execute(Issue, user, params) | |
57 | - issues.size.should == 2 | |
58 | - end | |
59 | - | |
60 | - it 'should filter by project' do | |
61 | - params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id } | |
62 | - issues = FilteringService.new.execute(Issue, user, params) | |
63 | - issues.size.should == 1 | |
64 | - end | |
65 | - | |
66 | - it 'should be empty for unauthorized user' do | |
67 | - params = { scope: "all", state: 'opened' } | |
68 | - issues = FilteringService.new.execute(Issue, nil, params) | |
69 | - issues.size.should be_zero | |
70 | - end | |
71 | - | |
72 | - it 'should not include unauthorized issues' do | |
73 | - params = { scope: "all", state: 'opened' } | |
74 | - issues = FilteringService.new.execute(Issue, user2, params) | |
75 | - issues.size.should == 2 | |
76 | - issues.should_not include(issue1) | |
77 | - issues.should include(issue2) | |
78 | - issues.should include(issue3) | |
79 | - end | |
80 | - end | |
81 | -end |
spec/services/projects_collect_service_spec.rb
... | ... | @@ -1,51 +0,0 @@ |
1 | -require 'spec_helper' | |
2 | - | |
3 | -describe Projects::CollectService do | |
4 | - let(:user) { create :user } | |
5 | - let(:group) { create :group } | |
6 | - | |
7 | - let(:project1) { create(:empty_project, group: group, visibility_level: Project::PUBLIC) } | |
8 | - let(:project2) { create(:empty_project, group: group, visibility_level: Project::INTERNAL) } | |
9 | - let(:project3) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) } | |
10 | - let(:project4) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) } | |
11 | - | |
12 | - context 'non authenticated' do | |
13 | - subject { Projects::CollectService.new.execute(nil, group: group) } | |
14 | - | |
15 | - it { should include(project1) } | |
16 | - it { should_not include(project2) } | |
17 | - it { should_not include(project3) } | |
18 | - it { should_not include(project4) } | |
19 | - end | |
20 | - | |
21 | - context 'authenticated' do | |
22 | - subject { Projects::CollectService.new.execute(user, group: group) } | |
23 | - | |
24 | - it { should include(project1) } | |
25 | - it { should include(project2) } | |
26 | - it { should_not include(project3) } | |
27 | - it { should_not include(project4) } | |
28 | - end | |
29 | - | |
30 | - context 'authenticated, project member' do | |
31 | - before { project3.team << [user, :developer] } | |
32 | - | |
33 | - subject { Projects::CollectService.new.execute(user, group: group) } | |
34 | - | |
35 | - it { should include(project1) } | |
36 | - it { should include(project2) } | |
37 | - it { should include(project3) } | |
38 | - it { should_not include(project4) } | |
39 | - end | |
40 | - | |
41 | - context 'authenticated, group member' do | |
42 | - before { group.add_user(user, Gitlab::Access::DEVELOPER) } | |
43 | - | |
44 | - subject { Projects::CollectService.new.execute(user, group: group) } | |
45 | - | |
46 | - it { should include(project1) } | |
47 | - it { should include(project2) } | |
48 | - it { should include(project3) } | |
49 | - it { should include(project4) } | |
50 | - end | |
51 | -end |